單一使用者的本機圖片管理系統(Windows 11),為十萬量級、以動漫圖為主的圖庫而設計。
核心理念:把「邏輯分類(tag)」跟「檔案系統」徹底脫鉤 —— 原圖就地索引、絕不搬動,以 tag 與布林查詢看圖,資料夾只是眾多 tag 軸之一。
完整設計與決策理由見
docs/design/2026-06-21-picture-management-design.md; 不可違反的鐵則與開發約定見AGENTS.md;部署/散布見docs/deployment.md。
file_hash(SHA-256)是圖片身分,file_path 只是位置。搬移、換碟、副本、去重都不影響 tag。/browse 並列,互不干擾。path / manual / wd14,自動標帶 confidence,不與手動策展混淆。Angular SPA
↓ REST(同源 localhost;ng serve 開發時走 proxy)
Pm.Api(啟動、DI、API endpoints、serve 前端靜態檔)
├─ Pm.Scanner 掃描、縮圖、EXIF、查詢、tag closure/facet、路徑→tag(service 層)
├─ Pm.Data EF Core、SQLite、九張 Entities、migrations
├─ Pm.Ml ONNX 推論後端抽象 IInferenceSessionFactory + WD14 pipeline
└─ Pm.Imaging AVIF/HEIC/HEIF 解碼橋接(Magick.NET/libheif → ImageSharp)
需求:.NET SDK 10.0.301、Node 24.x / npm。
# 1) 先 build 前端,輸出進 Pm.Api/wwwroot
cd src/Pm.Web ; npm ci ; npm run build
# 2) 起後端(同時 serve API 與前端於 http://localhost:5180)
cd ../.. ; dotnet run --project src/Pm.Api
瀏覽器開 http://localhost:5180。首次啟動自動建 pm.sqlite、套 migration。
dotnet run --project src/Pm.Api # 後端 :5180
cd src/Pm.Web ; npm start # ng serve :4200,/api 經 proxy 轉 :5180
# 註冊一個來源資料夾(Windows 路徑用正斜線免跳脫)
curl -X POST http://localhost:5180/api/roots -H "Content-Type: application/json" `
-d '{"name":"my-lib","absPath":"D:/pics"}'
# 觸發掃描(就地索引,絕不搬動原檔);POST 回 202,結果由 scan-status 輪詢
curl -X POST http://localhost:5180/api/roots/1/scan -H "Content-Type: application/json" -d '{}'
curl http://localhost:5180/api/roots/1/scan-status
之後在 UI 的「匯入確認」頁確認路徑→tag 規則。
把 Inference:Wd14:Enabled 設為 true(src/Pm.Api/appsettings.json 或環境變數),並視硬體設 Inference:Wd14:Backend(directml 預設 / cpu)。首次標註會自動下載 WD14 模型(~300MB)+ selected_tags.csv;關閉時零開銷、不下載。
# 例:以環境變數臨時開啟(走 CPU)
$env:Inference__Wd14__Enabled = "true"; $env:Inference__Wd14__Backend = "cpu"
dotnet run --project src/Pm.Api
dotnet test # 後端全測試
cd src/Pm.Web ; npm test # 前端(vitest + jsdom)
cd src/Pm.Web ; npm run e2e # 瀏覽器 e2e(@playwright/test;webServer 自動起 app)
cd src/Pm.Web ; npx ng build # 前端 → wwwroot
dotnet publish src/Pm.Api -p:PublishProfile=win-x64 # DirectML(預設)→ publish/(exe ~75MB + wwwroot)
# 另兩個推論 flavor(各為獨立 build,程式碼不動,僅換 profile):
dotnet publish src/Pm.Api -p:PublishProfile=win-x64-cuda # CUDA(NVIDIA,24H2 以下)
dotnet publish src/Pm.Api -p:PublishProfile=win-x64-windowsml # Windows ML(Win11 24H2+)
免裝 runtime、雙擊即跑。完整部署/設定/散布見 docs/deployment.md。
| 東西 | 位置 | 備註 |
|---|---|---|
| 資料庫(唯一真相) | pm.sqlite | 備份=複製此檔(可用 sqlite3 CLI VACUUM INTO 熱備);tag manifest 匯出為規劃中、app 尚未內建 |
| 縮圖快取 | thumbs/(依 hash 分桶) | 衍生資料,可重建;512px webp |
| WD14 模型 | models/wd14(opt-in 時下載) | 衍生資料,可重建 |
| 原始圖檔 | 你的來源資料夾 | 唯讀,絕不修改/搬移/改名,不寫 XMP |
預設程式與資料分離(資料落 %LOCALAPPDATA%,Windows 正規做法);攜帶版可用 Storage:BaseDir 讓資料貼著 exe。
Phase 1 核心可端對端運作:掃描就地索引 → SHA-256 身分 → 縮圖 → 布林查詢 → Angular 相簿,前端各畫面已接真實 API。
/browse(即時樹 + 麵包屑 + 下鑽 + 遞迴圖牆)/openapi/v1.json + Scalar 互動式文件 /scalar/v1InferenceFlavor 切套件,各有 publish profile + CI matrix。CPU / DirectML 已實機驗證;CUDA / Windows ML 已編譯與 publish 驗證,runtime 推論需對應硬體/OS(無 GPU 或非 24H2 環境無法在此驗)各子系統的設計與決策見 docs/design/。
src/
Pm.Api/ ASP.NET Core 宿主:DI、migration、API endpoints、serve wwwroot;TaggingWorker(背景服務)
Pm.Scanner/ 掃描 + 縮圖 + EXIF + 查詢 + tag closure/facet + 路徑→tag + TagService(service 層)
Pm.Data/ EF Core:Entities/(九實體)、PmDbContext、Migrations/
Pm.Ml/ 推論後端抽象 IInferenceSessionFactory(三 flavor:DirectML 預設 / CUDA / Windows ML,編譯期切;無 GPU 退 CPU)+ WD14 pipeline
Pm.Imaging/ AVIF/HEIC/HEIF 解碼橋接
Pm.Web/ Angular(core / features / shell 分區;ng build 輸出至 ../Pm.Api/wwwroot)
tests/ 與 src 一一對應的測試專案
docs/ design/(設計 spec)、deployment.md、mockups/
MIT © 2026 alexlin7
第三方相依套件授權見 THIRD-PARTY-NOTICES.md。
單一使用者的本機圖片管理系統(Windows 11),為十萬量級、以動漫圖為主的圖庫而設計。
核心理念:把「邏輯分類(tag)」跟「檔案系統」徹底脫鉤 —— 原圖就地索引、絕不搬動,以 tag 與布林查詢看圖,資料夾只是眾多 tag 軸之一。
完整設計與決策理由見
docs/design/2026-06-21-picture-management-design.md; 不可違反的鐵則與開發約定見AGENTS.md;部署/散布見docs/deployment.md。
file_hash(SHA-256)是圖片身分,file_path 只是位置。搬移、換碟、副本、去重都不影響 tag。/browse 並列,互不干擾。path / manual / wd14,自動標帶 confidence,不與手動策展混淆。Angular SPA
↓ REST(同源 localhost;ng serve 開發時走 proxy)
Pm.Api(啟動、DI、API endpoints、serve 前端靜態檔)
├─ Pm.Scanner 掃描、縮圖、EXIF、查詢、tag closure/facet、路徑→tag(service 層)
├─ Pm.Data EF Core、SQLite、九張 Entities、migrations
├─ Pm.Ml ONNX 推論後端抽象 IInferenceSessionFactory + WD14 pipeline
└─ Pm.Imaging AVIF/HEIC/HEIF 解碼橋接(Magick.NET/libheif → ImageSharp)
需求:.NET SDK 10.0.301、Node 24.x / npm。
# 1) 先 build 前端,輸出進 Pm.Api/wwwroot
cd src/Pm.Web ; npm ci ; npm run build
# 2) 起後端(同時 serve API 與前端於 http://localhost:5180)
cd ../.. ; dotnet run --project src/Pm.Api
瀏覽器開 http://localhost:5180。首次啟動自動建 pm.sqlite、套 migration。
dotnet run --project src/Pm.Api # 後端 :5180
cd src/Pm.Web ; npm start # ng serve :4200,/api 經 proxy 轉 :5180
# 註冊一個來源資料夾(Windows 路徑用正斜線免跳脫)
curl -X POST http://localhost:5180/api/roots -H "Content-Type: application/json" `
-d '{"name":"my-lib","absPath":"D:/pics"}'
# 觸發掃描(就地索引,絕不搬動原檔);POST 回 202,結果由 scan-status 輪詢
curl -X POST http://localhost:5180/api/roots/1/scan -H "Content-Type: application/json" -d '{}'
curl http://localhost:5180/api/roots/1/scan-status
之後在 UI 的「匯入確認」頁確認路徑→tag 規則。
把 Inference:Wd14:Enabled 設為 true(src/Pm.Api/appsettings.json 或環境變數),並視硬體設 Inference:Wd14:Backend(directml 預設 / cpu)。首次標註會自動下載 WD14 模型(~300MB)+ selected_tags.csv;關閉時零開銷、不下載。
# 例:以環境變數臨時開啟(走 CPU)
$env:Inference__Wd14__Enabled = "true"; $env:Inference__Wd14__Backend = "cpu"
dotnet run --project src/Pm.Api
dotnet test # 後端全測試
cd src/Pm.Web ; npm test # 前端(vitest + jsdom)
cd src/Pm.Web ; npm run e2e # 瀏覽器 e2e(@playwright/test;webServer 自動起 app)
cd src/Pm.Web ; npx ng build # 前端 → wwwroot
dotnet publish src/Pm.Api -p:PublishProfile=win-x64 # DirectML(預設)→ publish/(exe ~75MB + wwwroot)
# 另兩個推論 flavor(各為獨立 build,程式碼不動,僅換 profile):
dotnet publish src/Pm.Api -p:PublishProfile=win-x64-cuda # CUDA(NVIDIA,24H2 以下)
dotnet publish src/Pm.Api -p:PublishProfile=win-x64-windowsml # Windows ML(Win11 24H2+)
免裝 runtime、雙擊即跑。完整部署/設定/散布見 docs/deployment.md。
| 東西 | 位置 | 備註 |
|---|---|---|
| 資料庫(唯一真相) | pm.sqlite | 備份=複製此檔(可用 sqlite3 CLI VACUUM INTO 熱備);tag manifest 匯出為規劃中、app 尚未內建 |
| 縮圖快取 | thumbs/(依 hash 分桶) | 衍生資料,可重建;512px webp |
| WD14 模型 | models/wd14(opt-in 時下載) | 衍生資料,可重建 |
| 原始圖檔 | 你的來源資料夾 | 唯讀,絕不修改/搬移/改名,不寫 XMP |
預設程式與資料分離(資料落 %LOCALAPPDATA%,Windows 正規做法);攜帶版可用 Storage:BaseDir 讓資料貼著 exe。
Phase 1 核心可端對端運作:掃描就地索引 → SHA-256 身分 → 縮圖 → 布林查詢 → Angular 相簿,前端各畫面已接真實 API。
/browse(即時樹 + 麵包屑 + 下鑽 + 遞迴圖牆)/openapi/v1.json + Scalar 互動式文件 /scalar/v1InferenceFlavor 切套件,各有 publish profile + CI matrix。CPU / DirectML 已實機驗證;CUDA / Windows ML 已編譯與 publish 驗證,runtime 推論需對應硬體/OS(無 GPU 或非 24H2 環境無法在此驗)各子系統的設計與決策見 docs/design/。
src/
Pm.Api/ ASP.NET Core 宿主:DI、migration、API endpoints、serve wwwroot;TaggingWorker(背景服務)
Pm.Scanner/ 掃描 + 縮圖 + EXIF + 查詢 + tag closure/facet + 路徑→tag + TagService(service 層)
Pm.Data/ EF Core:Entities/(九實體)、PmDbContext、Migrations/
Pm.Ml/ 推論後端抽象 IInferenceSessionFactory(三 flavor:DirectML 預設 / CUDA / Windows ML,編譯期切;無 GPU 退 CPU)+ WD14 pipeline
Pm.Imaging/ AVIF/HEIC/HEIF 解碼橋接
Pm.Web/ Angular(core / features / shell 分區;ng build 輸出至 ../Pm.Api/wwwroot)
tests/ 與 src 一一對應的測試專案
docs/ design/(設計 spec)、deployment.md、mockups/
MIT © 2026 alexlin7
第三方相依套件授權見 THIRD-PARTY-NOTICES.md。