本卡屬 FR-192(母卡 FR-192 母案(同清單上一張)),卡 M-3,批 3。只改 BE(主 repo,Repo 欄空著)。依賴:A-1、I-1。
主系統收 Agent 送來的回饋的那支端點。Agent 用控制面通行證打進來,一次最多 50 筆,每筆帶動作(新增/修改/刪除)。端點要:驗送件人是這租戶的人或 local-admin;新增就建成 jedi-issue 的正常回饋並標來源;修改先比版本時間(主系統較新回「過期」);刪除走既有刪回饋;Agent 附件每個建一筆「檔在 Agent」的參照列;一張對照表記「哪台+Agent 端編號 → 主系統回饋編號」做去重與溯源。附件建參照那段邏輯主系統已有(證據檔走 Agent 儲存時用的),是私有方法,本卡抽成公開的給兩邊共用,不複製。另外設定通道加「類別選項」這一類。
new(照型):route 照 api/source_scan/routes/agent_manual_scan_route.py、service 照 jedi-remote-agent local_run_service.ingest(通行證身分、批次、accepted/rejected);extend:RemoteAgentAdapter._add_reference 抽成公開 register_agent_blob(),收單與既有上傳共用;設定類 provider 照 _agent_config_sections.py 既有 provider 形狀;對照表 migration 照 011-remote-agent-offline-operators.sql 的 RLS/GRANT
repo:~/Projects/Billows/Audit-Manager/compliance-manager-be
改既有:infra/upload_file/remote_agent_adapter.py 158(_add_reference → register_agent_blob 公開)
改既有:core/plugins/_agent_config_sections.py(feedback_labels provider)
改既有:core/plugins/remote_agent.py(route 登記一行)
改既有:di_containers/remote_agent_container.py(intake service wiring)
改既有:common/enum/event_code.py(AGENT_FEEDBACK_RECEIVED)
改既有:scripts/sql/manifest.tsv(登記兩支:本卡 014 鏡像+M-1 的 seed,M-1 不碰此檔)
改既有:scripts/sql/packages/jedi_remote_agent/(鏡像 014)
新開:api/remote_agent/routes/agent_feedback_route.py
新開:app/remote_agent/service/agent_feedback_intake_service.py
新開:common/code/agent_feedback_error_code.py
新開:jedi-remote-agent/jedi_remote_agent/migrations/014-agent-feedbacks.sql(compliance.agent_feedbacks;套件側檔)
新開:test/test_agent_feedback_intake.py
infra/upload_file/remote_agent_adapter.py,開工先 git log --oneline -3 -- infra/upload_file/remote_agent_adapter.py 看它合回沒;沒合回停下回寫「等 FR-188 M-4」。remote_agent_adapter.py 第 158 行 _add_reference 改名為公開 register_agent_blob(agent, *, agent_file_uid, file_name, size, mimetype, sha256, user_name, storage_scope="customer", owner_user_id=None) -> UploadFileEntity,path=agent.base_url;原 save_file 內呼叫改用它。只抽不改行為。api/remote_agent/routes/agent_feedback_route.py(照 api/source_scan/routes/agent_manual_scan_route.py:@agent_pass_required、current_agent()、DI Provide);core/plugins/remote_agent.py route 登記一行 ("/agents/feedbacks", AgentFeedbackRoute) 進 agent 端點組;di_containers/remote_agent_container.py wiring agent_feedback_intake_service。app/remote_agent/service/agent_feedback_intake_service.py:ingest(items, principal) 在 agent_tenant_context 內逐筆——(a) 形狀驗證照 FEEDBACK_ITEM_KEYS,超 50 筆 400;(b) created_by:user_domain_service 查該租戶啟用使用者 login_name,或等於 LOCAL_ADMIN_LOGIN_NAME,否則 rejected unknown_user;(c) 對照表 agent_feedbacks 查 (agent_id, local_uid)——create 已存在回 accepted 不重建;update 比 base_cloud_updated_at 與 feedback_issues.updated_at,主系統較新回 stale;delete 走 feedback_service.delete_feedback(uid, login_user_name=created_by)(local-admin 走代管身分:傳 has_capability=lambda _: True)並對照表 deleted_at=now();(d) files 每項 register_agent_blob(),remove_file_uids 走 delete_feedback_file;(e) add_feedback(title, content=description, labels=[type_label_uid, AGENT_CONSOLE_FUNCTION_LABEL_UID], attached_file_uids=[…], user_login_name=created_by, source=SOURCE_AGENT, source_ref=agent.uid) 或 update_feedback;(f) 對照表寫列。回 {accepted:[local_uid], inserted, stale:[local_uid], rejected:[{local_uid, reason}]}。migrations/014-agent-feedbacks.sql(compliance.agent_feedbacks,欄位照 design §5.4,RLS 四指令與 GRANT 照 011;套件版號 minor +1 由本卡 bump);主專案 scripts/sql/packages/jedi_remote_agent/014-… 鏡像;domain entity/repo/service 照 local_run 那組形狀放套件。core/plugins/_agent_config_sections.py 加 feedback_labels provider:回 labels 表 scope=FEEDBACK_TYPE, is_deleted=false 的 [{uid, name}],version 內容雜湊。common/enum/event_code.py 加 AGENT_FEEDBACK_RECEIVED;common/code/agent_feedback_error_code.py 新檔(AGENT_FEEDBACK_400001 批次超限等)。scripts/sql/manifest.tsv 本卡一次登記兩支:014 鏡像+M-1 的 seed(M-1 不碰 manifest);DEV 套 014。test/test_agent_feedback_intake.py:驗收列的每一條各一個 case;BE 重啟後用 123 Agent 的通行證(或 AGENT_AUTH_MODE=none 本機 Agent)實打。DEV 套 014 後 \d compliance.agent_feedbacks 有 RLS 四指令與 (agent_id, local_uid) 唯一;用 123 Agent 的通行證打 50 筆 create 回 accepted 50、第 51 筆 400;重送同 local_uid 回 accepted 不重建;created_by 不是該租戶的人回 rejected unknown_user;local-admin 放行且 feedback_issues.created_user=local-admin;帶 files 的那筆 upload_files 多一列 storage_type=remote_agent、save_file_name=Agent 檔 uid、path=該 Agent base_url;update 帶舊的 base_cloud_updated_at 回 stale;delete 後 feedback 不在、對照表 deleted_at 有值;GET /agents/config 回 feedback_labels 三個;BE 重啟實打;守衛測試綠;回寫明講「出貨基線待重產」