本卡屬 FR-091(母卡 CM-1690)第二批。中量:有 DB 表(upload_files)、2 支 migration、6 條 route。主專案 venv 裡這支是 Nexus wheel 0.0.23,不是工作樹——所有主專案側驗證必帶
PYTHONPATH。主專案側接線已由 CM-1689 收進core/plugins/file_upload.py,本卡不動主專案。
jedi-file-upload(檔案上傳與儲存後端)plugin.py 352 行塞 6 個 dataclass,api/init.py 113 行含 ctx() 14 處,logger 三種名("app"、"infra"、name),前兩個會跟主專案 logger 撞名、log 落到別人的 handler。tests/integration/ 有 conftest 與 initdb 但 0 支測試。本卡整成 jedi-asset 那個樣子。
首腦核對(2026-09-12):plugin.py 352 行 6 dataclass;api/init.py 113 行;route 6;entity 檔 1(0 dataclass);表 upload_files;migration 2 支;tests 118 支(unittest/architecture/根層兩支 adapter convert_to_pdf 測試/test_plugin_contract.py);tests/integration/ 空骨架;harness 有 compose、無 --smoke;施工日誌 17 處;ctx() 14 處;logger "app"/"infra"/name;有吐 created_user_name(6 處)但已走 D8 identity 欄位+app/service/identity_enricher.py,不必再開新 port。主專案 pyproject.toml:100 pin jedi-file-upload==0.0.23,path override 在 196/259 行是註解掉的——venv 是 wheel。
套件:/Users/chouraymond/Projects/Jedicogy/module/jedi-python-package/jedi-file-upload/
範例:jedi-asset/(plugin/ 五檔、api/guards.py+routing.py、tests/unittest/test_plugin_layout.py、tests/integration/test_service_behaviour.py、harness --smoke)
SOP:extraction-sop.md §4.3/§3.4/§6.1/§8;說明:plugin-anatomy.md
主專案 import 面:grep -rn "from jedi_file_upload\|import jedi_file_upload" compliance-manager-be --include='*.py' --exclude-dir=.venv(18 檔:core/plugins/file_upload.py、app/upload_file/、infra/upload_file/、di_containers/upload_file/ 等)
主專案側不動的例外:infra/upload_file/remote_agent_adapter.py 被 app/ 直接 import,守衛白名單登記,留原地
plugin.py → plugin/ 五檔(含 migrations.py,MIGRATIONS_DIR 用 parent.parent);api/__init__.py → guards.py+routing.py。對外 import 路徑一字不改,__all__ 列齊。主專案 18 檔 import 這支,拆完要用 AST 掃主專案全部 import(不是 grep 符號名)逐一實跑——CM-1689 runner 用 grep 漏了被 route 直接 import 的函式,起 BE 才炸。common.jedi_file_upload("app"/"infra" 兩處撞名必改);命名統一。inspect.signature 逐欄對照預設值。test_*_adapter_convert_to_pdf.py 若能歸進 tests/unittest/ 就歸,不能就留並在 README 說明為什麼在根層。--smoke(test client 不綁 port);pyproject.toml 加 addopts = "--import-mode=importlib";README 補新結構與接線路徑(含儲存後端切換那幾條陷阱,若原 README 已有就保留)。tests/integration/test_service_behaviour.py:真 postgres 套 001/002,app service 走一輪建立→查詢→刪除,斷言 grant/RLS 生效。儲存後端用 local 檔案系統(tmp 目錄)就好,不接 MinIO/SeaweedFS。照 jedi-asset 那支的骨架。test_plugin_contract.py 凍結集合整理前後同綠。.venv/bin/python -c "import jedi_file_upload;print(jedi_file_upload.__file__)"——首腦已查是 site-packages 的 wheel,所以主專案側每一條驗證都要 PYTHONPATH=/Users/chouraymond/Projects/Jedicogy/module/jedi-python-package/jedi-file-upload,否則假綠。不要為了驗證去改主專案 pyproject.toml 的 pin。pytest tests/ --import-mode=importlib(需 docker);harness --smoke;主專案 PYTHONPATH=... pytest test/test_module_boundaries.py;主專案 18 檔 import 逐一 PYTHONPATH=... python -c 實跑。