diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 486a460fe..056dcb90a 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,30 @@ +## 2026-06-24|Bitan Pharmacy dev baseline owner decision package + +**背景**:Blocked products pick list 將 Bitan 排在第七候選,且使用者回報 `[Bitan Pharmacy] Public content cleanliness check failed` 類告警。本輪只讀 `/Users/ogt/bitan-pharmacy`,先把 internal repo / public content evidence / dirty source 分桶;沒有 commit、branch、push、讀 `.env`、讀 `.npmrc` 或讀 secret value。 + +**只讀 readback**: +- local branch:`main`。 +- local HEAD:`e122c8cbd9522999fd9844c2b63790fadcc89c20`。 +- Gitea refs:internal inventory / owner export required。 +- tracked modified:`64`。 +- tracked deleted:`0`。 +- untracked:`252`。 +- diff shortstat:`64 files changed, 4069 insertions(+), 665 deletions(-)`。 +- untracked 分桶:`src_app=75`、`components=19`、`lib=17`、`scripts=104`、`supabase=27`、`docs=5`、`public=2`、`logs=1`、`root=2`。 +- `git diff --check`:failed,`scripts/verify-production-stack.sh` 與 `src/app/api/customer-support/chat/route.ts` 有 trailing whitespace。 +- env-like paths observed but not read:`.env.example`、`.env.local`。 +- default quarantine:`.npmrc`、`logs/public-content-cleanliness.latest.json`。 + +**文件**: +- `docs/operations/bitan-pharmacy-dev-baseline-owner-decision.snapshot.json` +- `docs/operations/BITAN-PHARMACY-DEV-BASELINE-OWNER-DECISION-2026-06-24.md` + +**判定**:Bitan 不能直接建立遠端 `dev`。此產品缺 authenticated Gitea inventory / owner export,且 worktree 混合 public content cleanliness evidence、production deploy / blue-green scripts、AI support、privacy、MCP、Supabase migrations、cron / verification scripts 與大量 admin / public pages。 + +**下一步**:先取得 owner export / internal refs;再建立 source-only include / exclude response,明確處理 `.npmrc`、public content cleanliness evidence 與 Supabase migration ownership。 + +**邊界**:沒有產品 repo 寫入、沒有 remote write、沒有 runtime write、沒有 secret collection、沒有讀 `.npmrc` 內容、沒有執行 public content check / deploy / DB migration;Mac Mini / MacBook Pro 仍不得把 Bitan 視為雙機可開發 ready。 + ## 2026-06-24|StockPlatform v2 dev baseline owner decision package **背景**:Blocked products pick list 將 StockPlatform v2 排在第六候選。本輪只讀 `/Users/ogt/stockplatform-v2`,目標是把 `3800` 個 untracked 先拆成 source candidates 與 generated outputs;沒有 commit、branch、push、讀 `.env` 或讀 secret value。 diff --git a/docs/operations/BITAN-PHARMACY-DEV-BASELINE-OWNER-DECISION-2026-06-24.md b/docs/operations/BITAN-PHARMACY-DEV-BASELINE-OWNER-DECISION-2026-06-24.md new file mode 100644 index 000000000..671482579 --- /dev/null +++ b/docs/operations/BITAN-PHARMACY-DEV-BASELINE-OWNER-DECISION-2026-06-24.md @@ -0,0 +1,91 @@ +# Bitan Pharmacy Dev Baseline Owner Decision + +- generated_at: `2026-06-24T14:05:45+08:00` +- product_id: `bitan-pharmacy` +- local_path: `/Users/ogt/bitan-pharmacy` +- status: `high risk, internal repo owner export required` + +## Readback + +| Gate | Result | +|------|--------| +| local branch | `main` | +| local head | `e122c8cbd9522999fd9844c2b63790fadcc89c20` | +| Gitea main | internal inventory required | +| Gitea dev | internal inventory required | +| tracked modified | `64` | +| tracked deleted | `0` | +| untracked | `252` | +| diff shortstat | `64 files changed, 4069 insertions(+), 665 deletions(-)` | +| diff check | failed: trailing whitespace in two files | + +## Untracked 分桶 + +| Bucket | Count | 判定 | +|--------|------:|------| +| `src/app` | `75` | source candidates | +| `src/components` | `19` | source candidates | +| `src/lib` | `17` | source candidates | +| `scripts` | `104` | source candidates, but production / cron / verification split required | +| `supabase/migrations` | `27` | migration candidates, requires DB owner review | +| `docs` | `5` | source docs candidates | +| `public` | `2` | asset candidates | +| `logs` | `1` | evidence/log, default quarantine | +| root | `2` | `.npmrc` requires quarantine / sanitization review | + +## Tracked Modified Groups + +- Docs:12-agent audit progress、tech stack、user flow、data recovery guide、deploy checklist。 +- i18n / runtime config:messages、middleware、Next config、package lock、manifest。 +- Ops scripts:production readiness、full fix、health check、production stack recovery、recovery drill、production verification。 +- Public / admin / API routes:login、products、prescription、admin, announcements, articles, pages, products, services, settings, translate, users, cron cleanup, customer support chat, product inquiry, settings, tracking。 +- Components / libraries / types:admin settings/users、customer support widget、product inquiry button、layout, auth, notifications, rate limiter, Supabase server, auth/product types。 +- Supabase:`002_storage_buckets.sql`。 + +## Untracked Source Candidates + +- AI / ops docs:MCP RAG integration、AI support governance / health check、AI operations automation、external MCP onboarding。 +- Scripts:blue-green deploy, safe deploy, release sync, install / run / verify cron and production health scripts, external MCP provider tooling, public content cleanliness checks。 +- Admin / public pages:AI information suggestions、knowledge sources、operations reports/tasks/workbench、support conversations, support FAQ, blue-green events, privacy, product inquiries, production health, public FAQ / information / news / policies / privacy。 +- API / cron routes:admin action approval, AI information suggestions, knowledge sources, operations, support, blue-green, privacy, product inquiries, production health, AI operations cron, customer support Telegram webhook, health, internal MCP, privacy request。 +- Libraries / migrations:AI provider / MCP / RAG / operations, API response, admin action approval, public content safety, privacy compliance / governance / rights request, Supabase migrations。 + +Quarantined by default: + +- `.npmrc` +- `logs/public-content-cleanliness.latest.json` + +Env-like paths observed but not read: + +- `.env.example` +- `.env.local` + +## 判定 + +Bitan 不能直接建立遠端 `dev`。這不是單純缺 branch,而是 internal repo inventory、public content cleanliness evidence、production deploy scripts、blue-green, Supabase migrations, AI support, privacy, MCP, cron 與 admin workflow 全部混在同一個 dirty tree。 + +`logs/public-content-cleanliness.latest.json` 可作為「告警 / evidence metadata」候選,但預設不可直接進 source baseline;`.npmrc` 也必須先 quarantine,確認沒有 credential material 或改以 sanitized replacement 進入。 + +## Owner Decision + +需要 owner 回覆: + +1. 提供 authenticated Gitea inventory 或 owner export,確認 Bitan 正確遠端 repo 與 refs。 +2. 64 個 tracked modified files 哪些要納入。 +3. 252 個 untracked candidates 哪些要納入。 +4. `.npmrc` 是否含 credential material;未確認前不可納入。 +5. `logs/public-content-cleanliness.latest.json` 是否只保留 evidence ref,或作為 sanitized evidence artifact。 +6. `.env.example` / `.env.local` 一律不讀內容、不收 secret value。 +7. public content cleanliness alert 要先 closeout 或明確標為 blocking production evidence。 +8. 是否先修 `scripts/verify-production-stack.sh` 與 `src/app/api/customer-support/chat/route.ts` trailing whitespace。 +9. owner 接受 include / exclude、evidence policy 與 internal inventory 後,才可建立 review branch 或遠端 `dev`。 + +## 安全邊界 + +- 未讀 `.env`。 +- 未讀 `.npmrc` 內容。 +- 未讀 secret value。 +- 未修改 Bitan repo。 +- 未建立 branch、commit 或 push。 +- 未同步 logs、runtime volumes、raw `.git` 或 raw Codex conversations。 +- 未執行 public content check、deploy、cron、DB migration、production smoke 或 runtime write。 diff --git a/docs/operations/bitan-pharmacy-dev-baseline-owner-decision.snapshot.json b/docs/operations/bitan-pharmacy-dev-baseline-owner-decision.snapshot.json new file mode 100644 index 000000000..e37801390 --- /dev/null +++ b/docs/operations/bitan-pharmacy-dev-baseline-owner-decision.snapshot.json @@ -0,0 +1,229 @@ +{ + "schema_version": "bitan_pharmacy_dev_baseline_owner_decision_v1", + "generated_at": "2026-06-24T14:05:45+08:00", + "product_id": "bitan-pharmacy", + "local_path": "/Users/ogt/bitan-pharmacy", + "gitea_repo": "internal:bitan-pharmacy", + "remote_refs": { + "main": "", + "dev": "", + "status": "internal_inventory_or_owner_export_required" + }, + "local_readback": { + "branch": "main", + "head": "e122c8cbd9522999fd9844c2b63790fadcc89c20", + "tracked_modified_count": 64, + "tracked_deleted_count": 0, + "untracked_count": 252, + "diff_shortstat": "64 files changed, 4069 insertions(+), 665 deletions(-)", + "diff_check": "failed_trailing_whitespace_in_two_files", + "status": "high_risk_internal_repo_owner_export_required" + }, + "untracked_classification": { + "src_app_count": 75, + "components_count": 19, + "lib_count": 17, + "scripts_count": 104, + "supabase_migration_count": 27, + "docs_count": 5, + "public_asset_count": 2, + "log_evidence_count": 1, + "root_count": 2 + }, + "tracked_modified_groups": { + "docs": [ + "docs/12-agent-full-audit-progress.md", + "docs/TechStack.md", + "docs/UserFlow.md", + "docs/data-recovery-guide.md", + "docs/ops/deploy-checklist.md" + ], + "i18n_and_runtime_config": [ + "messages/en.json", + "messages/zh-TW.json", + "middleware.ts", + "next.config.ts", + "package-lock.json", + "package.json", + "public/manifest.json" + ], + "ops_scripts": [ + "scripts/check-production-readiness.sh", + "scripts/fix-production-full.sh", + "scripts/health-check.sh", + "scripts/recover-production-stack.sh", + "scripts/recovery-drill.sh", + "scripts/verify-production-only.sh", + "scripts/verify-production-stack.sh" + ], + "public_pages_and_api": [ + "src/app/(auth)/login/page.tsx", + "src/app/[locale]/(auth)/login/page.tsx", + "src/app/[locale]/(public)/products/[id]/page.tsx", + "src/app/[locale]/(public)/products/page.tsx", + "src/app/[locale]/prescription/page.tsx", + "src/app/admin/layout.tsx", + "src/app/admin/page.tsx", + "src/app/api/admin/announcements/[id]/route.ts", + "src/app/api/admin/announcements/route.ts", + "src/app/api/admin/articles/[id]/route.ts", + "src/app/api/admin/articles/route.ts", + "src/app/api/admin/pages/[slug]/route.ts", + "src/app/api/admin/products/[id]/route.ts", + "src/app/api/admin/products/route.ts", + "src/app/api/admin/services/[slug]/route.ts", + "src/app/api/admin/services/route.ts", + "src/app/api/admin/settings/menu/route.ts", + "src/app/api/admin/translate/route.ts", + "src/app/api/admin/users/[id]/route.ts", + "src/app/api/announcements/route.ts", + "src/app/api/cron/cleanup/route.ts", + "src/app/api/customer-support/chat/route.ts", + "src/app/api/products/[id]/route.ts", + "src/app/api/products/inquiry/route.ts", + "src/app/api/products/route.ts", + "src/app/api/services/route.ts", + "src/app/api/settings/menu/route.ts", + "src/app/api/settings/pharmacy/route.ts", + "src/app/api/track/route.ts", + "src/app/layout.tsx", + "src/app/sitemap.ts" + ], + "components_libraries_and_types": [ + "src/components/admin/settings/menu-settings-manager.tsx", + "src/components/admin/users/users-manager.tsx", + "src/components/ai/customer-support-widget.tsx", + "src/components/business/product/InquiryButton.tsx", + "src/components/layout/footer.tsx", + "src/components/layout/header.tsx", + "src/lib/auth/config.ts", + "src/lib/auth/permissions.ts", + "src/lib/notifications/index.ts", + "src/lib/security/rate-limiter.ts", + "src/lib/supabase/server.ts", + "src/types/auth.ts", + "src/types/product.ts", + "supabase/migrations/002_storage_buckets.sql" + ] + }, + "untracked_source_candidate_groups": { + "ai_and_ops_docs": [ + "docs/ai/mcp-rag-integration-blueprint.md", + "docs/ops/ai-support-conversation-governance.md", + "docs/ops/ai-support-health-check.md", + "docs/runbooks/AI_OPERATIONS_AUTOMATION.md", + "docs/runbooks/external-mcp-onboarding.md" + ], + "scripts": [ + "scripts/deploy-production-safe.sh", + "scripts/deploy-production-release.sh", + "scripts/deploy-production-blue-green.sh", + "scripts/sync-production-release.sh", + "scripts/install-*.sh", + "scripts/run-*.sh", + "scripts/verify-*.sh", + "scripts/bitan-blue-green-monitor.js", + "scripts/bitan-blue-green-proxy.js", + "scripts/manage-external-mcp-env.sh", + "scripts/onboard-external-mcp-provider.sh", + "scripts/probe-external-mcp-endpoint.sh" + ], + "admin_and_public_pages": [ + "src/app/admin/ai-information-content-suggestions/page.tsx", + "src/app/admin/ai-knowledge-sources/page.tsx", + "src/app/admin/ai-operations-reports/page.tsx", + "src/app/admin/ai-operations-tasks/page.tsx", + "src/app/admin/ai-operations-workbench/page.tsx", + "src/app/admin/ai-support-conversations/page.tsx", + "src/app/admin/blue-green-events/page.tsx", + "src/app/admin/data-retention/page.tsx", + "src/app/admin/privacy-incidents/page.tsx", + "src/app/admin/privacy-processing-records/page.tsx", + "src/app/admin/privacy-requests/page.tsx", + "src/app/admin/product-inquiries/page.tsx", + "src/app/admin/production-health/page.tsx", + "src/app/[locale]/(public)/faq/page.tsx", + "src/app/[locale]/(public)/information/page.tsx", + "src/app/[locale]/(public)/news/page.tsx", + "src/app/[locale]/(public)/policies/page.tsx", + "src/app/[locale]/(public)/privacy/page.tsx" + ], + "api_and_cron_routes": [ + "src/app/api/admin/action-approval/route.ts", + "src/app/api/admin/ai-information-content-suggestions/route.ts", + "src/app/api/admin/ai-knowledge-sources/route.ts", + "src/app/api/admin/ai-operations-reports/route.ts", + "src/app/api/admin/ai-operations-tasks/route.ts", + "src/app/api/admin/ai-support-conversations/route.ts", + "src/app/api/admin/ai-support-faq-drafts/route.ts", + "src/app/api/admin/blue-green-events/route.ts", + "src/app/api/admin/data-retention/route.ts", + "src/app/api/admin/privacy-incidents/route.ts", + "src/app/api/admin/privacy-processing-records/route.ts", + "src/app/api/admin/privacy-requests/route.ts", + "src/app/api/admin/product-inquiries/route.ts", + "src/app/api/admin/production-health/route.ts", + "src/app/api/cron/ai-information-content-refresh/route.ts", + "src/app/api/cron/ai-low-risk-maintenance/route.ts", + "src/app/api/cron/ai-operations-daily-brief/route.ts", + "src/app/api/cron/ai-operations-reports-retention/route.ts", + "src/app/api/cron/ai-operations-tasks-refresh/route.ts", + "src/app/api/cron/ai-operations-weekly-report/route.ts", + "src/app/api/customer-support/telegram-webhook/route.ts", + "src/app/api/health/route.ts", + "src/app/api/internal-mcp/route.ts", + "src/app/api/privacy/requests/route.ts" + ], + "libraries_and_migrations": [ + "src/lib/ai/config.ts", + "src/lib/ai/customer-support/conversation-governance.ts", + "src/lib/ai/customer-support/knowledge.ts", + "src/lib/ai/customer-support/ops-summary.ts", + "src/lib/ai/governance/source-policy.ts", + "src/lib/ai/mcp/clients/http-mcp-client.ts", + "src/lib/ai/mcp/registry.ts", + "src/lib/ai/operations/report-task-sync.ts", + "src/lib/ai/provider/gemini.ts", + "src/lib/ai/rag/site-knowledge-provider.ts", + "src/lib/api/response.ts", + "src/lib/auth/admin-action-approval.ts", + "src/lib/content/public-content-safety.ts", + "src/lib/privacy/compliance.ts", + "src/lib/privacy/governance.ts", + "src/lib/privacy/rights-requests.ts", + "supabase/migrations/20260523_create_ai_support_conversation_audit.sql", + "supabase/migrations/20260524_add_ai_operations_reports_task_sync.sql", + "supabase/migrations/20260524_add_ai_support_conversation_governance.sql", + "supabase/migrations/20260524_add_privacy_compliance_consent_fields.sql" + ] + }, + "excluded_or_quarantined_by_default": [ + ".npmrc", + "logs/public-content-cleanliness.latest.json" + ], + "secret_or_env_paths_seen_but_not_read": [ + ".env.example", + ".env.local" + ], + "risk_assessment": { + "secret_value_collected": false, + "env_file_read": false, + "runtime_write_performed": false, + "product_repo_write_performed": false, + "remote_write_performed": false, + "risk_level": "high_internal_inventory_and_public_content_evidence_required", + "reason": "Bitan is an internal repo with no current Gitea refs readback in this package, 64 tracked changes, 252 untracked candidates, public-content cleanliness evidence, production scripts, Supabase migrations, AI support, privacy, MCP, blue-green, and cron surfaces." + }, + "owner_decision_required": [ + "Provide authenticated Gitea inventory or owner export before any remote dev branch action.", + "Approve or reject 64 tracked modified files by group.", + "Approve or reject 252 untracked candidates by source group.", + "Keep .npmrc quarantined until owner confirms it contains no credential material or provides a sanitized replacement.", + "Keep logs/public-content-cleanliness.latest.json as evidence metadata unless owner explicitly marks it as source-controlled evidence artifact.", + "Confirm .env.example and .env.local remain excluded from content reads and secret collection.", + "Resolve public content cleanliness alert evidence before declaring Bitan production source current.", + "Fix or explicitly defer trailing whitespace in scripts/verify-production-stack.sh and src/app/api/customer-support/chat/route.ts.", + "Approve remote dev branch only after internal inventory, source include / exclude, evidence policy, and public-content cleanliness decision are accepted." + ], + "recommended_next_step": "Request owner export / authenticated inventory and create a source-only include-exclude response before any Bitan Gitea dev branch or MacBook workspace bootstrap." +}