/kb/enterprise-upload + /kb/intake-workspace เป็น contract-only.
Runtime ต้องผ่าน tenant-admin + platform-governance dual sign-off · founder sign-off สำหรับ first pilot.
งานนี้มี 2 ส่วนที่รวมกันเป็น "Tenant": Enterprise Upload (SUB-3/SUB-4) = upload surface + 9-stage normalisation pipeline + conflict matrix + coverage score. Hybrid Intake Workspace = 8-panel workspace ผสม wizard + upload · shared state · multi-user · same approval gates. เหนือสองส่วนนี้คือ Tenant Registry ที่ provision per-tenant Nerve instance + data partitioning + cross-tenant marketplace listing.
coverage_scoring · progress dashboard per tenanttenant_scope.app_registry_handoff fields · schema for tenants tableSource: enterprise_intake root fields.
| B Field | B Type | A Runtime Target | A Owner | Approval Gate | Binding | Notes |
|---|---|---|---|---|---|---|
| source_origins[] | enum(13) | Upload form radio group + origin tag on each asset | Backend + FE | none | mapped-not-bound | 13: founder · canonical · concept · system · legacy-wiki · partner-doc · regulator · press · chatgpt · claude · gemini · perplexity · mixed |
| unit_modes[] | enum(4) | Upload widget mode selector | Frontend | none | mapped-not-bound | single-file · folder · link · ai-bundle |
| coverage_scoring.dimensions | array | Coverage dashboard · per-dimension meter | Backend + FE | none | mapped-not-bound | — |
| coverage_scoring.thresholds | object | Thresholds → pass/warn/fail colour | Backend | none | mapped-not-bound | Block tenant go-live until green |
| conflict_resolution | object | Conflict matrix UI · resolution form | Frontend | gate-conflict-resolution | mapped-not-bound | Each conflict needs sign-off · T1 source wins by default per authority rules |
| review_gates | array | Step gating in publish workflow | Backend | gate-review | mapped-not-bound | Each gate = reviewer role + SLA |
| tenant_ownership | object | Tenant DB schema + RLS policies | Backend + Infra | gate-tenant-instantiate | mapped-not-bound | Founder sign-off for first pilot tenant |
| shareability_and_resellability | object | Marketplace listing rules | Backend | gate-marketplace | mapped-not-bound | Payment + contract brokering explicitly OUT of scope per handoff deferred list |
Source: hybrid_intake_workspace.workspace_panels.
| Panel (B) | A Runtime Component | A Owner | Binding | Notes |
|---|---|---|---|---|
| panel-overview | Workspace home · KPI + status | Frontend | mapped-not-bound | Always visible · sidebar nav |
| panel-wizard | Embedded Wizard (shared w/ Wizard Runtime) | Frontend | mapped-not-bound | See Wizard Runtime page for details |
| panel-upload | Upload dropzone + progress | Frontend | mapped-not-bound | 4 unit_modes |
| panel-normalise | 9-stage pipeline viewer · stage-by-stage logs | Backend + FE | mapped-not-bound | Real-time SSE feed |
| panel-conflict | Conflict matrix · resolve form | Frontend | mapped-not-bound | — |
| panel-review-queue | Reviewer queue · assignment | Frontend | mapped-not-bound | Shared w/ Cases queue pattern |
| panel-coverage | Coverage dashboard | Frontend | mapped-not-bound | Per dimension meter |
| panel-handoff | Draft KB → live KB promote form | Backend + FE | mapped-not-bound | Gated: tenant go-live approval |
Shared state: state_model.persisted_fields → WebSocket + CRDT · state_merge_rules → conflict resolution per-field.
| B Field | A Runtime Target | A Owner | Binding | Notes |
|---|---|---|---|---|
| tenant_id | tenants.id PK | Backend | mapped-not-bound | Embedded in every JWT · used in RLS |
| tenant_roles | tenant_user_roles table | Backend | mapped-not-bound | Per-tenant role assignment |
| scope_transitions | State machine for tenant lifecycle | Backend | mapped-not-bound | draft → review → pilot → live · rollback allowed |
| feature_flag_handoff | Per-tenant flag override in flag registry | Backend | mapped-not-bound | Depends on Feature Flag Registry runtime |
approval_matrix.row-tenant-instantiate-nerve · tenant-admin + platform-governance dual + founder for first pilot