26 Commits

Author SHA1 Message Date
ericwyuan
3b5f7db51d fix(fam-edge): SQLite 改每线程一条连接,修好 DiskGuard 等一切并发写
OracleDB 原来在 __init__ 里建一条 check_same_thread=False 的连接给全进程共用,
而 VideoQueue / PersonService / DiskGuard 三个后台线程 + gunicorn 的请求线程都在
并发读写它。sqlite3 的连接对象本来就不是可并发共享的,事务状态互相踩踏,线上
累计刷出三类错误(同一个根因):

  database is locked                            71604 次
  cannot start a transaction within a transaction  378 次
  no more rows available                           92 次(堆栈落在 commit())

最严重的后果是磁盘守护形同虚设:DiskGuard 的清理被打断 2837 次,成功仅 128 次,
剩余空间在 2.7GB 和 16GB 之间来回荡——赶上 rclone 集中下载(实测 5 分钟写入
12.6GB)就掉进危险区。NAS 推来的运动事件被 500 打回也是它(失败批次不推进游标,
下一轮补推,所以没丢事件)。

改法:_conn 改成 @property,从 threading.local() 取当前线程的连接,没有就新建
(WAL + busy_timeout=10000)。做成 property 是因为外部调用方(api_gateway 的
activity 端点)也在直接用 db._conn.execute(...),这样全部现有调用点原样工作。
close() 相应改成收掉所有线程开过的连接。_write_lock 保留,复合写语义不变。

测试:新增 8 线程 × 25 轮并发读写、close 收连接两个用例;在旧代码上稳定复现
同族错误 cannot commit transaction - SQL statements in progress。

线上验证:重启后 DiskGuard 立刻跑通一轮(清 40 个文件,剩余回到 15.3GB),
三类 SQLite 错误在重启后的日志里均为 0。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 09:34:24 +08:00
ericwyuan
1964e976f4 refactor: 全量迁云——fam-core 直读甲骨文 SQLite,NAS 只剩推送进程
前一天刚把登录迁到甲骨文,隔天 NAS 上的 fam-core 又挂了导致数据接口 502。
盘点后确认:甲骨文的 SQLite 才是权威数据源(videos 3113 / events 16159 /
people 60 / model_calls 9876),NAS 的 MariaDB 全是它的镜像——前端读的数据
本来就产自甲骨文,绕了一圈回家又绕回来。

改动:
- db_layer.py 从 725 行重写成 377 行:MySQL 镜像查询改为直读 fam-edge 的
  SQLite。5 个 upsert_sync_*(约 300 行去重逻辑,8/29 和 9/3 两次 1062 事故的
  发源地)连同 oracle_sync.py 整个删除。SQL 方言:JSON_CONTAINS -> json_each
  (前置 json_valid,历史脏数据不会把查询搞崩)、LEFT() -> substr()、%s -> ?。
  函数名 get_sync_* 一并改掉——已经没有 sync 这回事了
- 新增 edge_client.py:写操作(改名/删除)、帧图头像、服务状态都打给同机
  fam-edge,全走 127.0.0.1
- 新增 fam-notifier/:motion_notifier 从 fam-core 拆出独立成服务,游标从
  MariaDB 换成本地 JSON 文件。NAS 上从此没有 Flask、没有数据库、没有监听端口
