本卡屬 FR-114 資安修正(母卡 CM-2019),掃描線分析 CM-2108 第 2 件,決策者 09-24 裁同批到位、同意動 jedi-survey。🔴 依賴 CM-2113(全系統唯一的任務歸屬判斷)先 commit 進 BE 工作區才能接線。jedi-survey 已在發版清單,不增支數;發版卡 CM-2110 第三段等本卡。
任務問卷的讀、填、管理三道守門,都要先知道「這個任務屬於哪個專案」,再看你是不是那個專案的成員或管理人。現在套件自己拿主程式交給它的「指派表存取權」去翻,取第一筆指派列的專案——但任務剛建好時沒有指派列,於是還沒指派人的任務問卷,連專案管理人都讀不到、管不了(403)。根本問題是主程式交出去的是「原料」(整張表),判斷留在套件裡,套件就自己發明了錯的查法。改成主程式直接交「判斷」:給任務編號、回專案編號,套件只呼叫、不自己推。
套件 jedi-survey/jedi_survey/app/common/task_survey_guard.py (84 行)
:34-42 _resolve_project_id_by_task(task_assignee_domain_service, task_id):翻指派表取第一筆 project_id ← 要換掉
:45 assert_task_survey_writer 第 1 步「你是不是被指派人本人」查指派表(保留,這是指派表本職);第 2 步 manager 代填靠 _resolve
:67 assert_task_survey_reader 靠 _resolve
:79 assert_task_survey_manager 靠 _resolve
套件 jedi-survey/jedi_survey/domain/ports.py 既有 ITaskUidResolver 等 port 的寫法(新 port 照這裡的格式與 docstring 風格)
套件呼叫三守門、要多收 port 的服務:
app/service/question_answer_history_detail_service.py、question_answer_history_service.py、question_answer_service.py、
survey_discussion_service.py、task_survey_service.py、app/handler/fill_survey_socketio_handler.py:64
(目前都以 svc.task_assignee_domain_service, svc.participant_role_service 兩參數呼叫守門)
主程式注入點:
BE di_containers/task_survey/question_answer_containers.py:76-97(三處同形)、di_containers/task_survey/task_survey_containers.py、di_containers/survey/survey_containers.py
BE infra/survey/adapters.py:77 既有 ITaskUidResolver 宿主實作(新 port 的實作放同檔或同目錄)
保留:task_survey_service.py:496 用指派清單寄通知(指派表本職,不動)
套件 /Users/chouraymond/Projects/Jedicogy/module/jedi-python-package/.claude/worktrees/jedi-wt-fix-security branch fix/security-b1
BE /Users/chouraymond/Projects/Billows/Audit-Manager/compliance-manager-be/.claude/worktrees/wt-fix-security branch fix/security-b1
🔴 主 checkout 不動。開工先確認 CM-2113 已 commit(BE 工作區 git log --oneline -5 看得到它、Notion CM-2113 回寫有寫三個方法名);沒有就停下回寫等。發版卡 CM-2110 可能同時改 pyproject.toml——你不碰任何 pyproject/lock。
domain/ports.py 新增 port(例 ITaskProjectResolver),單一方法 resolve_project_id(task_id: int) -> Optional[int];docstring 寫明「查無回 None,呼叫端一律視為拒絕;宿主實作須用全系統唯一的任務歸屬判斷,不可查指派表」。task_survey_guard.py:_resolve_project_id_by_task 改呼叫 port;三個守門的簽章把「推專案用的 task_assignee_domain_service」換成 port(writer 第 1 步仍需要 task_assignee_domain_service 判斷「是不是被指派人本人」→ writer 兩個都收,reader/manager 只收 port+participant_role_service)。守門的判斷規則本身不動,fail-closed 不變。docstring 的「判定資料來源」段同步改。plugin/contract.py、plugin/assembly.py,照 ITaskUidResolver 怎麼登記的),新 port 一併登記。resolve_project_id_for_task_id(不准另寫 SQL);三個 container 注入。git grep -n "_resolve_project_id_by_task\|\.project_id" -- jedi-survey/jedi_survey 逐條說明每一處用途,指派表只剩「誰被指派/你是不是被指派人/寄通知給被指派人」。