Skip to content

chore: upstream downstream DB-first、i18n、Telegram 與部署維護改動#325

Draft
causecos wants to merge 46 commits into
cft0808:mainfrom
causecos:fix/dashboard-db-mode-contract-20260606
Draft

chore: upstream downstream DB-first、i18n、Telegram 與部署維護改動#325
causecos wants to merge 46 commits into
cft0808:mainfrom
causecos:fix/dashboard-db-mode-contract-20260606

Conversation

@causecos

@causecos causecos commented Jun 6, 2026

Copy link
Copy Markdown

Summary / 摘要

這個 PR 是我在 downstream fork 中整理的一組維護性改動,主要涵蓋:

  • Dashboard DB-first / DB mode 任務狀態來源與 mutation contract
  • 繁體中文本地化與 fanti variants 同步
  • Telegram 通知管道與 task list CLI workflow
  • dispatch / event-bus-first 工作流整理
  • Docker、systemd、install script、config 與安全性修正
  • 測試、README、部署與維護文件補強

目前先以 draft PR 形式提出,主要目標是讓 upstream maintainer 先看到 downstream fork 中已驗證的一組改動,並確認後續是否要拆成多個較小 PR 逐步合併。

Motivation / 動機

我在 fork 中實際部署與驗證 edict 時,遇到幾類問題:

  1. Dashboard 在 DB-first / DB mode 下,部分 task mutation 仍與 backend API contract 不一致,導致 task state、stop/resume/cancel、public task id、scheduler/progress 更新等行為不穩定。
  2. 對繁體中文使用者而言,部分文件、前後端字串與 fanti variants 需要更一致的同步方式。
  3. 原本通知與 dispatch workflow 中有 Feishu / Telegram、source channel、task list output 等路徑差異,實際操作時需要更清楚的一致性。
  4. 部署與本地運行時,Docker、systemd、install script、.env.example、API key、hardcoded password 等部分需要補強。
  5. 部分測試、E2E、kanban state machine、task mutation race 等行為需要明確測試覆蓋。

因此這個分支不是單一 bug fix,而是 downstream fork 的一組維護整理。這個 draft PR 先用來同步方向,後續我可以依 maintainer 偏好拆分。

Major changes / 主要修改範圍

1. Dashboard DB-first / DB mode

  • 將 Dashboard DB-mode mutation path 對齊 backend API helpers。
  • 對齊 task transition payload,使用 backend 預期的 new_state
  • 支援 DB mode 下的 stop / cancel / resume。
  • 避免 task create 後重複 transition 到 Taizi
  • 保留 public task id,同時維持內部 UUID task id 相容性。
  • 補強 scheduler、progress、metadata、flow entries 的 patch/update 路徑。

2. i18n / 繁體中文本地化

  • 加入繁體中文本地化工具與 fanti variants 同步流程。
  • 同步 backend / frontend 相關繁中內容。
  • 補充繁中維護與使用文件。
  • 清理重複 _fanti 檔案,避免長期維護分歧。

3. Telegram / 通知與 CLI workflow

  • 將通知管道從 Feishu 調整為 Telegram-oriented workflow。
  • task 建立時記錄 source channel,dispatch 時優先使用任務來源 channel。
  • 補強 TG CLI task list output。
  • 加入中文 alias,例如任務清單相關命令。
  • 調整 task list 顯示邏輯,包含 content / progress / report-first output。

4. Dispatch / event-bus-first workflow

  • 統一 dispatch 邏輯,減少重複 dispatch code。
  • 同步 event-bus-first workflow rules。
  • 修正 openclaw path resolution 與常見 bin 目錄搜尋。
  • 修正 report content 在 DB task flow 中的保存與傳遞。