- fam-core 移到甲骨文 /opt/fam-core(systemd,gunicorn -w 2,只绑
  127.0.0.1:5401——5400 被 chat-relay 占了)。Caddy 的 /api/* 从"frp 隧道
  回源 NAS"改成同机反代,forward_auth 闸门不变
- 前端删掉侧边栏同步面板、统计页同步状态、服务状态页的"NAS 同步"卡片与
  "立即同步"按钮(背后的镜像层已不存在);换成"NAS 运动推送"卡片,读
  fam-edge activity 新增的 motion 段(心跳年龄 + 最近事件)
- 顺带修掉一个隐蔽 bug:镜像表为保外键稳定用的是 NAS 本地自增 id,而帧图接口
  要的是甲骨文的 id,两边在 9/3 那次 id 重排后就对不上了。现在只有一套 id

测试:fam-core 21(新增 12 个 db_layer 用例:脏 JSON 不崩、人物精确匹配不误伤
"人物B"、日期过滤、统计口径、chat_history 懒建表)、fam-notifier 6、
fam-edge 157,全绿。

生产验证:甲骨文 /api/ui/stats 返回 videos 2965 / events 16159 / people 59;
NAS 侧 fam-notifier 已推送成功(事件 33070-33072 落库,心跳新鲜);
chat_history 19 条经 scripts/import_chat_history.py 迁移完成。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 08:03:32 +08:00
ericwyuan
feb096ff3d docs: 订正 FAM-UI 部署位置描述(NAS -> 云服务器 Caddy)
多处历史遗留描述仍写 FAM-UI 部署在 NAS(含不存在的 static_app.py),
实际已迁至甲骨文云服务器由 Caddy 静态托管,逐处订正。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 21:50:42 +08:00
ericwyuan
8120d2ae6a feat(fam-core): 登录改接 auth-hub 统一登录(OAuth2 Authorization Code + PKCE / OIDC)
移除本地 FAM_AUTH_USER/PASS 账号密码校验和内置登录表单,/login 改为 302
跳转 auth-hub /authorize,新增 /api/auth/callback 完成 code 换 token +
id_token 签名验证(PyJWT + JWKS),验证通过后种回原有 fam_session cookie,
is_authed()/全局登录拦截逻辑不变。接入参数走环境变量,未配置齐全 fail
closed。本地起 auth-hub 开发实例 + 真实浏览器验证过完整登录/登出闭环。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 21:32:26 +08:00
ericwyuan
c9354ed1a1 docs: 同步 8/28 迁移故障排查记录(FFmpeg 缺失 + 磁盘写满死循环 + DiskGuard)
README.md 新增 Disk-Guard 模块表条目、修正一处遗漏的机器规格描述
(2C12G -> 4C23G)、当前进度补充这次完整排查记录;PROGRESS.md 服务运行
状态表更新 + 新增详细的故障排查时间线记录。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-28 12:10:14 +08:00
ericwyuan
3ec79de911 docs: 清理已删除的 /api/ss/webhook 端点在文档中的残留描述
上次 SS Webhook 重构(cf3d145)已经彻底移除了 /api/ss/webhook 接收端点
(motion_bp.py 不再注册该路由),但 README.md 里 5 处描述、鉴权白名单
说明都还停留在"保留为可选低延迟补充",跟实际代码不符,逐处订正。

顺带更新 vite.config.js 里一句过时注释(还写"生产环境由 fam-core 的
Flask 同源提供",实际前端已经迁到云服务器 Caddy 托管)。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-28 09:31:41 +08:00
ericwyuan
7948f55b02 docs: 同步 8/25 迁移(前端迁云 Caddy:80、Oracle 换新机 129.146.26.249、旧 IP 清理、Drive 中转设计说明) 2026-08-25 23:55:57 +08:00
ericwyuan
3cb08c9749 docs: 同步事件时间轴删除视频功能到 README/PROGRESS
补充 §5.1/§5.2 新增的 POST /api/oracle/video/delete + DELETE /api/ui/videos/<id>
端点说明、FAM-UI 页面表格、§12 当前进度;PROGRESS.md 记录完整变更 + 端到端
验证过程。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 04:28:55 +08:00
ericwyuan
2e370ab668 docs: 同步问答链路抽离到 ai-gateway 后的架构文档
README.md/PROGRESS.md 里大量描述还停留在"FAM-Edge 自己维护 Gemini→NVIDIA→
Ollama 问答降级链"的旧架构,跟实际代码(FAM-Edge 已改为转发客户端,模型链
整个搬到独立的 ai-gateway 服务)不一致,逐处订正:

- 新增 §3.4 AI-Gateway 模块章节、部署拓扑图、Gitea 仓库表新增 ai-gateway 条目
- 模块表(FAM-Core/FAM-Edge)、API 文档、数据库 compute_provider 说明更新
- §6.2/6.3 本地 Ollama 与模型适配器章节:去掉已删除的 OllamaAdapter/role=text,
  问答降级链路图重画为"FAM-Edge 转发 -> AI-Gateway 内部降级"
- 修复已经损坏(合并冲突残留)且过时的 fam-edge/config.yaml 示例,新增
  ai-gateway/config.yaml 示例;如实记录两份 .env 各自独立维护的实际部署状态
- PROGRESS.md 补一条 2026-08-23 变更记录 + 服务运行状态表新增 AI-Gateway 行

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 17:40:55 +08:00
ericwyuan
bdf561a415 fix(fam-core): 登录密码不再硬编码兜底(fail-closed) + 会话有效期改 2 小时
之前 FAM_AUTH_USER/FAM_AUTH_PASS 没配置时会退回代码里写死的 ericwyuan/
iLoveJava5——这两个值跟 NAS SSH 密码是同一个,且这个登录页已经通过 frp 暴露在
公网上。.env 万一没配置好(这个项目里已经发生过好几次"忘了 source .env"的
情况),公网入口就会用一个和 SSH 密码相同、且写在源码里的已知密码兜底,双重
风险叠一起。

现在改成 fail-closed:FAM_AUTH_USER/FAM_AUTH_PASS 只要有一个没配置,直接拒绝
所有登录(打一条 ERROR 日志提醒去配 .env),不再有任何硬编码默认值。

会话有效期从 7 天改成 2 小时(按用户要求)。

新增 test_auth.py 11 个用例覆盖:未配置时 fail-closed、正确/错误凭据校验、
只配了一半也要拒绝、session 过期判定、白名单路径匹配。

已实测验证:当前 .env 里 FAM_AUTH_USER/PASS 仍是配置好的(还是 ericwyuan/
iLoveJava5,这个值本身没改——只是不再硬编码在代码里,运维如果想换成不同于
SSH 的密码,现在改 .env 就行,不用改代码),登录/拒绝错误密码都验证正常,
cookie Max-Age=7200 确认生效。
2026-08-23 07:56:33 +08:00
ericwyuan
aca1a674b1 [文档] README 补充登录校验(auth 模块/凭据/白名单)与 frp 外网 8000 映射说明 2026-08-22 14:20:40 +08:00
ericwyuan
01a8ac2a3f [文档] 拓扑图 FAM-UI 标注同步为 Vue3(清理残留 Streamlit :8501) 2026-08-22 13:15:04 +08:00
ericwyuan
354ff18101 [文档] 代码-文档一致性整理 - README 同步 v3 全量(2.1网络/3模块表/4表结构/5 API含people-clips/6.1历史标注/8部署systemd+Vue3+config/12进度); docs/DEPLOY.md 重写为 v3; 删除过时 start_ui.sh(Streamlit); start_edge.sh 注明 systemd 为准; 补提交 test_motion_notifier 2026-08-22 13:14:38 +08:00
ericwyuan
ffcc292cce [文档] 同步 v3 运动事件驱动架构 - 整段素材分割运动片段再分析(不再整段送云端): README 1.1/2.2/2.2.1/2.3/模块表, PROGRESS 运行状态+变更记录; 记录 systemd 守护部署方式 2026-08-22 12:46:33 +08:00
ericwyuan
b2b537dde5 [文档] 同步 v3 运动监测架构(Webhook 驱动/去轮询) - README 补充 2.2.1 链路/API 表/模块表,PROGRESS 更新运行状态与变更记录 51-53 2026-08-22 11:11:15 +08:00
ericwyuan
ce27e4ab0c feat(fam-edge): 视频生产-消费队列 - 新增 video_queue.py(生产者扫描新文件入队+重启恢复,独立消费者线程云端分析);模型消费超时按原配置×timeout_multiplier(2);failed 重试上限 max_retries(2);删除旧 watch_processor 2026-08-21 12:01:25 +08:00
ericwyuan
44026b65ea [阶段3] FAM-Core 瘦身为管理后台+Oracle-Sync 同步引擎,FAM-UI 改读同步镜像 - 删除 scheduler/dispatcher/poller/event_receiver/video_server,新增 oracle_sync 每30分钟拉增量写 sync_* 镜像表;member_manager/chat_handler 改走同步数据;UI 移除帧图改为事件时间线;DDL 新增 sync_videos/events/people/cursor 2026-08-21 10:38:26 +08:00
ericwyuan
2e43afb6b2 docs(README/PROGRESS): 文档收尾,与架构重构代码对齐
1. README 8.3 节:fam-core 配置示例更新(video_dir 生产路径 + chat_handler.qa_url),fam-edge 配置示例对齐新架构(role/usage=qa_fallback、gemini-flash-latest、实际 timeout)
2. README 1.3 节:历史视频积压标记已处理(forward-only);吞吐不足表述更新(无本地融合)
3. README 5.3 节:改名为云端结构化输出 JSON Schema,描述适配器解析 + format_cloud_result 校验两阶段
4. README 6.2 节:移除融合 timeout 行,num_predict 更新为 512,已知问题改述为专职问答兜底
5. README 10.5/10.6 节:Gemini 模型名修正为 gemini-flash-latest;NVIDIA 验证状态更新为已验证
6. README 12 节:架构重构与双端部署验证纳入已完成;v1.1 待办移除已完成项 1-5,保留单元测试/Tailscale/daily_summaries
7. PROGRESS.md:服务状态表更新(新架构、qwen2.5:7b);任务进度追加 32-38;技术决策记录追加云端直出直存与 Q&A 降级;聊天链路验证段更新为 run_qa 编排
2026-08-20 10:45:29 +08:00
ericwyuan
babf5b09a9 [架构重构] 移除本地Ollama融合,云端直出JSON直存DB,Q&A三模型降级
1. 视频摘要链路:云端VLM直出结构化JSON → Edge format_cloud_result格式化校验 → 直存NAS DB(移除run_text_fusion本地融合)
2. 智能问答链路:Gemini→NVIDIA→Ollama降级,新增chat()纯文本问答方法
3. 适配器重构:base/gemini/nvidia/ollama adapter新增chat();gemini多图单请求结构化JSON;nvidia逐帧调用聚合
4. 端点变更:/api/edge/chat → /api/edge/chat/ask,调orchestrator.run_qa()
5. chat_handler改经Edge Q&A编排,不再直连Ollama
6. 配置更新:ollama_url → qa_url,Ollama role注释改为Q&A兜底
7. README同步更新架构描述、拓扑图、时序图、模块表
2026-08-20 10:21:09 +08:00
0af541097f 更新 README.md 2026-08-20 01:00:53 +00:00
0045b074a2 更新 README.md 2026-08-20 01:00:05 +00:00
ericwyuan
3a5ea459a2 docs: 需求文档与 README 整合为单一文档
- 按当前代码实际状态重写:推送模式架构、自适应关键帧、实际 API 端点
- 补充实测性能基准(30min视频929s)、E2E 验证结果、可靠性加固机制
- 记录已知遗留问题(多图失效/吞吐不足)与 v1.1 计划
- 项目需求文档.md 内容并入后删除
2026-08-20 07:19:55 +08:00
ericwyuan
e7fb0c92bc docs(readme): 记录 Gemini API Key 与调用示例(gemini-flash-latest,已验证可用) 2026-08-20 02:18:42 +08:00
ericwyuan
e5ac667586 [deploy] NAS MariaDB DDL 执行 + Tailscale 状态 + README 更新
- NAS MariaDB 10.11.11 确认可用, root 密码 iLoveJava5!
- DDL 执行成功: sentinel_home_ai 库 + 6 张表 (process_tasks, monitor_events, daily_summaries, event_details, chat_history, family_members)
- NAS Tailscale 已运行, IP: 100.70.234.39
- Oracle Tailscale 1.102.2 已安装, 待用户认证
- README 新增 MariaDB 密码 + Tailscale IP + NAS 型号信息
- PROGRESS.md 更新全部环境状态
2026-08-19 23:08:21 +08:00
ericwyuan
ba905d2f84 [1.1] 服务器访问信息 - NAS/Oracle SSH 凭证 + Gitea 账号记录到 README 2026-08-19 22:46:31 +08:00
ericwyuan
3a315c7129 [1.0] 项目初始化 - 目录结构 + README + .gitignore 2026-08-19 22:17:23 +08:00