5. 安全、config、部署與運行環境

  • 為 backend write endpoints 加入 API key authentication。
  • 移除 hardcoded passwords,改用 .env 與動態生成。
  • 修復 docker-compose 設定,包含 Redis URL 與 worker services。
  • 修正 systemd service 與 edict.sh,支援 all-services management。
  • 補強 install.sh idempotency。
  • .env.example、service name、port、runtime artifacts、dead-code cleanup 等維護修正。

6. Tests / 測試

  • 補強 Dashboard DB-mode contract tests。
  • 補 task mutation race handling 測試。
  • 補 task API contract、review action、session-agent visibility 測試。
  • 修復 kanban compatibility、E2E state machine、dispatch mock tests。
  • 集中 pytest repo-root bootstrap 到 conftest.py

7. Documentation / 文件

  • 補充 README 中的 DB-first、mode switch、backend architecture、安全、部署、通知管道、本地化與 dead-code cleanup 說明。
  • 加入 Maintained Fork Notice,說明 fork 目標、改動狀態與 upstream PR 方向。
  • 補齊 backend 中文註解與維護文件。

Testing / 測試狀態

這個分支已補上與更新多組 pytest coverage,重點包含:

  • Dashboard DB-mode task mutation contract
  • task transition payload contract
  • stop / cancel / resume in DB mode
  • public task id 與 internal UUID 相容性
  • task mutation race handling
  • task API behavior
  • Dashboard review/action contract
  • kanban compatibility
  • dispatch mock behavior
  • session-agent visibility policy

主要相關測試檔案包含:

  • tests/test_dashboard_db_mode_contract.py
  • tests/test_dashboard_review_action.py
  • tests/test_task_mutation_race.py
  • tests/test_tasks_api_contract.py

Review notes / Review 說明

這個 PR 目前範圍偏大,原因是它整理的是 downstream fork 中一組互相關聯的實際部署與維護修正,而不是單一 isolated bug fix。

我先以 draft PR 提出,主要希望先同步整體方向。若 maintainer 覺得直接 review 這個 PR 成本太高,我可以拆成以下幾個較小 PR:

  1. Dashboard DB-first / DB-mode mutation contract
  2. i18n / 繁體中文本地化與 fanti variants cleanup
  3. Telegram 通知與 task list CLI workflow
  4. dispatch / event-bus-first workflow cleanup
  5. security / config / .env / API key auth
  6. Docker / systemd / install script 修正
  7. tests only
  8. docs only

Compatibility / 相容性

這組改動的目標是讓 downstream 實際部署路徑更穩定,同時盡量保留既有 JSON/shadow mode 與原本 task workflow 的相容性。

其中 DB-first / DB mode 行為仍由 task source mode configuration 控制;繁體中文與 Telegram 相關改動也可依 upstream 方向再拆分或調整。

太子 added 30 commits June 3, 2026 01:37
- scripts/dispatch.py: 新增統一派發模組 dispatch_for_state()
- scripts/kanban_update.py: create/state/done 時自動 trigger dispatch
- dashboard/server.py: 派發入口統一轉發至 dispatch.py 實作

解決 kanban_update.py 與 Dashboard Server dispatch 邏輯不一致的問題。
- config.py: default_dispatch_channel feishu → telegram
- data/agent_config.json: dispatchChannel → telegram (需手動同步)
解決 dispatch_worker 無法找到 openclaw CLI 的問題(shutil.which 在 PATH 缺失時返回 None)。
dashboard/server.py 有獨立的 _resolve_openclaw_bin(),優先檢查
常見 bin 目錄,避免 scheduler_scan 無法找到 CLI 的問題。
1. cmd_create() 新增 --source 參數(格式:telegram:493683906)
   任務 JSON 新增 source 欄位:{channel, target}
2. dispatch_for_state() 優先使用 task.source.channel
   僅在任務無 source 時才使用全域 dispatchChannel 設定
3. 修復 dashboard server 獨立的路徑解析(與 dispatch.py 同步)
- 新增 scripts/fanti_convert.py:簡體→繁體轉換工具(zhconv/opencc)
- dashboard/server.py:--host 預設值改為 0.0.0.0(支援外網訪問)
Current state includes:
- Dashboard i18n (3-language support: zh_TW/zh_CN/en, 459 keys)
- Backend trace_id VARCHAR(32→64) fix
- Orchestrator stall detection expanded to 9 states
- /api/source-mode endpoint
- test_20260602_fixes.py (38 tests passed)
- Various Dashboard bug fixes (TDZ, i18n loading, tab translation)
Dashboard now uses i18n.json for language switching instead of
maintaining separate _fanti copies. Scripts that were identical
copies are removed; differing scripts will be parameterized via
CLI args or i18n if needed in the future.
- New auth.py module: X-API-Key / Bearer token auth via Depends
- Protected: POST/PUT endpoints on tasks, admin, legacy routers
- Open: GET endpoints (dashboard reads, health checks)
- Fixed CORS: allow_origins=[*] + credentials=True removed,
  replaced with localhost-only allowlist
- Dashboard server.py: passes API key to backend if EDICT_API_KEY set
- Config: api_key field added (default '' = dev mode, no auth required)
- When API_KEY env var is set, write endpoints require auth
… add worker services

- Fixed REDIS_URL: was postgres:5432/edict → redis:6379/0
- Added orchestrator, dispatch, outbox_relay worker services
- Backend depends_on postgres+redis with healthcheck conditions
- Password via POSTGRES_PASSWORD env var (required, not defaulted)
- Ports configurable via PG_PORT, REDIS_PORT, BACKEND_PORT env vars
…ation

- config.py: postgres_password now uses default_factory=_generate_secret()
  (64-char random hex, overridable via POSTGRES_PASSWORD env var)
- config.py: api_key and secret_key added (env-var driven)
- .env.example: all passwords/keys changed to CHANGE_ME placeholders
- Security rule cft0808#2 enforced: no hardcoded secrets in code
… management

- edict.service: fixed User/Group/WorkingDirectory paths to actual values
- edict.service: added After=postgresql.service redis.service dependency
- edict.sh: added start-all / stop-all / restart-all commands
- edict.sh: now manages Backend (uvicorn) + 3 Workers + Dashboard + Loop
- PID files for all services under .pids/; logs under logs/
- dispatch_worker: returncode 1,2 changed from retryable=True to False
  (rc=1 is CLI usage error, rc=2 is misuse — not transient)
- tasks.py: TaskCreate.title now has max_length=500 (Pydantic Field)
- tasks.py: TaskCreate.description max_length=5000
- Long titles now return 422 (was 500 Internal Server Error)
…anges.json

- AGENTS.md creation now checks existence before overwriting
- pending_model_changes.json only initialized if not exists
- Prevents data loss on re-install
太子 added 16 commits June 3, 2026 01:43
…spatch mock tests

config: env_file from CWD-relative to __file__-absolute path
  - pydantic-settings loads .env from CWD, breaking when pytest runs from tests/
  - Changed to Path(__file__).resolve().parent.parent / '.env'
  - Added from pathlib import Path import
  - test_config: Settings(_env_file=None) for default-password test

e2e: fix state machine transitions to match STATE_TRANSITIONS
  - Zhongshu → Menxia → Assigned (not skip Menxia)
  - Assigned → Doing → Done (not skip Doing)
  - Fix progress field: message → content

test_sync_agent_config: add scripts/ to sys.path for file_lock import

test_dispatch_mock (new): 37 task dispatch tests with mocked _call_openclaw
  - Context builders: _build_task_context, _build_reminder (7 tests)
  - Injection detection: _sanitize_agent_output (5 tests)
  - Dispatch flow with mock: success/failure/retry/dedup (6 tests)
  - Orchestrator: task_created/status/stalled/failed (19 tests)
  - Zero provider dependency — all model calls mocked
…xpansion

_ensure_dirs: [ ! -f ] && → [ -f ] || to survive set -e
start-all/stop-all: fix indirect variable expansion for worker PID/LOG files
- 移除 agentrec_advisor.py / linucb_router.py(已廢棄的推薦/路由模組)
- 清理 dashboard/auth.py 未使用的 import
- dashboard/server.py 改用 pathlib 解析 home dir
- 清理 dispatch/orchestrator worker 死碼
- 配置加固(API_KEY / DB 密碼改用 .env 注入)
- README 更新架構說明:區分 stdlib Dashboard vs FastAPI backend
- 測試從 49 passed → 225 passed
- fix(cft0808#2): config.py 補 heartbeat_interval_sec 欄位(避免 dispatch_worker AttributeError)
- fix(cft0808#4): test_skill_manager.py 同步重構後 6-skill OFFICIAL_SKILLS_HUB
- fix(cft0808#5): 清理 9 檔案未使用 import、7 個死常量、1 個死函數
- fix(cft0808#6): edict.service 改用 EnvironmentFile= 代替明文 Environment=
- fix(cft0808#7): AGENT_META 補齊 taizi、libu_hr
- .gitignore 新增 edict.service.env

250 tests passed, 0 failed
涵蓋 11 個檔案,245+ 行註解:

models:
- audit.py: 設計原則(append-only、跨任務檢索、索引設計)
- task.py: 狀態機流轉圖、雙層欄位設計、to_dict 兼容層
- event.py: 雙層事件模型(topic/event_type/producer)

auth:
- _extract_api_key: 優先級與 strip 原因
- require_api_key: 4 步驗證流程 + timing-safe 比較
- generate_api_key: lru_cache 語義

config:
- _generate_secret: 256-bit 熵說明、token_urlsafe 選擇理由
- database_url/database_url_sync: async/sync 雙 URL 策略

api:
- tasks.py: 每個端點的過濾/事務/outbox 語義
- agents.py: AGENT_META 結構、SOUL.md 路徑解析

services:
- task_service.py: Transactional Outbox 保證、SELECT FOR UPDATE 並發控制
- event_bus.py: XREADGROUP/XACK/XAUTOCLAIM 語義

workers:
- outbox_relay.py: SKIP LOCKED 並行、DLQ 策略
…u/死檔

fixes:
- cft0808#6: README port 8900→8000,service 名稱對齊 (dispatch→dispatch-worker, outbox→outbox-relay)
- cft0808#13: 三語言 README 移除 agents/ 重複段落
- cft0808#7: flow_log Column comment 補齊 7 欄位 (from,to,agent,reason,remark,ts,at)
- cft0808#5: .env.example 清除 6 個死變數,補 SCHEDULER_SCAN_INTERVAL_SECONDS,feishu→telegram
- cft0808#1: .env.example BACKEND_PORT→PORT
- cft0808#3: api/agents.py libu 錯標吏部→禮部
- cft0808#9: 刪除死檔 kanban_update_edict.py
- cft0808#10: 刪除死檔 edict.service.env + .gitignore
- cft0808#11: edict.service %h 可攜路徑,移除不存在 install-services 引用
- cft0808#15: 朝堂议政_開發规格.md → docs/ + git track
- EN/JA README: 3 處 Feishu→Telegram
- README EN/JA 完整同步至中文版(含 fork 改動表、近期更新、systemd 部署、troubleshooting 等)
- Badge 修正:Zero Backend Dependencies → FastAPI + PostgreSQL + Redis
- 新建 CHANGELOG.md、docs/api-reference.md、docs/db-schema.md
- docs/getting-started.md 管道更新為 Telegram
- docs/design-docker.md port 3926→7891
- docs/performance-baseline-plan.md port 改用 DASHBOARD_PORT env
- CONTRIBUTING.md E2E 測試數 24→17(與檔案內第 182 行一致)
- 刑部 SOUL.md 補上「共用函式契約」段落
- README 近期更新章節補上 5 項近期修正
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant