task-d.7.2
This commit is contained in:
402
docs/implementation/task-d7-initial-system-setup-audit.md
Normal file
402
docs/implementation/task-d7-initial-system-setup-audit.md
Normal file
@@ -0,0 +1,402 @@
|
||||
# Task D.7 Initial System Setup Wizard and Seed Framework - Phase 1/2 Audit
|
||||
|
||||
Date: 2026-07-02
|
||||
Status: Phase 1 and Phase 2 audit complete. Implementation intentionally not started.
|
||||
|
||||
## Scope
|
||||
|
||||
Task D.7 asks for a production initialization framework for a brand-new ALLA OS installation, including seed dependency analysis, CSV templates, a reusable CSV import engine, Setup Wizard, verification, reset/reseed support, and documentation.
|
||||
|
||||
The task contract explicitly says no implementation should begin until the current system audit and seed dependency report are complete. This document records that required first pass.
|
||||
|
||||
## Documents Reviewed
|
||||
|
||||
- `AGENTS.md`
|
||||
- `plans/task-d.7.md`
|
||||
- `docs/standards/task-contract-template.md`
|
||||
- `docs/standards/task-catalog.md`
|
||||
- `docs/standards/project-foundations.md`
|
||||
- `docs/standards/architecture-rules.md`
|
||||
- `docs/standards/ui-ux-rules.md`
|
||||
- `docs/standards/task-review-checklist.md`
|
||||
- `docs/adr/*.md`
|
||||
- `docs/business/*.md`
|
||||
- `docs/security/*.md`
|
||||
- existing implementation notes under `docs/implementation/**`
|
||||
|
||||
## Code Areas Reviewed
|
||||
|
||||
- `src/db/schema.ts`
|
||||
- `drizzle/*.sql`
|
||||
- `src/db/seeds/**`
|
||||
- `scripts/seed-system.ts`
|
||||
- `scripts/seed-uat.ts`
|
||||
- `scripts/seed-reset.ts`
|
||||
- `scripts/db/reset-database.ts`
|
||||
- `scripts/lib/seed-utils.ts`
|
||||
- `src/features/foundation/**`
|
||||
- `src/features/crm/**`
|
||||
- `src/features/setup/components/setup-wizard.tsx`
|
||||
- existing API routes under `src/app/api/**`
|
||||
- existing dashboard routes under `src/app/dashboard/**`
|
||||
- `src/config/nav-config.ts`
|
||||
|
||||
## Existing Seed and Reset Inventory
|
||||
|
||||
| Area | Existing file | Current behavior | Reuse decision |
|
||||
| --- | --- | --- | --- |
|
||||
| Super admin | `scripts/seed-super-admin.js` | Creates or updates the bootstrap admin from environment variables. | Reuse. Wizard should call or wrap this behavior server-side. |
|
||||
| System seed runner | `scripts/seed-system.ts` | Runs super admin, system organization, foundation seed, and PDF template reseed. | Reuse as foundation install orchestration baseline. |
|
||||
| System organization | `src/db/seeds/system-organization.seed.ts` | Creates deterministic `ALLA Demo` organization and super-admin membership. | Reuse logic, but D.7 needs user-provided organization inputs instead of hardcoded demo values. |
|
||||
| Foundation data | `src/db/seeds/foundation.seed.ts` | Idempotently seeds master options, document sequences, approval workflows/matrices, document templates, document libraries, notification templates, and report definitions per organization. | Reuse and split into callable services before wizard execution. |
|
||||
| UAT users | `src/db/seeds/uat-users.seed.ts` | Seeds marketing, sales, manager, CEO, and admin UAT users with CRM role assignments. | Reuse for Demo/UAT mode only. Do not mix with production foundation seed. |
|
||||
| CRM UAT data | `src/db/seeds/crm-uat.seed.ts` | Seeds customers, contacts, leads, opportunities, quotations, approval requests/actions, followups, project parties, and sequence bumps. | Reuse for Demo/UAT mode only. Needs transaction wrapper and import/report output. |
|
||||
| UAT runner | `scripts/seed-uat.ts` | Runs UAT users then CRM UAT data. | Reuse as demo seed orchestration baseline. |
|
||||
| Seed reset | `scripts/seed-reset.ts` | Guarded full database reset, migrate, system seed, UAT seed. | Extend rather than duplicate. D.7 needs narrower reset scopes. |
|
||||
| DB reset | `scripts/db/reset-database.ts` | Guarded schema drop/recreate, blocked in production and unsafe targets. | Keep guard contract. D.7 reset engine must preserve explicit confirmation and production blocking. |
|
||||
|
||||
## Existing Setup UI
|
||||
|
||||
`src/features/setup/components/setup-wizard.tsx` already exists, but it is a client-only template onboarding helper. It generates `.env.local` values and points users to example dashboards.
|
||||
|
||||
It does not currently provide:
|
||||
|
||||
- dashboard administration route
|
||||
- server readiness checks
|
||||
- seed execution API
|
||||
- CSV template generation
|
||||
- CSV upload, preview, validation, or rollback
|
||||
- organization/branch/product type initialization
|
||||
- document sequence setup
|
||||
- administrator creation through app-owned services
|
||||
- verification report
|
||||
- setup resume state
|
||||
|
||||
Reuse decision: treat it as historical UI prototype only. D.7 should build a dashboard-native Administration Setup Wizard using `PageContainer`, shadcn/ui primitives, server route handlers, and setup feature services.
|
||||
|
||||
## Seed Classification
|
||||
|
||||
### Required Foundation Seed
|
||||
|
||||
These are required for a production install to operate:
|
||||
|
||||
- users and initial super admin
|
||||
- organizations
|
||||
- memberships
|
||||
- CRM role profiles
|
||||
- CRM user role assignments for the first administrator
|
||||
- master options in `ms_options`
|
||||
- branch options in `ms_options` category `crm_branch`
|
||||
- product type options in `ms_options` category `crm_product_type`
|
||||
- currencies, units, statuses, priorities, lead channels, lost reasons, job titles, project party roles
|
||||
- document sequences for customer, lead, opportunity, quotation, and approval-related numbering
|
||||
- approval workflows
|
||||
- approval steps
|
||||
- approval matrices
|
||||
- document templates and template versions
|
||||
- document template mappings and table columns
|
||||
- document libraries and library versions
|
||||
- notification templates
|
||||
- report definitions
|
||||
|
||||
### Optional Configuration Seed
|
||||
|
||||
These may be required by deployment policy but are not always required before first login:
|
||||
|
||||
- Sentry configuration
|
||||
- email provider configuration
|
||||
- storage provider configuration beyond local defaults
|
||||
- PDF visual assets or organization-specific logos
|
||||
- additional document libraries
|
||||
- additional branch/team/warehouse abstractions once modeled as first-class domains
|
||||
- price books, tax rates, and product/service catalogs, because current schema has only the generic `products` table and CRM quotation items use free-form item data plus master options
|
||||
|
||||
### Demo / UAT Seed
|
||||
|
||||
These are already represented by `uat-users.seed.ts` and `crm-uat.seed.ts`:
|
||||
|
||||
- Marketing user
|
||||
- Sales users by product type
|
||||
- Sales manager
|
||||
- CEO/top manager
|
||||
- CRM admin
|
||||
- customers
|
||||
- contacts
|
||||
- leads
|
||||
- opportunities
|
||||
- quotations across approved, rejected, pending, returned, sent, cancelled, won/lost/no-quotation scenarios
|
||||
- followups
|
||||
- approval requests and actions
|
||||
- quotation items, project parties, topics
|
||||
|
||||
### Generated Runtime Data
|
||||
|
||||
These should not be manually seeded except through controlled fixture generation:
|
||||
|
||||
- audit logs, except explicit UAT followup/audit fixture rows
|
||||
- notification events, dispatches, deliveries
|
||||
- approval requests and approval actions in production
|
||||
- document artifacts for generated approved PDFs
|
||||
- quotation approved snapshots
|
||||
- sequence current numbers, except after deterministic demo data creation
|
||||
|
||||
### Runtime Only
|
||||
|
||||
These are produced by application behavior and should not be foundation seed inputs:
|
||||
|
||||
- active user sessions
|
||||
- notification deliveries
|
||||
- audit security-denial events
|
||||
- generated PDFs and immutable approved artifacts
|
||||
- uploaded binary attachment storage objects
|
||||
- report export output files
|
||||
|
||||
## Dependency Graph
|
||||
|
||||
```text
|
||||
Environment
|
||||
-> Database migration status
|
||||
-> Storage/PDF/email configuration checks
|
||||
-> Super admin user
|
||||
-> Organization
|
||||
-> Membership
|
||||
-> CRM role profiles
|
||||
-> CRM user role assignments
|
||||
-> Master options
|
||||
-> Branch scope options
|
||||
-> Product type options
|
||||
-> Currency/unit/status/priority/job title/project party options
|
||||
-> Document sequences
|
||||
-> Customer codes
|
||||
-> Lead codes
|
||||
-> Opportunity codes
|
||||
-> Quotation codes
|
||||
-> Approval workflows
|
||||
-> Approval steps
|
||||
-> Approval matrices
|
||||
-> Document templates
|
||||
-> Template versions
|
||||
-> Template mappings
|
||||
-> Table-column mappings
|
||||
-> Document libraries
|
||||
-> Library versions
|
||||
-> Storage provider objects
|
||||
-> Notification templates
|
||||
-> Report definitions
|
||||
|
||||
Demo/UAT:
|
||||
Organization foundation
|
||||
-> UAT users
|
||||
-> UAT memberships
|
||||
-> UAT CRM role assignments
|
||||
-> Customers
|
||||
-> Customer owner history
|
||||
-> Contacts
|
||||
-> Contact sharing, optional
|
||||
-> Leads
|
||||
-> Lead followup audit rows
|
||||
-> Opportunities
|
||||
-> Opportunity project parties
|
||||
-> Opportunity followups
|
||||
-> Quotations
|
||||
-> Quotation items
|
||||
-> Quotation project parties
|
||||
-> Quotation topics
|
||||
-> Quotation topic items
|
||||
-> Quotation followups
|
||||
-> Approval requests
|
||||
-> Approval actions
|
||||
-> Document sequence bumps
|
||||
```
|
||||
|
||||
## Recommended Seed Order
|
||||
|
||||
1. Validate environment: `AUTH_SECRET`, `DATABASE_URL`, storage, upload directory, PDF template assets, email settings.
|
||||
2. Validate migrations are applied.
|
||||
3. Create first system administrator.
|
||||
4. Create organization from wizard input.
|
||||
5. Create administrator membership in the organization.
|
||||
6. Seed CRM role profiles for the organization.
|
||||
7. Assign CRM administrator role assignment to first administrator.
|
||||
8. Seed master options, including branch and product type options.
|
||||
9. Seed document sequences using organization, branch, product type, document type, and period scope.
|
||||
10. Seed approval workflows and steps.
|
||||
11. Seed approval matrices.
|
||||
12. Seed document templates, versions, mappings, and table columns.
|
||||
13. Seed document libraries through the storage provider.
|
||||
14. Seed notification templates.
|
||||
15. Seed report definitions.
|
||||
16. Optionally import CSV master/business data.
|
||||
17. Optionally run Demo/UAT seed.
|
||||
18. Run verification checks and persist setup summary/report.
|
||||
|
||||
## Circular Dependency Check
|
||||
|
||||
No hard circular dependency was found in the existing seed flow.
|
||||
|
||||
Important dependency edges:
|
||||
|
||||
- Foundation seed requires at least one organization and `created_by` user.
|
||||
- Document sequence seed requires branch/product type options from master options.
|
||||
- UAT user role assignments require role profiles and branch/product type options.
|
||||
- CRM UAT data requires UAT users, master options, branches, approval workflow, customers, contacts, leads, opportunities, and quotations in order.
|
||||
- Approval actions require approval requests.
|
||||
- Document library seed writes storage objects and therefore depends on storage provider readiness.
|
||||
|
||||
Potential soft cycle to avoid:
|
||||
|
||||
- First administrator creation needs permissions/role assignment, but role profiles are organization-scoped and need an organization. Resolve by creating user, organization, membership, then role profiles, then role assignment.
|
||||
|
||||
## Existing Coverage Matrix
|
||||
|
||||
| Requirement from Task D.7 | Current coverage | Gap |
|
||||
| --- | --- | --- |
|
||||
| Foundation seed | Strong script coverage in `foundation.seed.ts`. | Not exposed as service/API/wizard step. |
|
||||
| Roles and permissions | `src/lib/auth/rbac.ts`, role profiles, assignments. | Wizard needs first-admin role assignment flow. |
|
||||
| Master options | Strong coverage through `ms_options`. | CSV template/import for governed options missing. |
|
||||
| Branch scope | Implemented as `ms_options` category `crm_branch`. | Wizard asks branch/department/team/warehouse, but only branch is modeled. Department/team/warehouse need scope decision. |
|
||||
| Product type scope | Implemented as `ms_options` category `crm_product_type`. | Wizard needs product-type-aware sequence setup UI. |
|
||||
| Document sequence | Strong foundation and APIs exist. | Wizard orchestration and verification missing. |
|
||||
| Approval workflow | Strong foundation and settings APIs exist. | Wizard initialization/verification missing. |
|
||||
| Storage | Foundation exists. | Readiness check and seed report integration missing. |
|
||||
| PDF configuration | Foundation and audit docs exist. | Setup verification should call template inventory/mapping checks. |
|
||||
| Report foundation | Existing definitions and services. | Setup should verify report definitions seeded. |
|
||||
| Demo/UAT seed | Strong script coverage. | Needs deterministic report, transaction boundary, and wizard separation from production seed. |
|
||||
| CSV templates | Not present. | Need `/setup/templates/*.csv` generator or checked-in templates. |
|
||||
| Generic CSV import engine | Not present. | Need reusable setup/import foundation. |
|
||||
| Setup Wizard route | Prototype component only. | Need dashboard admin page, route handlers, state persistence. |
|
||||
| Verification engine | Not present as setup feature. | Need checks for login, permissions, org, branch, sequences, approval, storage, PDF, email. |
|
||||
| Reset/reseed engine | Full reset exists. | Need scoped reset: foundation, organization, demo, business data. |
|
||||
|
||||
## Missing or Ambiguous Seed Data
|
||||
|
||||
- `branches.csv` can map to `ms_options` today, not a first-class branch table.
|
||||
- `departments.csv`, `teams.csv`, and `warehouses.csv` have no obvious first-class schema in the reviewed model.
|
||||
- `roles.csv` and `permissions.csv` should map to CRM role profiles and static permission definitions; permissions are code-defined in `src/lib/auth/rbac.ts`, not a database table.
|
||||
- `products.csv`, `services.csv`, `price-books.csv`, `tax-rates.csv`, and `sites.csv` are not fully represented as CRM-owned first-class schemas. Current quotation item/product behavior does not equal a production price book.
|
||||
- Attachments have metadata tables, but upload/storage transport is not a generic CSV-importable business seed.
|
||||
- Email configuration appears environment/provider-driven; no dedicated setup table was identified.
|
||||
- There is no setup state table for resume setup or setup summary persistence.
|
||||
|
||||
## Recommended Architecture for Next Phase
|
||||
|
||||
Create a setup feature that wraps existing foundations instead of duplicating them:
|
||||
|
||||
```text
|
||||
src/features/setup/
|
||||
api/
|
||||
types.ts
|
||||
service.ts
|
||||
queries.ts
|
||||
mutations.ts
|
||||
server/
|
||||
readiness.service.ts
|
||||
seed.service.ts
|
||||
csv-template.service.ts
|
||||
csv-import.service.ts
|
||||
verification.service.ts
|
||||
reset.service.ts
|
||||
components/
|
||||
setup-wizard.tsx
|
||||
import-preview-table.tsx
|
||||
verification-summary.tsx
|
||||
```
|
||||
|
||||
Route handlers should live under:
|
||||
|
||||
```text
|
||||
src/app/api/setup/readiness/route.ts
|
||||
src/app/api/setup/foundation/route.ts
|
||||
src/app/api/setup/templates/route.ts
|
||||
src/app/api/setup/import/preview/route.ts
|
||||
src/app/api/setup/import/commit/route.ts
|
||||
src/app/api/setup/verify/route.ts
|
||||
src/app/api/setup/reset/route.ts
|
||||
```
|
||||
|
||||
Dashboard page:
|
||||
|
||||
```text
|
||||
src/app/dashboard/administration/setup/page.tsx
|
||||
```
|
||||
|
||||
Key rules for implementation:
|
||||
|
||||
- service layer owns business logic
|
||||
- route handlers remain thin
|
||||
- seed execution must be transaction-aware where database writes happen
|
||||
- storage writes need compensation/reporting because they cannot participate in the DB transaction
|
||||
- CSV import must preview and validate before commit
|
||||
- reset operations must preserve the existing explicit confirmation and production-safety guard
|
||||
- CRM authorization must use existing resolved access helpers, not raw role branching
|
||||
- audit setup mutations using the audit foundation once setup APIs exist
|
||||
|
||||
## CSV Template Scope Recommendation
|
||||
|
||||
Start with templates that map to existing schema and foundations:
|
||||
|
||||
- `organizations.csv`
|
||||
- `users.csv`
|
||||
- `memberships.csv`
|
||||
- `crm-role-assignments.csv`
|
||||
- `master-options.csv`
|
||||
- `branches.csv` as a typed `master-options` template for `crm_branch`
|
||||
- `product-types.csv` as a typed `master-options` template for `crm_product_type`
|
||||
- `document-sequences.csv`
|
||||
- `approval-workflows.csv`
|
||||
- `approval-steps.csv`
|
||||
- `approval-matrix.csv`
|
||||
- `customers.csv`
|
||||
- `contacts.csv`
|
||||
- `contact-shares.csv`
|
||||
- `leads.csv`
|
||||
- `opportunities.csv`
|
||||
- `opportunity-parties.csv`
|
||||
- `quotations.csv`
|
||||
- `quotation-items.csv`
|
||||
- `quotation-parties.csv`
|
||||
- `quotation-topics.csv`
|
||||
- `quotation-topic-items.csv`
|
||||
|
||||
Defer or mark as unsupported until schema is clarified:
|
||||
|
||||
- `departments.csv`
|
||||
- `teams.csv`
|
||||
- `warehouses.csv`
|
||||
- `sites.csv`
|
||||
- `services.csv`
|
||||
- `price-books.csv`
|
||||
- `tax-rates.csv`
|
||||
|
||||
## Verification Checks Needed
|
||||
|
||||
- environment variable presence and secrecy checks
|
||||
- database connectivity
|
||||
- migration table/status check
|
||||
- storage provider write/read/delete smoke test
|
||||
- upload directory readiness for local provider
|
||||
- PDF template inventory and mapping coverage
|
||||
- email provider configuration and optional dry-run
|
||||
- first admin login readiness
|
||||
- active organization on first admin
|
||||
- membership and CRM role assignment resolution
|
||||
- branch and product type scope resolution
|
||||
- document sequence preview for customer, lead, opportunity, quotation
|
||||
- approval workflow and matrix resolution for quotation
|
||||
- report definition availability
|
||||
- notification template availability
|
||||
|
||||
## Implementation Boundary
|
||||
|
||||
No code implementation was started in this pass because Task D.7 requires the audit and dependency report first. The safest next implementation slice is:
|
||||
|
||||
1. Extract current seed script logic into setup-callable server services without changing behavior.
|
||||
2. Add setup readiness and verification read-only APIs.
|
||||
3. Add checked-in CSV templates for entities already represented in schema.
|
||||
4. Build CSV preview validation before commit support.
|
||||
5. Replace the existing prototype setup wizard with a dashboard-native wizard that calls the setup APIs.
|
||||
|
||||
## Notes
|
||||
|
||||
- `rtk` was requested by repository instructions, but it was not available in this shell session. Raw PowerShell commands were used for the audit.
|
||||
- Existing seed scripts include Thai strings that appeared mojibake in terminal output. This audit did not modify those files.
|
||||
@@ -0,0 +1,51 @@
|
||||
# Task D.7.2 Setup Readiness and Verification APIs
|
||||
|
||||
Date: 2026-07-02
|
||||
Status: implemented
|
||||
|
||||
## Scope Delivered
|
||||
|
||||
- Added setup API contracts:
|
||||
- `src/features/setup/api/types.ts`
|
||||
- `src/features/setup/api/service.ts`
|
||||
- `src/features/setup/api/queries.ts`
|
||||
- Added read-only setup server services:
|
||||
- `src/features/setup/server/readiness.service.ts`
|
||||
- `src/features/setup/server/verification.service.ts`
|
||||
- Added thin protected route handlers:
|
||||
- `src/app/api/setup/readiness/route.ts`
|
||||
- `src/app/api/setup/verify/route.ts`
|
||||
|
||||
## Behavior
|
||||
|
||||
- `GET /api/setup/readiness`
|
||||
- protected by `requireSystemRole('super_admin')`
|
||||
- returns structured setup readiness checks
|
||||
- checks environment, database, migrations/schema queryability, storage smoke test, local upload directory, PDF template/mapping readiness, and optional email configuration
|
||||
|
||||
- `POST /api/setup/verify`
|
||||
- protected by `requireSystemRole('super_admin')`
|
||||
- accepts optional `organizationId` and `administratorEmail`
|
||||
- falls back to the current session active organization when `organizationId` is not provided
|
||||
- returns structured verification checks for administrator, membership, CRM assignment, organization, branch/product type options, document sequences, approval workflow/matrix, PDF, notification templates, report definitions, email config, and planned CSV/manifest checks
|
||||
|
||||
## Safety Notes
|
||||
|
||||
- No seed execution was added.
|
||||
- No CSV import was added.
|
||||
- No reset/reseed behavior was added.
|
||||
- No setup state tables or migrations were added.
|
||||
- The only intentional write-like behavior is the readiness storage smoke test, which writes a temporary setup object and immediately deletes it. Cleanup failures are reported as warnings.
|
||||
- Document sequence checks are read-only and do not call `generateNextDocumentCode()`.
|
||||
- Report verification checks query report definition rows directly and do not call report services that audit report views.
|
||||
|
||||
## Verification
|
||||
|
||||
- `npm run typecheck`: passed.
|
||||
- `npx oxlint src/features/setup src/app/api/setup`: passed.
|
||||
- `npm run lint`: failed due to pre-existing unrelated lint errors/warnings outside this task, including `src/features/foundation/document-template/server/management-service.ts` and skill asset scripts.
|
||||
|
||||
## Follow-up
|
||||
|
||||
- D.7.3 can add static CSV template pack.
|
||||
- D.7.8 should replace planned CSV preview/seed manifest warnings with persisted setup state checks.
|
||||
557
docs/setup/csv-template-spec.md
Normal file
557
docs/setup/csv-template-spec.md
Normal file
@@ -0,0 +1,557 @@
|
||||
# CSV Template Specification
|
||||
|
||||
Source task: `plans/task-d.7.1.md`
|
||||
|
||||
All supported CSV imports must run in two phases:
|
||||
|
||||
1. Preview: parse, validate, resolve references, detect duplicates, and produce an import report.
|
||||
2. Commit: upsert in a transaction where database-only writes are involved.
|
||||
|
||||
CSV imports must not bypass feature/foundation services once those services exist. Where current seed logic only exists in scripts, D.7.2+ should extract reusable server services first.
|
||||
|
||||
## Supported Templates
|
||||
|
||||
### `organizations.csv`
|
||||
|
||||
Purpose: create tenant organizations.
|
||||
Target: `organizations`.
|
||||
Seed type: `organization`.
|
||||
Required columns: `organization_code`, `organization_name`, `slug`, `created_by_email`.
|
||||
Optional columns: `tax_id`, `default_currency`, `phone`, `email`, `address`, `logo_url`, `plan`, `status`.
|
||||
Generated columns: `id`, `created_at`, `updated_at`.
|
||||
Validation rules: `slug` lowercase and unique; `organization_code` uppercase; `created_by_email` must resolve to a user.
|
||||
Relationship resolution: `created_by_email -> users.id`.
|
||||
Duplicate detection: existing organization by `slug`.
|
||||
Upsert key: `slug`.
|
||||
Import order: `02`.
|
||||
|
||||
```csv
|
||||
organization_code,organization_name,slug,created_by_email,tax_id,default_currency,status
|
||||
ALLA,ALLA Public Company Limited,alla,admin@example.com,0107558000393,THB,active
|
||||
```
|
||||
|
||||
Error examples: duplicate slug with conflicting name; missing creator user; invalid lowercase/uppercase format.
|
||||
|
||||
### `users.csv`
|
||||
|
||||
Purpose: create setup-managed users.
|
||||
Target: `users` through auth/user service.
|
||||
Seed type: `organization`.
|
||||
Required columns: `email`, `name`, `system_role`.
|
||||
Optional columns: `password`, `active_organization_code`, `image_url`, `reset_password`.
|
||||
Generated columns: `id`, `password_hash`, `created_at`, `updated_at`.
|
||||
Validation rules: email format; `system_role` in `super_admin,user`; password required for new credential users unless invitation flow exists.
|
||||
Relationship resolution: `active_organization_code -> organizations.slug or setup organization_code`.
|
||||
Duplicate detection: existing user by email.
|
||||
Upsert key: `email`.
|
||||
Import order: `01`.
|
||||
|
||||
```csv
|
||||
email,name,system_role,password,active_organization_code,reset_password
|
||||
admin@example.com,System Administrator,super_admin,ChangeMe123!,ALLA,true
|
||||
```
|
||||
|
||||
Error examples: invalid email; unsupported system role; existing user without reset permission.
|
||||
|
||||
### `memberships.csv`
|
||||
|
||||
Purpose: grant app-level organization access.
|
||||
Target: `memberships`.
|
||||
Seed type: `organization`.
|
||||
Required columns: `organization_code`, `user_email`, `membership_role`, `business_role`.
|
||||
Optional columns: `permissions`, `branch_scope_codes`, `product_type_scope_codes`.
|
||||
Generated columns: `id`, timestamps.
|
||||
Validation rules: `membership_role` in `admin,user`; `business_role` should be a known CRM role fallback code; scope codes must resolve when provided.
|
||||
Relationship resolution: organization, user, branch options, product type options.
|
||||
Duplicate detection: existing membership by `organization_id + user_id`.
|
||||
Upsert key: `organization_code + user_email`.
|
||||
Import order: `03`.
|
||||
|
||||
```csv
|
||||
organization_code,user_email,membership_role,business_role,permissions,branch_scope_codes,product_type_scope_codes
|
||||
ALLA,admin@example.com,admin,crm_admin,crm.dashboard.read|crm.role.read,head_office,crane|dockdoor
|
||||
```
|
||||
|
||||
Error examples: unknown user; unknown organization; invalid branch/product type code.
|
||||
|
||||
### `crm-role-assignments.csv`
|
||||
|
||||
Purpose: assign CRM role profiles and CRM scopes.
|
||||
Target: `crm_user_role_assignments`.
|
||||
Seed type: `organization`.
|
||||
Required columns: `organization_code`, `user_email`, `crm_role_code`, `is_primary`, `branch_scope_mode`, `product_type_scope_mode`.
|
||||
Optional columns: `branch_codes`, `product_type_codes`, `is_active`.
|
||||
Generated columns: `id`, `assigned_at`, timestamps.
|
||||
Validation rules: role profile must exist; scope mode in `all,selected,none,inherit`; selected modes require matching codes.
|
||||
Relationship resolution: user, organization, role profile, branch options, product type options.
|
||||
Duplicate detection: existing assignment by `organization_id + user_id + role_profile_id`.
|
||||
Upsert key: `organization_code + user_email + crm_role_code`.
|
||||
Import order: `05`.
|
||||
|
||||
```csv
|
||||
organization_code,user_email,crm_role_code,is_primary,branch_scope_mode,branch_codes,product_type_scope_mode,product_type_codes,is_active
|
||||
ALLA,admin@example.com,crm_admin,true,all,,all,,true
|
||||
```
|
||||
|
||||
Error examples: selected scope without codes; role profile missing; multiple primary rows for one user unless explicit replacement mode.
|
||||
|
||||
### `master-options.csv`
|
||||
|
||||
Purpose: import governed option rows.
|
||||
Target: `ms_options`.
|
||||
Seed type: `foundation`.
|
||||
Required columns: `organization_code`, `category`, `code`, `label`.
|
||||
Optional columns: `value`, `parent_category`, `parent_code`, `sort_order`, `is_active`, `metadata_json`.
|
||||
Generated columns: `id`, timestamps.
|
||||
Validation rules: category/code non-empty; parent resolves in same organization when provided; metadata must be valid JSON.
|
||||
Relationship resolution: organization, optional parent option.
|
||||
Duplicate detection: existing option by `organization_id + category + code`.
|
||||
Upsert key: `organization_code + category + code`.
|
||||
Import order: `06`.
|
||||
|
||||
```csv
|
||||
organization_code,category,code,label,value,parent_category,parent_code,sort_order,is_active,metadata_json
|
||||
ALLA,crm_customer_group,industrial,Industrial,industrial,,,1,true,{}
|
||||
```
|
||||
|
||||
Error examples: invalid JSON; missing parent option; duplicate category/code in same CSV with conflicting labels.
|
||||
|
||||
### `branches.csv`
|
||||
|
||||
Purpose: typed convenience template for branch options.
|
||||
Target: `ms_options` with `category=crm_branch`.
|
||||
Seed type: `organization`.
|
||||
Required columns: `organization_code`, `branch_code`, `branch_name`.
|
||||
Optional columns: `prefix`, `address`, `tax_id`, `phone`, `email`, `sort_order`, `is_active`.
|
||||
Generated columns: `id`, `category`, timestamps.
|
||||
Validation rules: branch code unique per organization; code lowercase snake_case recommended; metadata fields serialized into option metadata.
|
||||
Relationship resolution: organization.
|
||||
Duplicate detection: existing `crm_branch` option by code.
|
||||
Upsert key: `organization_code + branch_code`.
|
||||
Import order: `07`.
|
||||
|
||||
```csv
|
||||
organization_code,branch_code,branch_name,prefix,address,tax_id,sort_order,is_active
|
||||
ALLA,head_office,Head Office,HO,99/9 Rama IX Road,0107558000393,1,true
|
||||
```
|
||||
|
||||
Error examples: duplicate branch code; invalid organization; malformed metadata.
|
||||
|
||||
### `product-types.csv`
|
||||
|
||||
Purpose: typed convenience template for product type options.
|
||||
Target: `ms_options` with `category=crm_product_type`.
|
||||
Seed type: `organization`.
|
||||
Required columns: `organization_code`, `product_type_code`, `product_type_name`.
|
||||
Optional columns: `document_prefix`, `sort_order`, `is_active`, `metadata_json`.
|
||||
Generated columns: `id`, `category`, timestamps.
|
||||
Validation rules: product type code unique per organization; `document_prefix` uppercase recommended.
|
||||
Relationship resolution: organization.
|
||||
Duplicate detection: existing `crm_product_type` option by code.
|
||||
Upsert key: `organization_code + product_type_code`.
|
||||
Import order: `08`.
|
||||
|
||||
```csv
|
||||
organization_code,product_type_code,product_type_name,document_prefix,sort_order,is_active
|
||||
ALLA,crane,Crane,CR,1,true
|
||||
```
|
||||
|
||||
Error examples: duplicate product type code; invalid JSON metadata; unsupported inactive default product type for document sequence.
|
||||
|
||||
### `document-sequences.csv`
|
||||
|
||||
Purpose: configure document numbering.
|
||||
Target: `document_sequences`.
|
||||
Seed type: `foundation`.
|
||||
Required columns: `organization_code`, `document_type`, `prefix`, `period`.
|
||||
Optional columns: `branch_code`, `product_type_code`, `current_number`, `padding_length`, `format`, `reset_policy`, `is_active`.
|
||||
Generated columns: `id`, timestamps.
|
||||
Validation rules: document type supported by sequence foundation; branch/product type resolve or default to generic scope; current number non-negative integer.
|
||||
Relationship resolution: organization, branch option, product type option.
|
||||
Duplicate detection: `organization_id + branch_id + product_type + document_type + period`.
|
||||
Upsert key: same as duplicate detection.
|
||||
Import order: `14`.
|
||||
|
||||
```csv
|
||||
organization_code,branch_code,product_type_code,document_type,prefix,period,current_number,padding_length,format,reset_policy,is_active
|
||||
ALLA,head_office,crane,quotation,QT-HO-CR-,2607,0,3,{prefix}{period}-{running},period,true
|
||||
```
|
||||
|
||||
Error examples: unknown branch; unknown product type; malformed format missing `{running}`.
|
||||
|
||||
### `approval-workflows.csv`
|
||||
|
||||
Purpose: configure approval workflow headers.
|
||||
Target: `crm_approval_workflows`.
|
||||
Seed type: `foundation`.
|
||||
Required columns: `organization_code`, `workflow_code`, `workflow_name`, `entity_type`.
|
||||
Optional columns: `description`, `is_system`, `is_active`.
|
||||
Generated columns: `id`, timestamps.
|
||||
Validation rules: workflow code unique per organization; entity type supported, currently `quotation`.
|
||||
Relationship resolution: organization.
|
||||
Duplicate detection: `organization_id + workflow_code`.
|
||||
Upsert key: `organization_code + workflow_code`.
|
||||
Import order: `15`.
|
||||
|
||||
```csv
|
||||
organization_code,workflow_code,workflow_name,entity_type,description,is_system,is_active
|
||||
ALLA,quotation_standard,Quotation Standard Approval,quotation,Default quotation approval,false,true
|
||||
```
|
||||
|
||||
Error examples: duplicate workflow code; unsupported entity type.
|
||||
|
||||
### `approval-steps.csv`
|
||||
|
||||
Purpose: configure workflow steps.
|
||||
Target: `crm_approval_steps`.
|
||||
Seed type: `foundation`.
|
||||
Required columns: `organization_code`, `workflow_code`, `step_number`, `role_code`, `role_name`.
|
||||
Optional columns: `approval_mode`, `is_required`, `sla_hours`, `calendar_mode`, `timeout_action`.
|
||||
Generated columns: `id`, timestamps.
|
||||
Validation rules: workflow resolves; step number positive integer; role code known to CRM role profiles or approved workflow roles.
|
||||
Relationship resolution: organization, approval workflow.
|
||||
Duplicate detection: `workflow_id + step_number`.
|
||||
Upsert key: `organization_code + workflow_code + step_number`.
|
||||
Import order: `16`.
|
||||
|
||||
```csv
|
||||
organization_code,workflow_code,step_number,role_code,role_name,approval_mode,is_required,sla_hours,calendar_mode,timeout_action
|
||||
ALLA,quotation_standard,1,sales_manager,Sales Manager,sequential,true,24,calendar_days,none
|
||||
```
|
||||
|
||||
Error examples: missing workflow; duplicate step number; invalid SLA value.
|
||||
|
||||
### `approval-matrix.csv`
|
||||
|
||||
Purpose: map approval workflows to entity/scope/amount.
|
||||
Target: `crm_approval_matrices`.
|
||||
Seed type: `foundation`.
|
||||
Required columns: `organization_code`, `entity_type`, `workflow_code`, `priority`, `is_default`.
|
||||
Optional columns: `branch_code`, `product_type_code`, `min_amount`, `max_amount`, `currency`, `is_active`, `description`.
|
||||
Generated columns: `id`, timestamps.
|
||||
Validation rules: workflow resolves; branch/product optional; amount range valid; at most one default per target policy unless replacement mode.
|
||||
Relationship resolution: organization, workflow, branch option, product type option.
|
||||
Duplicate detection: default matrix by `organization + entity_type + is_default` or scoped matrix by full scope/amount tuple.
|
||||
Upsert key: `organization_code + entity_type + workflow_code + priority + scope`.
|
||||
Import order: `17`.
|
||||
|
||||
```csv
|
||||
organization_code,entity_type,workflow_code,branch_code,product_type_code,min_amount,max_amount,currency,priority,is_default,is_active,description
|
||||
ALLA,quotation,quotation_standard,head_office,crane,0,5000000,THB,100,true,true,Default crane approval
|
||||
```
|
||||
|
||||
Error examples: max less than min; missing workflow; unresolved currency option.
|
||||
|
||||
### `customers.csv`
|
||||
|
||||
Purpose: import CRM customers.
|
||||
Target: `crm_customers`.
|
||||
Seed type: `business`.
|
||||
Required columns: `organization_code`, `customer_code`, `customer_name`, `customer_type`, `customer_status`, `created_by_email`.
|
||||
Optional columns: `branch_code`, `abbr`, `tax_id`, `address`, `province`, `district`, `sub_district`, `postal_code`, `country`, `phone`, `fax`, `email`, `website`, `lead_channel`, `customer_group`, `customer_sub_group`, `owner_user_email`, `notes`, `is_active`.
|
||||
Generated columns: `id`, timestamps, owner assignment timestamps if owner provided.
|
||||
Validation rules: code unique per organization; option references resolve; email format when provided.
|
||||
Relationship resolution: organization, branch, owner user, creator user, master options.
|
||||
Duplicate detection: `organization_id + customer_code`.
|
||||
Upsert key: `organization_code + customer_code`.
|
||||
Import order: `30`.
|
||||
|
||||
```csv
|
||||
organization_code,customer_code,customer_name,customer_type,customer_status,owner_user_email,created_by_email,branch_code,customer_group,email,phone
|
||||
ALLA,CUS-001,Siam Manufacturing,company,active,sales.crane.uat@alla.local,admin@example.com,head_office,industrial,contact@siam.example,02-000-1000
|
||||
```
|
||||
|
||||
Error examples: unresolved owner; invalid customer group/sub-group relationship; duplicate customer code.
|
||||
|
||||
### `contacts.csv`
|
||||
|
||||
Purpose: import customer contacts.
|
||||
Target: `crm_customer_contacts`.
|
||||
Seed type: `business`.
|
||||
Required columns: `organization_code`, `customer_code`, `contact_name`, `created_by_email`.
|
||||
Optional columns: `position`, `department`, `phone`, `mobile`, `email`, `is_primary`, `notes`, `is_active`.
|
||||
Generated columns: `id`, timestamps.
|
||||
Validation rules: customer resolves; email format; one primary contact warning when multiple rows set primary.
|
||||
Relationship resolution: organization, customer, creator user.
|
||||
Duplicate detection: `organization + customer + email` when email exists, otherwise customer + contact name.
|
||||
Upsert key: `organization_code + customer_code + email/contact_name`.
|
||||
Import order: `32`.
|
||||
|
||||
```csv
|
||||
organization_code,customer_code,contact_name,email,mobile,position,is_primary,created_by_email
|
||||
ALLA,CUS-001,Anan Sales,anan@siam.example,081-000-0001,Procurement Manager,true,admin@example.com
|
||||
```
|
||||
|
||||
Error examples: missing customer; duplicate primary contact warning; invalid email.
|
||||
|
||||
### `contact-shares.csv`
|
||||
|
||||
Purpose: import contact sharing grants.
|
||||
Target: `crm_contact_shares`.
|
||||
Seed type: `business`.
|
||||
Required columns: `organization_code`, `customer_code`, `contact_email`, `shared_to_user_email`, `shared_by_user_email`.
|
||||
Optional columns: `remark`, `is_active`.
|
||||
Generated columns: `id`, `shared_at`, timestamps.
|
||||
Validation rules: contact resolves; users resolve; cannot share to user outside organization membership.
|
||||
Relationship resolution: organization, customer, contact, users.
|
||||
Duplicate detection: `organization_id + contact_id + shared_to_user_id`.
|
||||
Upsert key: same as duplicate detection.
|
||||
Import order: `33`.
|
||||
|
||||
```csv
|
||||
organization_code,customer_code,contact_email,shared_to_user_email,shared_by_user_email,remark,is_active
|
||||
ALLA,CUS-001,anan@siam.example,sales.dockdoor.uat@alla.local,admin@example.com,Shared for joint account coverage,true
|
||||
```
|
||||
|
||||
Error examples: contact not found; target user has no membership; self-share warning.
|
||||
|
||||
### `leads.csv`
|
||||
|
||||
Purpose: import marketing-owned leads.
|
||||
Target: `crm_leads`.
|
||||
Seed type: `business`.
|
||||
Required columns: `organization_code`, `lead_code`, `status`, `created_by_email`.
|
||||
Optional columns: `branch_code`, `customer_code`, `contact_email`, `description`, `project_name`, `project_location`, `lead_channel`, `product_type_code`, `priority`, `estimated_value`, `awareness_code`, `followup_status`, `lost_reason`, `outcome`, `owner_marketing_user_email`, `assigned_sales_owner_email`, `assignment_remark`.
|
||||
Generated columns: `id`, assignment timestamps when assigned, timestamps.
|
||||
Validation rules: status/priority/product type resolve; customer/contact relationship valid; estimated value numeric.
|
||||
Relationship resolution: organization, branch, customer, contact, users, master options.
|
||||
Duplicate detection: `organization_id + lead_code`.
|
||||
Upsert key: `organization_code + lead_code`.
|
||||
Import order: `34`.
|
||||
|
||||
```csv
|
||||
organization_code,lead_code,status,created_by_email,customer_code,contact_email,branch_code,product_type_code,priority,project_name,owner_marketing_user_email,assigned_sales_owner_email
|
||||
ALLA,LD-001,assigned,mk.uat@alla.local,CUS-001,anan@siam.example,head_office,crane,high,Warehouse Crane,mk.uat@alla.local,sales.crane.uat@alla.local
|
||||
```
|
||||
|
||||
Error examples: contact does not belong to customer; unresolved status option; assignee outside organization.
|
||||
|
||||
### `opportunities.csv`
|
||||
|
||||
Purpose: import sales opportunities.
|
||||
Target: `crm_opportunities`.
|
||||
Seed type: `business`.
|
||||
Required columns: `organization_code`, `opportunity_code`, `customer_code`, `title`, `product_type_code`, `status`, `priority`, `created_by_email`, `updated_by_email`.
|
||||
Optional columns: `lead_code`, `contact_email`, `branch_code`, `description`, `requirement`, `project_name`, `project_location`, `outcome_status`, `lead_channel`, `estimated_value`, `chance_percent`, `expected_close_date`, `competitor`, `source`, `notes`, `is_hot_project`, `pipeline_stage`, `assigned_to_user_email`.
|
||||
Generated columns: `id`, assignment timestamps when assigned, lifecycle timestamps where appropriate.
|
||||
Validation rules: product/status/priority resolve; percent 0-100; dates ISO `YYYY-MM-DD`; lead optional.
|
||||
Relationship resolution: organization, lead, customer, contact, users, options.
|
||||
Duplicate detection: `organization_id + opportunity_code`.
|
||||
Upsert key: `organization_code + opportunity_code`.
|
||||
Import order: `36`.
|
||||
|
||||
```csv
|
||||
organization_code,opportunity_code,customer_code,title,product_type_code,status,priority,created_by_email,updated_by_email,branch_code,contact_email,lead_code,chance_percent,assigned_to_user_email
|
||||
ALLA,OP-001,CUS-001,Warehouse Crane Expansion,crane,negotiation,high,sales.crane.uat@alla.local,sales.crane.uat@alla.local,head_office,anan@siam.example,LD-001,70,sales.crane.uat@alla.local
|
||||
```
|
||||
|
||||
Error examples: chance percent outside range; unresolved lead; contact/customer mismatch.
|
||||
|
||||
### `opportunity-parties.csv`
|
||||
|
||||
Purpose: import opportunity project parties.
|
||||
Target: `crm_opportunity_customers`.
|
||||
Seed type: `business`.
|
||||
Required columns: `organization_code`, `opportunity_code`, `customer_code`, `role_code`.
|
||||
Optional columns: `remark`.
|
||||
Generated columns: `id`, timestamps.
|
||||
Validation rules: opportunity/customer resolve; project party role resolves.
|
||||
Relationship resolution: opportunity, customer, role option.
|
||||
Duplicate detection: `opportunity_id + customer_id + role`.
|
||||
Upsert key: same as duplicate detection.
|
||||
Import order: `37`.
|
||||
|
||||
```csv
|
||||
organization_code,opportunity_code,customer_code,role_code,remark
|
||||
ALLA,OP-001,CUS-001,end_customer,Primary project owner
|
||||
```
|
||||
|
||||
Error examples: unknown role; opportunity not found; duplicate role/customer row.
|
||||
|
||||
### `quotations.csv`
|
||||
|
||||
Purpose: import quotation headers.
|
||||
Target: `crm_quotations`.
|
||||
Seed type: `business`.
|
||||
Required columns: `organization_code`, `quotation_code`, `customer_code`, `quotation_date`, `quotation_type`, `status`, `currency`, `subtotal`, `total_amount`, `created_by_email`, `updated_by_email`.
|
||||
Optional columns: `opportunity_code`, `contact_email`, `branch_code`, `valid_until`, `project_name`, `project_location`, `attention`, `reference`, `notes`, `revision`, `parent_quotation_code`, `revision_remark`, `exchange_rate`, `discount`, `discount_type`, `tax_rate`, `tax_amount`, `chance_percent`, `is_hot_project`, `competitor`, `salesman_email`, `is_sent`, `sent_at`, `sent_via`.
|
||||
Generated columns: `id`, timestamps, approval/snapshot/artifact fields remain runtime generated.
|
||||
Validation rules: status/currency/type resolve; amounts numeric; parent quotation resolves for revision imports.
|
||||
Relationship resolution: organization, opportunity, customer, contact, branch, options, users.
|
||||
Duplicate detection: `organization_id + quotation_code`.
|
||||
Upsert key: `organization_code + quotation_code`.
|
||||
Import order: `40`.
|
||||
|
||||
```csv
|
||||
organization_code,quotation_code,customer_code,quotation_date,quotation_type,status,currency,subtotal,total_amount,created_by_email,updated_by_email,opportunity_code,branch_code,salesman_email
|
||||
ALLA,QT-HO-CR-2607-001,CUS-001,2026-07-02,crane,draft,THB,1000000,1070000,sales.crane.uat@alla.local,sales.crane.uat@alla.local,OP-001,head_office,sales.crane.uat@alla.local
|
||||
```
|
||||
|
||||
Error examples: parent revision missing; total mismatch warning; approved/runtime fields supplied.
|
||||
|
||||
### `quotation-items.csv`
|
||||
|
||||
Purpose: import quotation line items.
|
||||
Target: `crm_quotation_items`.
|
||||
Seed type: `business`.
|
||||
Required columns: `organization_code`, `quotation_code`, `item_number`, `product_type_code`, `description`, `quantity`, `unit_price`, `total_price`.
|
||||
Optional columns: `unit`, `discount`, `discount_type`, `tax_rate`, `notes`, `sort_order`.
|
||||
Generated columns: `id`, timestamps.
|
||||
Validation rules: numeric amount fields; product type resolves; quotation resolves.
|
||||
Relationship resolution: quotation, product type, unit, discount type.
|
||||
Duplicate detection: `quotation_id + item_number`.
|
||||
Upsert key: `organization_code + quotation_code + item_number`.
|
||||
Import order: `41`.
|
||||
|
||||
```csv
|
||||
organization_code,quotation_code,item_number,product_type_code,description,quantity,unit,unit_price,discount,discount_type,tax_rate,total_price,sort_order
|
||||
ALLA,QT-HO-CR-2607-001,1,crane,Crane installation package,1,set,1000000,0,,7,1000000,1
|
||||
```
|
||||
|
||||
Error examples: missing quotation; invalid item number; total calculation warning.
|
||||
|
||||
### `quotation-parties.csv`
|
||||
|
||||
Purpose: import quotation project parties.
|
||||
Target: `crm_quotation_customers`.
|
||||
Seed type: `business`.
|
||||
Required columns: `organization_code`, `quotation_code`, `customer_code`, `role_code`.
|
||||
Optional columns: `is_primary`, `remark`.
|
||||
Generated columns: `id`, timestamps.
|
||||
Validation rules: quotation/customer resolve; role resolves; one primary warning per role as applicable.
|
||||
Relationship resolution: quotation, customer, project party role option.
|
||||
Duplicate detection: `quotation_id + customer_id + role`.
|
||||
Upsert key: same as duplicate detection.
|
||||
Import order: `42`.
|
||||
|
||||
```csv
|
||||
organization_code,quotation_code,customer_code,role_code,is_primary,remark
|
||||
ALLA,QT-HO-CR-2607-001,CUS-001,end_customer,true,Primary quotation customer
|
||||
```
|
||||
|
||||
Error examples: missing quotation; unknown project party role; duplicate primary warning.
|
||||
|
||||
### `quotation-topics.csv`
|
||||
|
||||
Purpose: import quotation topic headers.
|
||||
Target: `crm_quotation_topics`.
|
||||
Seed type: `business`.
|
||||
Required columns: `organization_code`, `quotation_code`, `topic_key`, `topic_type`, `title`.
|
||||
Optional columns: `sort_order`.
|
||||
Generated columns: `id`, timestamps.
|
||||
Validation rules: quotation resolves; topic type resolves; topic key unique per quotation CSV batch.
|
||||
Relationship resolution: quotation, topic type option.
|
||||
Duplicate detection: `quotation_id + topic_key`.
|
||||
Upsert key: `organization_code + quotation_code + topic_key`.
|
||||
Import order: `43`.
|
||||
|
||||
```csv
|
||||
organization_code,quotation_code,topic_key,topic_type,title,sort_order
|
||||
ALLA,QT-HO-CR-2607-001,scope-main,scope,Scope of Work,1
|
||||
```
|
||||
|
||||
Error examples: topic type missing; duplicate topic key.
|
||||
|
||||
### `quotation-topic-items.csv`
|
||||
|
||||
Purpose: import quotation topic rows.
|
||||
Target: `crm_quotation_topic_items`.
|
||||
Seed type: `business`.
|
||||
Required columns: `organization_code`, `quotation_code`, `topic_key`, `content`.
|
||||
Optional columns: `sort_order`.
|
||||
Generated columns: `id`, timestamps.
|
||||
Validation rules: topic key resolves from imported or existing topic; content required.
|
||||
Relationship resolution: quotation topic.
|
||||
Duplicate detection: `topic_id + sort_order + content`.
|
||||
Upsert key: `organization_code + quotation_code + topic_key + sort_order`.
|
||||
Import order: `44`.
|
||||
|
||||
```csv
|
||||
organization_code,quotation_code,topic_key,content,sort_order
|
||||
ALLA,QT-HO-CR-2607-001,scope-main,Supply and install one overhead crane system,1
|
||||
```
|
||||
|
||||
Error examples: missing topic; empty content; duplicate sort order warning.
|
||||
|
||||
## Unsupported or Deferred Templates
|
||||
|
||||
### `departments.csv`
|
||||
|
||||
Status: unsupported pending schema. No first-class department table was identified. Do not map this to ad hoc options without an ADR.
|
||||
|
||||
```csv
|
||||
department_code,department_name
|
||||
SALES,Sales
|
||||
```
|
||||
|
||||
### `teams.csv`
|
||||
|
||||
Status: unsupported pending schema. Team scope limitations are documented; no first-class team graph exists.
|
||||
|
||||
```csv
|
||||
team_code,team_name
|
||||
SALES-CRANE,Crane Sales Team
|
||||
```
|
||||
|
||||
### `warehouses.csv`
|
||||
|
||||
Status: unsupported pending schema. No warehouse table was identified.
|
||||
|
||||
```csv
|
||||
warehouse_code,warehouse_name
|
||||
MAIN,Main Warehouse
|
||||
```
|
||||
|
||||
### `sites.csv`
|
||||
|
||||
Status: unsupported pending schema. Project/customer site is currently represented by text fields such as `project_location`, not a reusable site entity.
|
||||
|
||||
```csv
|
||||
site_code,site_name,address
|
||||
BKK-HQ,Bangkok HQ,99/9 Rama IX Road
|
||||
```
|
||||
|
||||
### `services.csv`
|
||||
|
||||
Status: unsupported pending schema. Service catalog does not currently exist as first-class CRM data.
|
||||
|
||||
```csv
|
||||
service_code,service_name
|
||||
INSTALL,Installation Service
|
||||
```
|
||||
|
||||
### `price-books.csv`
|
||||
|
||||
Status: unsupported pending schema. Current quotation items are not backed by a price-book foundation.
|
||||
|
||||
```csv
|
||||
price_book_code,product_or_service_code,currency,unit_price
|
||||
STD-THB,INSTALL,THB,10000
|
||||
```
|
||||
|
||||
### `tax-rates.csv`
|
||||
|
||||
Status: unsupported pending schema. Tax rate currently lives as numeric fields on quotation/item rows.
|
||||
|
||||
```csv
|
||||
tax_code,tax_name,tax_rate
|
||||
VAT7,VAT 7%,7
|
||||
```
|
||||
|
||||
### `attachments.csv`
|
||||
|
||||
Status: deferred. Attachment metadata exists, but binary upload/storage import is not safe as a generic CSV-only flow.
|
||||
|
||||
```csv
|
||||
entity_type,entity_code,file_path,description
|
||||
quotation,QT-HO-CR-2607-001,./files/spec.pdf,Customer specification
|
||||
```
|
||||
|
||||
### `email-settings.csv`
|
||||
|
||||
Status: unsupported pending schema. Email configuration appears environment/provider driven; verification can check readiness but CSV import should not persist secrets without a secure configuration design.
|
||||
|
||||
```csv
|
||||
provider,host,port,from_address
|
||||
smtp,smtp.example.com,587,no-reply@example.com
|
||||
```
|
||||
215
docs/setup/import-mapping.md
Normal file
215
docs/setup/import-mapping.md
Normal file
@@ -0,0 +1,215 @@
|
||||
# CSV Import Mapping
|
||||
|
||||
This document maps supported setup CSV columns to target fields and reference resolvers.
|
||||
|
||||
Common resolver rules:
|
||||
|
||||
- `organization_code` resolves to the setup organization by wizard code, organization slug, or import context alias.
|
||||
- `*_email` resolves to `users.email`.
|
||||
- `branch_code` resolves to `ms_options` where `category = crm_branch`.
|
||||
- `product_type_code` resolves to `ms_options` where `category = crm_product_type`.
|
||||
- Master option values resolve by category and code unless a target field explicitly stores plain text.
|
||||
- All imported rows are organization-scoped unless noted otherwise.
|
||||
|
||||
## `organizations.csv`
|
||||
|
||||
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `organization_code` | setup alias / metadata | trim uppercase | unique in import batch | yes | none | none | Not currently a DB column; used by setup import context. |
|
||||
| `organization_name` | `organizations.name` | trim | non-empty | yes | none | none | |
|
||||
| `slug` | `organizations.slug` | trim lowercase | unique | yes | `organizations.slug` duplicate check | generated from name only in wizard mode | |
|
||||
| `created_by_email` | `organizations.created_by` | lowercase email | user exists | yes | `users.email -> id` | current setup actor | |
|
||||
| `plan` | `organizations.plan` | trim lowercase | known plan string | no | none | `enterprise` for setup-created org | |
|
||||
| `logo_url` | `organizations.image_url` | trim | URL or relative path | no | none | null | |
|
||||
|
||||
## `users.csv`
|
||||
|
||||
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `email` | `users.email` | trim lowercase | email format, unique | yes | duplicate by email | none | Upsert key. |
|
||||
| `name` | `users.name` | trim | non-empty | yes | none | email local part | |
|
||||
| `system_role` | `users.system_role` | trim lowercase | `super_admin,user` | yes | none | `user` | |
|
||||
| `password` | `users.password_hash` | bcrypt hash | required for new credentials user | no | none | generated invite flow later | Do not store raw password. |
|
||||
| `active_organization_code` | `users.active_organization_id` | resolve | org exists | no | organization resolver | null | |
|
||||
| `image_url` | `users.image` | trim | URL optional | no | none | null | |
|
||||
| `reset_password` | import behavior | boolean | true/false | no | none | false | Allows password update for existing users. |
|
||||
|
||||
## `memberships.csv`
|
||||
|
||||
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `organization_code` | `memberships.organization_id` | resolve | org exists | yes | organization resolver | setup org | |
|
||||
| `user_email` | `memberships.user_id` | lowercase | user exists | yes | `users.email` | none | |
|
||||
| `membership_role` | `memberships.role` | lowercase | `admin,user` | yes | none | `user` | |
|
||||
| `business_role` | `memberships.business_role` | lowercase | known CRM fallback role | yes | role definition code | `sales_support` | Compatibility fallback only. |
|
||||
| `permissions` | `memberships.permissions` | pipe split | known permission codes | no | `src/lib/auth/rbac.ts` | default permissions | |
|
||||
| `branch_scope_codes` | `memberships.branch_scope_ids` | pipe split resolve | branch options exist | no | `crm_branch` options | empty array | Compatibility scope only. |
|
||||
| `product_type_scope_codes` | `memberships.product_type_scope_ids` | pipe split resolve | product type options exist | no | `crm_product_type` options | empty array | Compatibility scope only. |
|
||||
|
||||
## `crm-role-assignments.csv`
|
||||
|
||||
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `organization_code` | `organization_id` | resolve | org exists | yes | organization resolver | setup org | |
|
||||
| `user_email` | `user_id` | lowercase | user + membership exist | yes | user resolver | none | |
|
||||
| `crm_role_code` | `role_profile_id` | lowercase | role profile exists | yes | `crm_role_profiles.code` | none | |
|
||||
| `is_primary` | `is_primary` | boolean | true/false | yes | none | false | One primary per user warning/enforcement. |
|
||||
| `branch_scope_mode` | `branch_scope_mode` | lowercase | `all,selected,none,inherit` | yes | none | `inherit` | |
|
||||
| `branch_codes` | `branch_scope_ids` | pipe split resolve | required when mode selected | no | `crm_branch` options | empty array | |
|
||||
| `product_type_scope_mode` | `product_type_scope_mode` | lowercase | `all,selected,none,inherit` | yes | none | `inherit` | |
|
||||
| `product_type_codes` | `product_type_scope_ids` | pipe split resolve | required when mode selected | no | `crm_product_type` options | empty array | |
|
||||
| `is_active` | `is_active` | boolean | true/false | no | none | true | |
|
||||
|
||||
## `master-options.csv`
|
||||
|
||||
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `organization_code` | `organization_id` | resolve | org exists | yes | organization resolver | setup org | |
|
||||
| `category` | `category` | trim lowercase | non-empty | yes | none | none | |
|
||||
| `code` | `code` | trim | non-empty unique per category | yes | duplicate check | none | |
|
||||
| `label` | `label` | trim | non-empty | yes | none | none | |
|
||||
| `value` | `value` | trim | optional | no | none | same as code | |
|
||||
| `parent_category` | parent lookup | trim | parent requires parent_code | no | `ms_options.category` | null | |
|
||||
| `parent_code` | `parent_id` | resolve | parent exists | no | `ms_options.category+code` | null | |
|
||||
| `sort_order` | `sort_order` | integer | >= 0 | no | none | 0 | |
|
||||
| `is_active` | `is_active` | boolean | true/false | no | none | true | |
|
||||
| `metadata_json` | `metadata` | JSON parse | valid object | no | none | null | |
|
||||
|
||||
## `branches.csv`
|
||||
|
||||
Maps to `ms_options` with fixed `category = crm_branch`.
|
||||
|
||||
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `organization_code` | `organization_id` | resolve | org exists | yes | organization resolver | setup org | |
|
||||
| `branch_code` | `code`, `value` | trim lowercase snake_case | unique per org | yes | duplicate check | none | |
|
||||
| `branch_name` | `label` | trim | non-empty | yes | none | none | |
|
||||
| `prefix` | `metadata.prefix` | trim uppercase | optional | no | none | first letters of code | Used by sequence suggestions only. |
|
||||
| `address` | `metadata.address` | trim | optional | no | none | null | |
|
||||
| `tax_id` | `metadata.taxId` | trim | optional | no | none | null | |
|
||||
| `phone` | `metadata.phone` | trim | optional | no | none | null | |
|
||||
| `email` | `metadata.email` | lowercase | email optional | no | none | null | |
|
||||
| `sort_order` | `sort_order` | integer | >= 0 | no | none | 0 | |
|
||||
| `is_active` | `is_active` | boolean | true/false | no | none | true | |
|
||||
|
||||
## `product-types.csv`
|
||||
|
||||
Maps to `ms_options` with fixed `category = crm_product_type`.
|
||||
|
||||
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `organization_code` | `organization_id` | resolve | org exists | yes | organization resolver | setup org | |
|
||||
| `product_type_code` | `code`, `value` | lowercase snake_case | unique per org | yes | duplicate check | none | |
|
||||
| `product_type_name` | `label` | trim | non-empty | yes | none | none | |
|
||||
| `document_prefix` | `metadata.documentPrefix` | uppercase | optional | no | none | derived from code | Used for sequence suggestion. |
|
||||
| `sort_order` | `sort_order` | integer | >= 0 | no | none | 0 | |
|
||||
| `is_active` | `is_active` | boolean | true/false | no | none | true | |
|
||||
| `metadata_json` | `metadata` merge | JSON parse | object | no | none | null | Merged after `documentPrefix`. |
|
||||
|
||||
## `document-sequences.csv`
|
||||
|
||||
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `organization_code` | `organization_id` | resolve | org exists | yes | organization resolver | setup org | |
|
||||
| `branch_code` | `branch_id` | resolve | option exists when provided | no | `crm_branch` option | empty string | Empty string means generic branch scope. |
|
||||
| `product_type_code` | `product_type` | normalize | option exists or `all` | no | `crm_product_type` option/code | `all` | Store normalized code, not option id. |
|
||||
| `document_type` | `document_type` | lowercase | supported by sequence foundation | yes | none | none | |
|
||||
| `prefix` | `prefix` | trim | non-empty | yes | none | none | |
|
||||
| `period` | `period` | trim | matches active period format | yes | none | generated current YYMM later | |
|
||||
| `current_number` | `current_number` | integer | >= 0 | no | none | 0 | |
|
||||
| `padding_length` | `padding_length` | integer | 1-12 | no | none | 3 | |
|
||||
| `format` | `format` | trim | contains `{running}` | no | none | `{prefix}{period}-{running}` | |
|
||||
| `reset_policy` | `reset_policy` | lowercase | known reset policy | no | none | `period` | |
|
||||
| `is_active` | `is_active` | boolean | true/false | no | none | true | |
|
||||
|
||||
## `approval-workflows.csv`
|
||||
|
||||
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `organization_code` | `organization_id` | resolve | org exists | yes | organization resolver | setup org | |
|
||||
| `workflow_code` | `code` | lowercase snake_case | unique per org | yes | duplicate check | none | |
|
||||
| `workflow_name` | `name` | trim | non-empty | yes | none | none | |
|
||||
| `entity_type` | `entity_type` | lowercase | `quotation` initially | yes | none | `quotation` | |
|
||||
| `description` | `description` | trim | optional | no | none | null | |
|
||||
| `is_system` | `is_system` | boolean | true/false | no | none | false | |
|
||||
| `is_active` | `is_active` | boolean | true/false | no | none | true | |
|
||||
|
||||
## `approval-steps.csv`
|
||||
|
||||
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `organization_code` | `organization_id` | resolve | org exists | yes | organization resolver | setup org | |
|
||||
| `workflow_code` | `workflow_id` | resolve | workflow exists | yes | approval workflow | none | |
|
||||
| `step_number` | `step_number` | integer | > 0 | yes | none | none | |
|
||||
| `role_code` | `role_code` | lowercase | role code known | yes | role profile optional check | none | |
|
||||
| `role_name` | `role_name` | trim | non-empty | yes | none | label from role profile | |
|
||||
| `approval_mode` | `approval_mode` | lowercase | known mode | no | none | `sequential` | |
|
||||
| `is_required` | `is_required` | boolean | true/false | no | none | true | |
|
||||
| `sla_hours` | `sla_hours` | integer | >= 0 | no | none | 24 | |
|
||||
| `calendar_mode` | `calendar_mode` | lowercase | known mode | no | none | `calendar_days` | |
|
||||
| `timeout_action` | `timeout_action` | lowercase | known action | no | none | `none` | |
|
||||
|
||||
## `approval-matrix.csv`
|
||||
|
||||
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `organization_code` | `organization_id` | resolve | org exists | yes | organization resolver | setup org | |
|
||||
| `entity_type` | `entity_type` | lowercase | `quotation` initially | yes | none | quotation | |
|
||||
| `workflow_code` | `workflow_id` | resolve | workflow exists | yes | approval workflow | none | |
|
||||
| `branch_code` | `branch_id` | resolve | optional branch exists | no | branch option | null | Null means any branch. |
|
||||
| `product_type_code` | `product_type` | normalize | optional product type exists | no | product type option/code | null | |
|
||||
| `min_amount` | `min_amount` | decimal | <= max when both exist | no | none | null | |
|
||||
| `max_amount` | `max_amount` | decimal | >= min when both exist | no | none | null | |
|
||||
| `currency` | `currency` | uppercase | currency option exists | no | `crm_currency` | null | |
|
||||
| `priority` | `priority` | integer | >= 0 | yes | none | 100 | |
|
||||
| `is_default` | `is_default` | boolean | true/false | yes | none | false | |
|
||||
| `is_active` | `is_active` | boolean | true/false | no | none | true | |
|
||||
| `description` | `description` | trim | optional | no | none | null | |
|
||||
|
||||
## CRM Business CSVs
|
||||
|
||||
The following mappings use the same resolver pattern:
|
||||
|
||||
| CSV File | Business Key | Required Reference Resolvers | Important Option Resolvers | Generated Fields | Notes |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `customers.csv` | `organization_code + customer_code` | organization, branch, owner user, created_by user | `crm_customer_type`, `crm_customer_status`, `crm_customer_group`, `crm_customer_sub_group`, `crm_lead_channel` | `id`, timestamps, owner assignment timestamps | Owner history should be generated by service behavior. |
|
||||
| `contacts.csv` | `organization_code + customer_code + email/contact_name` | organization, customer, created_by user | none | `id`, timestamps | Contact must belong to resolved customer. |
|
||||
| `contact-shares.csv` | `organization + contact + shared_to_user` | organization, customer, contact, shared users | none | `id`, `shared_at`, timestamps | Target user must have organization membership. |
|
||||
| `leads.csv` | `organization_code + lead_code` | organization, branch, customer, contact, creator, marketing owner, sales assignee | `crm_lead_status`, `crm_lead_followup_status`, `crm_lead_lost_reason`, `crm_product_type`, `crm_priority`, `crm_lead_awareness`, `crm_lead_channel` | `id`, timestamps, assignment timestamps | Lead outcome defaults to `open`. |
|
||||
| `opportunities.csv` | `organization_code + opportunity_code` | organization, lead, customer, contact, creator, updater, assignee | `crm_product_type`, `crm_opportunity_status`, `crm_priority`, `crm_lead_channel`, outcome/cancel/no-quotation reasons | `id`, timestamps, assignment/lifecycle timestamps | Validate contact/customer and optional lead lineage. |
|
||||
| `opportunity-parties.csv` | `opportunity + customer + role_code` | organization, opportunity, customer | `crm_project_party_role` | `id`, timestamps | Used by revenue attribution. |
|
||||
| `quotations.csv` | `organization_code + quotation_code` | organization, opportunity, customer, contact, branch, users, parent quotation | `crm_quotation_type`, `crm_quotation_status`, `crm_currency`, `crm_discount_type`, `crm_sent_via` | `id`, timestamps | Runtime approval/PDF fields must not be accepted from CSV. |
|
||||
| `quotation-items.csv` | `quotation + item_number` | organization, quotation | `crm_product_type`, `crm_unit`, `crm_discount_type` | `id`, timestamps | Validate numeric price fields. |
|
||||
| `quotation-parties.csv` | `quotation + customer + role_code` | organization, quotation, customer | `crm_project_party_role` | `id`, timestamps | Used by quotation reporting/PDF context. |
|
||||
| `quotation-topics.csv` | `quotation + topic_key` | organization, quotation | `crm_quotation_topic_type` | `id`, timestamps | `topic_key` is import-only alias. |
|
||||
| `quotation-topic-items.csv` | `quotation + topic_key + sort_order` | organization, quotation topic by import alias or existing lookup | none | `id`, timestamps | Topic must be preview-resolved before commit. |
|
||||
|
||||
Business CSV field transforms:
|
||||
|
||||
- Dates: accept `YYYY-MM-DD`; API responses remain ISO UTC.
|
||||
- Booleans: accept `true,false,1,0,yes,no`; normalize to boolean.
|
||||
- Amounts: parse decimal with `.`; reject thousands separators in strict mode.
|
||||
- Pipe lists: split on `|`, trim, reject empty tokens in strict mode.
|
||||
- Empty string: normalize to `null` for nullable DB fields.
|
||||
|
||||
Business CSV fallback rules:
|
||||
|
||||
- `created_by_email` may fall back to setup actor only when the CSV file explicitly omits it and the import run is wizard-owned.
|
||||
- `updated_by_email` may fall back to `created_by_email`.
|
||||
- `branch_code` may fall back to the wizard default branch.
|
||||
- `currency` may fall back to organization default currency once that is persisted in setup state or organization metadata.
|
||||
- Option fields should not silently create new options unless import mode is `allowOptionCreate`.
|
||||
|
||||
## Unsupported Mapping Decisions
|
||||
|
||||
| CSV | Mapping Decision |
|
||||
| --- | --- |
|
||||
| `departments.csv` | Block. No first-class schema. |
|
||||
| `teams.csv` | Block. No first-class team graph; security docs note team-scope limitations. |
|
||||
| `warehouses.csv` | Block. No first-class schema. |
|
||||
| `sites.csv` | Block. Current project location is text on lead/opportunity/quotation. |
|
||||
| `services.csv` | Block. No first-class service catalog. |
|
||||
| `price-books.csv` | Block. No price book foundation. |
|
||||
| `tax-rates.csv` | Block. No tax rate table; quotation/item rows carry tax numbers. |
|
||||
| `attachments.csv` | Defer. Needs binary upload/storage import design, not pure CSV. |
|
||||
| `email-settings.csv` | Block. No secure first-class email settings table. |
|
||||
32
docs/setup/reset-reseed-matrix.md
Normal file
32
docs/setup/reset-reseed-matrix.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Reset and Reseed Matrix
|
||||
|
||||
All reset operations must be blocked in production unless an explicit product decision introduces a safe production-specific reset path. Existing reset guards in `scripts/db/reset-database.ts` and `scripts/seed-reset.ts` must be preserved.
|
||||
|
||||
| Scope | Tables Affected | Data Retained | Data Deleted | Safety Guard | Requires Confirmation | Allowed Environment | Transaction Behavior | Storage Cleanup Behavior | Audit Behavior | Recommended Command/API |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `foundation_reset` | `ms_options`, `document_sequences`, `crm_approval_workflows`, `crm_approval_steps`, `crm_approval_matrices`, document template/library/report/notification foundation rows | Users, organizations, memberships, business data where compatible | Foundation rows for target organization only | Block production destructive mode; require target org | yes | local, test, staging with flag | Single DB transaction where possible | Document library storage cleanup must be planned and reported; do not delete approved artifacts | Audit setup reset action | `POST /api/setup/reset` with scope |
|
||||
| `organization_reset` | `organizations`, `memberships`, CRM role assignments/profiles for target org, organization-scoped foundation rows | Global users unless explicitly selected | Target organization and tenant-scoped rows | Require exact organization code/name confirmation | yes | local/test/staging with flag | Transaction for DB rows | Cleanup only setup-owned storage prefix; report leftovers | Audit setup reset action | future setup reset service |
|
||||
| `business_reset` | customers, contacts, contact shares, leads, opportunities, quotations, related parties/items/topics/followups, business attachments metadata | Organization, users, memberships, foundation rows | Business records for target organization | Require target org and business reset phrase | yes | local/test/staging with flag | Transaction for DB rows | Delete only non-approved setup/business import files when explicitly selected | Audit reset summary | future setup reset service |
|
||||
| `demo_uat_reset` | UAT users, UAT memberships, UAT CRM role assignments, UAT-seeded CRM business/runtime fixture rows | Production foundation rows and non-UAT business data | Rows tagged/deterministically known from `uat-users.seed.ts` and `crm-uat.seed.ts` | Require demo/UAT mode and seed tag | yes | local/test/staging | Transaction for DB rows | Remove demo-generated storage objects under demo prefix only | Audit reset summary | extend `scripts/seed-uat.ts`/future API |
|
||||
| `full_reset` | Entire public/drizzle schemas through existing reset script | Nothing in target database | All DB data | Existing `--allow-db-reset`; production blocked; unsafe host/db blocked | yes | local/test only by default | Drop/recreate schema | Storage cleanup is out-of-band and must be explicit | Console/report only before setup audit exists | `npm run db:reset -- --allow-db-reset` |
|
||||
| `csv_import_rollback` | Rows from one import manifest | Data outside import manifest | Imported/updated rows when reversible metadata exists | Requires seed manifest item checksums | yes | local/test/staging; production only if designed later | Transaction if rollback immediately after failed commit; compensating actions otherwise | Cleanup files imported by same manifest only | Audit rollback action | future setup import rollback service |
|
||||
| `setup_run_reset` | proposed `setup_runs`, `setup_run_steps`, `seed_manifests`, `seed_manifest_items` | Actual business/foundation data unless separate scope selected | Setup run metadata | Require setup run id | yes | all non-production; production only metadata reset by super admin later | Transaction | No storage cleanup | Audit metadata reset | future setup state service |
|
||||
|
||||
## General Reset Rules
|
||||
|
||||
- Never rely on client-side confirmation alone.
|
||||
- Require exact typed confirmation for destructive scopes.
|
||||
- Refuse reset when `NODE_ENV=production` unless a future ADR defines an allowed production maintenance workflow.
|
||||
- Use organization-scoped deletes whenever possible.
|
||||
- Runtime generated approved artifacts must not be deleted by `business_reset` unless they are demo/UAT artifacts and the scope explicitly includes them.
|
||||
- Storage cleanup must be best-effort with a compensation report because storage providers do not participate in DB transactions.
|
||||
- Reset reports must list retained data, deleted data, skipped data, warnings, and errors.
|
||||
|
||||
## Reseed Behavior
|
||||
|
||||
- Foundation reseed must be idempotent.
|
||||
- Demo/UAT reseed must be deterministic and isolated from production seed.
|
||||
- Same seed version and checksum should skip unless `force` is explicitly set.
|
||||
- Same seed version with changed checksum should warn or block.
|
||||
- Newer compatible seed versions may apply.
|
||||
- Older versions should block unless rollback mode exists.
|
||||
82
docs/setup/seed-matrix.md
Normal file
82
docs/setup/seed-matrix.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Setup Seed Matrix
|
||||
|
||||
Source task: `plans/task-d.7.1.md`
|
||||
Source audit: `docs/implementation/task-d7-initial-system-setup-audit.md`
|
||||
|
||||
Seed type values:
|
||||
|
||||
- `foundation`: shared system or CRM foundation data required before normal app use.
|
||||
- `organization`: tenant-specific setup data.
|
||||
- `business`: customer, sales, quotation, and related master/business data.
|
||||
- `demo_uat`: deterministic demo or UAT fixture data.
|
||||
- `runtime_generated`: data generated by approved workflows or system actions.
|
||||
- `runtime_only`: operational data that should not be seeded directly.
|
||||
- `unsupported_pending_schema`: requested concept that does not currently have a first-class schema.
|
||||
|
||||
| Module | Entity | Table / Storage | Seed Type | Required For First Login | Required For CRM | Required For Quotation | CSV Importable | Wizard Editable | Auto Generated | Source Truth | Dependencies | Import Order | Reset Scope | Notes |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| Core | User | `users` | organization | yes | yes | yes | yes | yes | no | CSV/Wizard/Auth seed | none | 01 | organization_reset | First administrator must exist before organization-owned foundation setup can complete. |
|
||||
| Core | Organization | `organizations` | organization | yes | yes | yes | yes | yes | no | CSV/Wizard | created_by_user | 02 | organization_reset | Current system seed creates `ALLA Demo`; wizard must accept real organization input. |
|
||||
| Core | Membership | `memberships` | organization | yes | yes | yes | yes | yes | no | CSV/Wizard | user, organization | 03 | organization_reset | Grants app-level organization access. |
|
||||
| Authorization | CRM role profile | `crm_role_profiles` | foundation | no | yes | yes | no | limited | no | `src/lib/auth/rbac.ts` + role foundation | organization, created_by_user | 04 | foundation_reset | Seed from code-defined defaults; import custom profiles later only after governance. |
|
||||
| Authorization | CRM user role assignment | `crm_user_role_assignments` | organization | no | yes | yes | yes | yes | no | CSV/Wizard | user, organization, role profile, branch/product options | 05 | organization_reset | Primary CRM authorization source per ADR-0014. |
|
||||
| Foundation | Master option | `ms_options` | foundation | no | yes | yes | yes | yes | no | Foundation seed/CSV | organization, created_by_user | 06 | foundation_reset | Shared option table for many governed CRM dropdowns. |
|
||||
| Foundation | Branch | `ms_options(category=crm_branch)` | organization | no | yes | yes | yes | yes | no | CSV/Wizard | organization, created_by_user | 07 | organization_reset | Branch is currently modeled as a master option, not a branch table. |
|
||||
| Foundation | Product type | `ms_options(category=crm_product_type)` | organization | no | yes | yes | yes | yes | no | CSV/Wizard | organization, created_by_user | 08 | organization_reset | Used by CRM scope and document sequence resolution. |
|
||||
| Foundation | Currency | `ms_options(category=crm_currency)` | foundation | no | yes | yes | yes | yes | no | Foundation seed/CSV | organization | 09 | foundation_reset | Default should include THB. |
|
||||
| Foundation | Unit | `ms_options(category=crm_unit)` | foundation | no | no | yes | yes | yes | no | Foundation seed/CSV | organization | 10 | foundation_reset | Used by quotation items. |
|
||||
| Foundation | Status and reason options | `ms_options` status/reason categories | foundation | no | yes | yes | yes | limited | no | Foundation seed/CSV | organization | 11 | foundation_reset | Includes customer, lead, opportunity, quotation, lost/cancel/no-quotation statuses. |
|
||||
| Foundation | Job title | `ms_options(category=crm_job_title)` | foundation | no | yes | yes | yes | limited | no | Foundation seed/CSV | organization | 12 | foundation_reset | Used by PDF signature position fallback rules. |
|
||||
| Foundation | Project party role | `ms_options(category=crm_project_party_role)` | foundation | no | yes | yes | yes | limited | no | Foundation seed/CSV | organization | 13 | foundation_reset | Required by revenue attribution and quotation parties. |
|
||||
| Document sequence | Document sequence | `document_sequences` | foundation | no | yes | yes | yes | yes | no | Foundation seed/Wizard | organization, branch, product type | 14 | foundation_reset | Scoped by organization, branch, product type, document type, period. |
|
||||
| Approval | Approval workflow | `crm_approval_workflows` | foundation | no | no | yes | yes | yes | no | Foundation seed/Wizard | organization, created_by_user | 15 | foundation_reset | Quotation approval depends on this. |
|
||||
| Approval | Approval step | `crm_approval_steps` | foundation | no | no | yes | yes | yes | no | Foundation seed/Wizard | approval workflow | 16 | foundation_reset | Defines sequential actors and SLA metadata. |
|
||||
| Approval | Approval matrix | `crm_approval_matrices` | foundation | no | no | yes | yes | yes | no | Foundation seed/Wizard | approval workflow, branch, product type | 17 | foundation_reset | Resolves workflow by amount/scope. |
|
||||
| Document template | Template | `crm_document_templates` | foundation | no | no | yes | no | limited | no | Foundation seed/document-template foundation | organization, created_by_user | 18 | foundation_reset | Approved path for template metadata. |
|
||||
| Document template | Template version | `crm_document_template_versions` | foundation | no | no | yes | no | limited | no | Foundation seed/document-template foundation | template | 19 | foundation_reset | Must have one active PDFME version for quotation. |
|
||||
| Document template | Template mapping | `crm_document_template_mappings` | foundation | no | no | yes | no | limited | no | Foundation seed/PDF registry | template version | 20 | foundation_reset | DB mapping for PDF placeholders. |
|
||||
| Document template | Template table column | `crm_document_template_table_columns` | foundation | no | no | yes | no | limited | no | Foundation seed/PDF registry | template mapping | 21 | foundation_reset | Required by table placeholders. |
|
||||
| Document library | Document library | `crm_document_libraries` | foundation | no | no | yes | no | limited | no | Foundation seed/document-library foundation | organization, storage provider | 22 | foundation_reset | Metadata for reusable document library files. |
|
||||
| Document library | Document library version | `crm_document_library_versions` + storage object | foundation | no | no | yes | no | limited | partly | Foundation seed/storage provider | document library, storage provider | 23 | foundation_reset | Storage write cannot be DB-transactional; setup report must capture compensation needs. |
|
||||
| Notifications | Notification template | `app_notification_templates` | foundation | no | yes | yes | no | limited | no | Foundation seed/notification foundation | organization, created_by_user | 24 | foundation_reset | Required for approval in-app notifications. |
|
||||
| Reports | Report definition | `crm_report_definitions` | foundation | no | yes | no | no | limited | no | Foundation seed/report foundation | organization | 25 | foundation_reset | Required by report catalog. |
|
||||
| CRM | Customer | `crm_customers` | business | no | yes | yes | yes | yes | no | CSV/CRM service | organization, branch, owner user, master options | 30 | business_reset | Must use customer service/audit rules in implementation. |
|
||||
| CRM | Customer owner history | `crm_customer_owner_history` | runtime_generated | no | yes | yes | no | no | yes | Customer service | customer, owner user | 31 | business_reset | Generated when owner changes; UAT seed currently writes initial history. |
|
||||
| CRM | Contact | `crm_customer_contacts` | business | no | yes | yes | yes | yes | no | CSV/CRM service | organization, customer | 32 | business_reset | Contact visibility is governed by customer/contact sharing rules. |
|
||||
| CRM | Contact share | `crm_contact_shares` | business | no | yes | optional | yes | yes | no | CSV/CRM service | organization, contact, shared user | 33 | business_reset | Must preserve ADR-0015 visibility model. |
|
||||
| CRM | Lead | `crm_leads` | business | no | yes | optional | yes | yes | no | CSV/CRM service | organization, branch, customer/contact optional, owner/assignee users, options | 34 | business_reset | Dedicated marketing-owned lead table per ADR-0018 direction. |
|
||||
| CRM | Lead followup | audit payload in `tr_audit_logs` today | runtime_generated | no | yes | no | no | no | yes | Lead service | lead, user | 35 | business_reset | No first-class lead followup table currently identified. |
|
||||
| CRM | Opportunity | `crm_opportunities` | business | no | yes | yes | yes | yes | no | CSV/CRM service | organization, customer, contact, lead optional, options, assignee | 36 | business_reset | Active sales opportunity domain. |
|
||||
| CRM | Opportunity party | `crm_opportunity_customers` | business | no | yes | yes | yes | yes | no | CSV/CRM service | opportunity, customer, project party role | 37 | business_reset | Used by revenue attribution. |
|
||||
| CRM | Opportunity followup | `crm_opportunity_followups` | business | no | yes | optional | no | yes | no | Opportunity service | opportunity, contact, followup option | 38 | business_reset | Could be CSV-supported later; D.7.1 does not require a template. |
|
||||
| CRM | Opportunity attachment | `crm_opportunity_attachments` + storage/file path | business | no | yes | optional | no | yes | partly | Opportunity service/storage foundation | opportunity, storage | 39 | business_reset | File import deferred until upload transport rules are specified. |
|
||||
| Quotation | Quotation | `crm_quotations` | business | no | yes | yes | yes | yes | no | CSV/Quotation service | organization, opportunity optional, customer, contact, branch, options, salesman | 40 | business_reset | Must preserve revision/approval/document behavior. |
|
||||
| Quotation | Quotation item | `crm_quotation_items` | business | no | no | yes | yes | yes | no | CSV/Quotation service | quotation, product type, unit, discount type | 41 | business_reset | Not a price-book row; item text/pricing belong to quotation. |
|
||||
| Quotation | Quotation party | `crm_quotation_customers` | business | no | yes | yes | yes | yes | no | CSV/Quotation service | quotation, customer, project party role | 42 | business_reset | Billing/end customer rules affect reports. |
|
||||
| Quotation | Quotation topic | `crm_quotation_topics` | business | no | no | yes | yes | yes | no | CSV/Quotation service | quotation, topic type | 43 | business_reset | Parent for topic items. |
|
||||
| Quotation | Quotation topic item | `crm_quotation_topic_items` | business | no | no | yes | yes | yes | no | CSV/Quotation service | quotation topic | 44 | business_reset | Ordered terms/scope rows. |
|
||||
| Quotation | Quotation followup | `crm_quotation_followups` | business | no | yes | yes | no | yes | no | Quotation service | quotation, contact, followup option | 45 | business_reset | Could be CSV-supported later; D.7.1 does not require a template. |
|
||||
| Quotation | Quotation attachment | `crm_quotation_attachments` + storage/file path | business | no | optional | optional | no | yes | partly | Quotation service/storage foundation | quotation, storage | 46 | business_reset | `attachments.csv` deferred because binary transport is not generic CSV. |
|
||||
| Approval runtime | Approval request | `crm_approval_requests` | runtime_generated | no | no | yes | no | no | yes | Approval service | quotation, approval workflow | 50 | demo_uat_reset | Production requests are runtime data; demo seed may generate fixtures. |
|
||||
| Approval runtime | Approval action | `crm_approval_actions` | runtime_generated | no | no | yes | no | no | yes | Approval service | approval request, actor | 51 | demo_uat_reset | Production actions are runtime audit/workflow records. |
|
||||
| Audit | Audit log | `tr_audit_logs` | runtime_only | no | no | no | no | no | yes | Audit foundation | actor, entity | 60 | full_reset | Should be created by services, not CSV import. |
|
||||
| Notifications | Notification event | `app_notification_events` | runtime_only | no | no | no | no | no | yes | Notification foundation | entity/action | 61 | full_reset | Runtime queue/event state. |
|
||||
| Notifications | User notification | `app_notifications` | runtime_only | no | no | no | no | no | yes | Notification foundation | notification event, recipient | 62 | full_reset | User-facing runtime inbox state. |
|
||||
| Notifications | Dispatch | `app_notification_dispatches` | runtime_only | no | no | no | no | no | yes | Notification foundation | notification event/template | 63 | full_reset | Provider dispatch runtime state. |
|
||||
| Notifications | Delivery | `app_notification_deliveries` | runtime_only | no | no | no | no | no | yes | Notification foundation | notification | 64 | full_reset | Delivery runtime state. |
|
||||
| PDF/storage | Document artifact | `crm_document_artifacts` + storage object | runtime_generated | no | no | yes | no | no | yes | Document artifact/PDF/storage foundations | entity, template, storage | 65 | explicit_artifact_reset | Approved documents are immutable-first; do not delete casually. |
|
||||
| Storage | Uploaded file | storage provider + attachment metadata | runtime_generated | no | optional | optional | no | no | partly | Storage foundation | entity, uploader | 66 | explicit_storage_reset | Storage cleanup needs compensation/reporting. |
|
||||
| Setup | Setup run | proposed `setup_runs` | foundation | no | no | no | no | no | yes | Setup foundation | actor | 70 | setup_run_reset | Proposed for resume/reporting; not implemented yet. |
|
||||
| Setup | Setup run step | proposed `setup_run_steps` | foundation | no | no | no | no | no | yes | Setup foundation | setup run | 71 | setup_run_reset | Proposed for step state and error history. |
|
||||
| Setup | Seed manifest | proposed `seed_manifests` | foundation | no | yes | yes | no | no | yes | Setup foundation | organization optional | 72 | setup_run_reset | Proposed for seed lifecycle tracking. |
|
||||
| Setup | Seed manifest item | proposed `seed_manifest_items` | foundation | no | yes | yes | no | no | yes | Setup foundation | seed manifest | 73 | setup_run_reset | Proposed for checksum and item-level report. |
|
||||
| Demo | UAT users | `users`, `memberships`, `crm_user_role_assignments` | demo_uat | no | no | no | no | no | no | `src/db/seeds/uat-users.seed.ts` | foundation seed | 80 | demo_uat_reset | Separate from production foundation install. |
|
||||
| Demo | UAT CRM data | CRM business/runtime tables | demo_uat | no | no | no | no | no | no | `src/db/seeds/crm-uat.seed.ts` | UAT users, foundation seed | 81 | demo_uat_reset | Deterministic demo stories. |
|
||||
| Unsupported | Department | none identified | unsupported_pending_schema | no | no | no | no | no | no | pending ADR/schema | organization | 90 | none | Do not implement as first-class setup data without schema decision. |
|
||||
| Unsupported | Team | none identified | unsupported_pending_schema | no | no | no | no | no | no | pending ADR/schema | organization | 91 | none | Team-scope limitations are documented in security docs. |
|
||||
| Unsupported | Warehouse | none identified | unsupported_pending_schema | no | no | no | no | no | no | pending ADR/schema | organization | 92 | none | No warehouse table reviewed. |
|
||||
| Unsupported | Site | none identified | unsupported_pending_schema | no | optional | optional | no | no | no | pending ADR/schema | customer/opportunity | 93 | none | Project location is currently stored on lead/opportunity/quotation text fields. |
|
||||
| Unsupported | Service catalog | none identified | unsupported_pending_schema | no | no | optional | no | no | no | pending ADR/schema | organization | 94 | none | Current quotation item descriptions are free-form. |
|
||||
| Unsupported | Price book | none identified | unsupported_pending_schema | no | no | optional | no | no | no | pending ADR/schema | product/service catalog | 95 | none | Do not conflate with generic starter `products` table. |
|
||||
| Unsupported | Tax rate table | none identified | unsupported_pending_schema | no | no | optional | no | no | no | pending ADR/schema | organization/currency | 96 | none | Quotation tax rate is currently stored on quotation/item rows. |
|
||||
| Configuration | Email provider config | environment/provider settings | unsupported_pending_schema | no | optional | optional | no | limited | no | environment | deployment config | 97 | none | Verification can check env readiness; no first-class table identified. |
|
||||
136
docs/setup/seed-version-manifest.md
Normal file
136
docs/setup/seed-version-manifest.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# Seed Version and Manifest Strategy
|
||||
|
||||
Seed manifests make setup repeatable, auditable, and safe to resume.
|
||||
|
||||
## Seed Package Model
|
||||
|
||||
| Field | Meaning |
|
||||
| --- | --- |
|
||||
| `name` | Stable package name, such as `system-core`, `crm-foundation`, `crm-demo-uat`. |
|
||||
| `version` | Semantic version for the seed package. |
|
||||
| `type` | `foundation`, `organization`, `business`, `demo_uat`, or `setup_state`. |
|
||||
| `dependencies` | Package names and compatible versions required before this package. |
|
||||
| `checksum` | Checksum over manifest content and referenced item checksums. |
|
||||
| `appliedAt` | Timestamp when applied. |
|
||||
| `appliedBy` | User id or setup actor id. |
|
||||
| `targetOrganization` | Organization id/code when organization-scoped. |
|
||||
| `source` | `script`, `wizard`, `csv`, or `plugin`. |
|
||||
| `status` | `pending`, `applied`, `skipped`, `warning`, `failed`, `rolled_back`. |
|
||||
| `report` | Import/seed report with counts, warnings, errors, and storage compensation notes. |
|
||||
|
||||
## Manifest Format
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "crm-foundation",
|
||||
"version": "1.0.0",
|
||||
"type": "foundation",
|
||||
"dependencies": ["system-core@1.0.0"],
|
||||
"targetOrganization": "ALLA",
|
||||
"source": "wizard",
|
||||
"items": [
|
||||
{
|
||||
"file": "master-options.csv",
|
||||
"checksum": "sha256:...",
|
||||
"required": true,
|
||||
"importOrder": "06"
|
||||
},
|
||||
{
|
||||
"file": "document-sequences.csv",
|
||||
"checksum": "sha256:...",
|
||||
"required": true,
|
||||
"importOrder": "14"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Package Naming
|
||||
|
||||
| Package | Type | Owner |
|
||||
| --- | --- | --- |
|
||||
| `system-core` | organization | setup foundation |
|
||||
| `crm-foundation` | foundation | foundation seed services |
|
||||
| `crm-organization` | organization | setup wizard/import |
|
||||
| `crm-business-import` | business | CSV import engine |
|
||||
| `crm-demo-uat` | demo_uat | UAT seed services |
|
||||
| `document-template-foundation` | foundation | document-template/PDF foundations |
|
||||
| `notification-foundation` | foundation | notification foundation |
|
||||
| `report-foundation` | foundation | CRM report foundation |
|
||||
|
||||
## Version Rules
|
||||
|
||||
| Existing Manifest | Incoming Manifest | Behavior |
|
||||
| --- | --- | --- |
|
||||
| none | any valid version | Apply when dependencies pass. |
|
||||
| same version + same checksum | same content | Skip and report already applied. |
|
||||
| same version + changed checksum | changed content | Warn/block unless `force` is true and package allows mutable same-version seed. |
|
||||
| older version | newer compatible version | Apply upgrade path after compatibility check. |
|
||||
| newer version | older version | Block unless explicit rollback mode exists. |
|
||||
| failed | same checksum | Allow retry from failed item when service is idempotent. |
|
||||
| rolled back | newer version | Apply only after dependency and cleanup verification. |
|
||||
|
||||
## Checksum Rules
|
||||
|
||||
- Item checksum uses canonical CSV bytes after line-ending normalization.
|
||||
- Manifest checksum includes sorted item checksums and manifest metadata except `appliedAt`, `appliedBy`, and runtime report.
|
||||
- Generated wizard inputs should be serialized into canonical JSON and hashed as an item, for example `wizard-organization.json`.
|
||||
- Storage object checksums should be recorded separately because storage writes cannot be DB-transactional.
|
||||
|
||||
## Dependency Rules
|
||||
|
||||
- Dependencies use package names and semver ranges, such as `crm-foundation@^1.0.0`.
|
||||
- A dependency is satisfied when a successful manifest with compatible version/checksum exists for the same target organization or global scope.
|
||||
- Missing required dependencies block apply.
|
||||
- Optional dependencies produce warnings.
|
||||
|
||||
## Report Contract
|
||||
|
||||
Every seed package apply should produce:
|
||||
|
||||
```json
|
||||
{
|
||||
"imported": 0,
|
||||
"updated": 0,
|
||||
"skipped": 0,
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"storage": {
|
||||
"createdObjects": [],
|
||||
"cleanupWarnings": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Persistence Strategy
|
||||
|
||||
Use proposed tables:
|
||||
|
||||
- `seed_manifests`
|
||||
- `seed_manifest_items`
|
||||
|
||||
D.7.1 does not add migrations. D.7.8 should implement persistence after setup APIs and CSV import behavior are stable.
|
||||
|
||||
## Upgrade Behavior
|
||||
|
||||
1. Resolve target organization.
|
||||
2. Load existing manifests for target scope.
|
||||
3. Validate package dependencies.
|
||||
4. Compute incoming checksums.
|
||||
5. Compare version/checksum behavior table.
|
||||
6. Dry-run item operations.
|
||||
7. Apply in import order.
|
||||
8. Store manifest and item reports in the same DB transaction where possible.
|
||||
9. Store storage compensation report after non-transactional storage operations.
|
||||
|
||||
## Rollback Behavior
|
||||
|
||||
Rollback is not a default seed feature. It requires:
|
||||
|
||||
- previous manifest item reports
|
||||
- reversible upsert strategy
|
||||
- explicit reset scope
|
||||
- storage cleanup strategy
|
||||
- audit trail
|
||||
|
||||
Until implemented, use scoped reset/reseed rather than pretending arbitrary rollback is safe.
|
||||
161
docs/setup/setup-plugin-architecture.md
Normal file
161
docs/setup/setup-plugin-architecture.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# Setup Plugin Architecture
|
||||
|
||||
Goal: future modules can register setup behavior without editing the core wizard for every feature.
|
||||
|
||||
This is a design proposal only. No plugin runtime is implemented in D.7.1.
|
||||
|
||||
## Plugin Contract
|
||||
|
||||
```ts
|
||||
interface SetupPlugin {
|
||||
moduleId: string;
|
||||
displayName: string;
|
||||
dependencies: string[];
|
||||
enabledCondition: SetupEnabledCondition;
|
||||
setupSteps: SetupStepDefinition[];
|
||||
csvTemplates: CsvTemplateDefinition[];
|
||||
seedTasks: SeedTaskDefinition[];
|
||||
verificationChecks: VerificationCheckDefinition[];
|
||||
resetScopes: ResetScopeDefinition[];
|
||||
}
|
||||
```
|
||||
|
||||
## Fields
|
||||
|
||||
| Field | Purpose |
|
||||
| --- | --- |
|
||||
| `moduleId` | Stable identifier, for example `crm.quotation`. |
|
||||
| `displayName` | Human-readable module name in setup UI. |
|
||||
| `dependencies` | Other module ids or seed package versions required first. |
|
||||
| `enabledCondition` | Function/config deciding if module applies to this installation. |
|
||||
| `setupSteps` | Optional wizard steps or sections contributed by the module. |
|
||||
| `csvTemplates` | CSV templates owned by the module. |
|
||||
| `seedTasks` | Idempotent seed operations. |
|
||||
| `verificationChecks` | Checks added to the verification matrix. |
|
||||
| `resetScopes` | Reset/reseed behavior owned by the module. |
|
||||
|
||||
## Example Plugin Manifest
|
||||
|
||||
```json
|
||||
{
|
||||
"moduleId": "crm.quotation",
|
||||
"displayName": "CRM Quotation",
|
||||
"dependencies": ["core.foundation", "crm.foundation", "crm.approval"],
|
||||
"setupSteps": ["document-sequences", "approval-workflow", "csv-import"],
|
||||
"csvTemplates": ["quotations.csv", "quotation-items.csv", "quotation-parties.csv"],
|
||||
"seedTasks": ["quotation-document-sequences", "quotation-template-mappings"],
|
||||
"verificationChecks": ["SEQUENCE_QUOTATION", "APPROVAL_WORKFLOW", "PDF_TEMPLATE_ASSET"],
|
||||
"resetScopes": ["business_reset", "demo_uat_reset"]
|
||||
}
|
||||
```
|
||||
|
||||
## Core Modules
|
||||
|
||||
| Module | Owns |
|
||||
| --- | --- |
|
||||
| `core.foundation` | Readiness, users, organizations, memberships, setup state, seed manifests. |
|
||||
| `crm.foundation` | Master options, branch/product type scopes, CRM role profiles, CRM assignments. |
|
||||
| `crm.customer` | Customers, contacts, contact sharing, customer ownership verification. |
|
||||
| `crm.lead` | Lead import, lead sequence verification, lead master options. |
|
||||
| `crm.opportunity` | Opportunity import, parties, followups, outcome lifecycle checks. |
|
||||
| `crm.quotation` | Quotations, items, parties, topics, quotation sequences. |
|
||||
| `crm.approval` | Workflows, steps, matrices, approval verification. |
|
||||
| `document` | Templates, template versions, mappings, libraries. |
|
||||
| `notification` | Notification templates and provider readiness checks. |
|
||||
| `reporting` | Report definitions and report catalog verification. |
|
||||
| `future_asset` | Placeholder for asset/warehouse/catalog setup after schema decisions. |
|
||||
| `future_hr` | Placeholder for teams/departments after schema decisions. |
|
||||
|
||||
## Execution Order
|
||||
|
||||
1. Load core plugins.
|
||||
2. Resolve enabled modules.
|
||||
3. Build dependency graph.
|
||||
4. Detect cycles.
|
||||
5. Sort setup steps by dependency and declared order.
|
||||
6. Merge CSV templates and reject duplicate file ownership.
|
||||
7. Merge verification checks and reset scopes.
|
||||
8. Render wizard steps by module and step group.
|
||||
|
||||
## Cycle Rules
|
||||
|
||||
- A plugin cannot depend on itself.
|
||||
- Cycles block setup startup with a developer-facing error.
|
||||
- Optional dependencies must not introduce ordering ambiguity.
|
||||
|
||||
## Extension Points
|
||||
|
||||
### Setup Step
|
||||
|
||||
```ts
|
||||
interface SetupStepDefinition {
|
||||
key: string;
|
||||
title: string;
|
||||
required: boolean;
|
||||
inputsSchema: unknown;
|
||||
previewAction?: string;
|
||||
commitAction?: string;
|
||||
produces: string[];
|
||||
invalidates: string[];
|
||||
}
|
||||
```
|
||||
|
||||
### CSV Template
|
||||
|
||||
```ts
|
||||
interface CsvTemplateDefinition {
|
||||
fileName: string;
|
||||
requiredColumns: string[];
|
||||
optionalColumns: string[];
|
||||
importOrder: string;
|
||||
targetService: string;
|
||||
unsupportedReason?: string;
|
||||
}
|
||||
```
|
||||
|
||||
### Seed Task
|
||||
|
||||
```ts
|
||||
interface SeedTaskDefinition {
|
||||
key: string;
|
||||
packageName: string;
|
||||
version: string;
|
||||
idempotent: boolean;
|
||||
dependencies: string[];
|
||||
dryRunAction: string;
|
||||
commitAction: string;
|
||||
}
|
||||
```
|
||||
|
||||
### Verification Check
|
||||
|
||||
```ts
|
||||
interface VerificationCheckDefinition {
|
||||
checkId: string;
|
||||
area: string;
|
||||
requiredFor: string[];
|
||||
runAction: string;
|
||||
suggestedFix: string;
|
||||
}
|
||||
```
|
||||
|
||||
### Reset Scope
|
||||
|
||||
```ts
|
||||
interface ResetScopeDefinition {
|
||||
key: string;
|
||||
destructive: boolean;
|
||||
allowedEnvironments: string[];
|
||||
requiresTypedConfirmation: boolean;
|
||||
affectedTables: string[];
|
||||
storageCleanup: "none" | "report_only" | "best_effort";
|
||||
}
|
||||
```
|
||||
|
||||
## Safety Rules
|
||||
|
||||
- Plugins can register behavior but cannot bypass setup core authorization.
|
||||
- Plugin seed tasks must be idempotent or marked unsafe.
|
||||
- Plugin reset scopes must declare affected tables and storage behavior.
|
||||
- Plugin CSV templates must declare ownership to avoid two modules writing the same file contract.
|
||||
- Setup core owns persistence of run state, manifests, audit events, and final reports.
|
||||
155
docs/setup/setup-state-machine.md
Normal file
155
docs/setup/setup-state-machine.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# Setup State Machine
|
||||
|
||||
D.7.1 does not implement persistence. This document proposes the model and transitions for D.7.8.
|
||||
|
||||
## States
|
||||
|
||||
```text
|
||||
not_started
|
||||
readiness_checked
|
||||
foundation_installed
|
||||
organization_created
|
||||
administrator_created
|
||||
scope_configured
|
||||
sequences_configured
|
||||
approval_configured
|
||||
csv_validated
|
||||
csv_imported
|
||||
verified
|
||||
completed
|
||||
failed
|
||||
cancelled
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
```text
|
||||
CHECK_READINESS
|
||||
INSTALL_FOUNDATION
|
||||
CREATE_ORGANIZATION
|
||||
CREATE_ADMIN
|
||||
CONFIGURE_SCOPE
|
||||
CONFIGURE_SEQUENCES
|
||||
CONFIGURE_APPROVAL
|
||||
VALIDATE_CSV
|
||||
IMPORT_CSV
|
||||
RUN_VERIFICATION
|
||||
COMPLETE_SETUP
|
||||
FAIL_STEP
|
||||
CANCEL_SETUP
|
||||
RESUME_SETUP
|
||||
RESET_STEP
|
||||
```
|
||||
|
||||
## Transition Rules
|
||||
|
||||
| From | Event | To | Guard |
|
||||
| --- | --- | --- | --- |
|
||||
| `not_started` | `CHECK_READINESS` | `readiness_checked` | Required readiness checks pass or warnings are acknowledged. |
|
||||
| `readiness_checked` | `INSTALL_FOUNDATION` | `foundation_installed` | Migrations valid and seed transaction succeeds. |
|
||||
| `foundation_installed` | `CREATE_ORGANIZATION` | `organization_created` | Organization is created or resolved. |
|
||||
| `organization_created` | `CREATE_ADMIN` | `administrator_created` | User, membership, and CRM role assignment resolve. |
|
||||
| `administrator_created` | `CONFIGURE_SCOPE` | `scope_configured` | At least one branch and product type exists. |
|
||||
| `scope_configured` | `CONFIGURE_SEQUENCES` | `sequences_configured` | Required sequence previews succeed. |
|
||||
| `sequences_configured` | `CONFIGURE_APPROVAL` | `approval_configured` | Quotation workflow, steps, and matrix resolve. |
|
||||
| `approval_configured` | `VALIDATE_CSV` | `csv_validated` | Preview has no blocking errors, or no CSV files were selected. |
|
||||
| `csv_validated` | `IMPORT_CSV` | `csv_imported` | Commit succeeds or CSV import skipped. |
|
||||
| `csv_imported` | `RUN_VERIFICATION` | `verified` | Required verification checks pass. |
|
||||
| `verified` | `COMPLETE_SETUP` | `completed` | No blocking failures remain. |
|
||||
| any non-completed state | `FAIL_STEP` | `failed` | Step returns blocking error. |
|
||||
| any non-completed state | `CANCEL_SETUP` | `cancelled` | User confirms cancellation. |
|
||||
| `failed` | `RESUME_SETUP` | prior recoverable state | Failure source still recoverable. |
|
||||
| completed step state | `RESET_STEP` | earliest affected state | Explicit confirmation and reset scope guard pass. |
|
||||
|
||||
## Proposed Persistence
|
||||
|
||||
### `setup_runs`
|
||||
|
||||
Purpose: one row per setup attempt.
|
||||
|
||||
Fields:
|
||||
|
||||
- `id`
|
||||
- `status`
|
||||
- `mode`: `production | demo_uat | dry_run`
|
||||
- `target_organization_id`
|
||||
- `started_by`
|
||||
- `completed_by`
|
||||
- `started_at`
|
||||
- `completed_at`
|
||||
- `last_error`
|
||||
- `metadata`
|
||||
- timestamps
|
||||
|
||||
### `setup_run_steps`
|
||||
|
||||
Purpose: step-level status, resume, and report storage.
|
||||
|
||||
Fields:
|
||||
|
||||
- `id`
|
||||
- `setup_run_id`
|
||||
- `step_key`
|
||||
- `status`
|
||||
- `input_hash`
|
||||
- `output_json`
|
||||
- `errors_json`
|
||||
- `warnings_json`
|
||||
- `started_at`
|
||||
- `completed_at`
|
||||
- timestamps
|
||||
|
||||
### `seed_manifests`
|
||||
|
||||
Purpose: seed package lifecycle tracking.
|
||||
|
||||
Fields:
|
||||
|
||||
- `id`
|
||||
- `setup_run_id`
|
||||
- `organization_id`
|
||||
- `name`
|
||||
- `version`
|
||||
- `type`
|
||||
- `checksum`
|
||||
- `status`
|
||||
- `applied_by`
|
||||
- `applied_at`
|
||||
- `report_json`
|
||||
- timestamps
|
||||
|
||||
### `seed_manifest_items`
|
||||
|
||||
Purpose: item-level seed/import report and checksum tracking.
|
||||
|
||||
Fields:
|
||||
|
||||
- `id`
|
||||
- `seed_manifest_id`
|
||||
- `item_key`
|
||||
- `source_file`
|
||||
- `checksum`
|
||||
- `status`
|
||||
- `imported_count`
|
||||
- `updated_count`
|
||||
- `skipped_count`
|
||||
- `error_count`
|
||||
- `warning_count`
|
||||
- `report_json`
|
||||
- timestamps
|
||||
|
||||
## Staleness Rules
|
||||
|
||||
- Changing organization setup makes administrator, scope, sequence, approval, CSV, and verification stale.
|
||||
- Changing administrator makes verification stale.
|
||||
- Changing scope makes sequences, approval, CSV, and verification stale.
|
||||
- Changing sequences makes verification stale.
|
||||
- Changing approval makes CSV quotations and verification stale.
|
||||
- Changing CSV preview invalidates committed import unless the source file checksum is unchanged.
|
||||
- Any committed import makes verification stale.
|
||||
|
||||
## Cancellation Rules
|
||||
|
||||
- `cancelled` keeps report history.
|
||||
- Cancellation does not rollback already committed successful steps.
|
||||
- A cancelled setup can resume only through `RESUME_SETUP` with explicit acknowledgement of committed state.
|
||||
57
docs/setup/setup-wizard-blueprint.md
Normal file
57
docs/setup/setup-wizard-blueprint.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Setup Wizard Blueprint
|
||||
|
||||
Target route proposal: `src/app/dashboard/administration/setup/page.tsx`
|
||||
|
||||
Target feature proposal: `src/features/setup/**`
|
||||
|
||||
UI rules:
|
||||
|
||||
- Use dashboard shell and `PageContainer`.
|
||||
- Use shadcn/ui primitives and app icons through `@/components/icons`.
|
||||
- Use server-side enforcement for all setup actions.
|
||||
- Treat client-side step visibility as UX only.
|
||||
- Do not reuse the existing `/setup` template onboarding component as-is; it is a historical prototype.
|
||||
|
||||
| Step Number | Step Name | Purpose | Inputs | Validation | Actions | APIs | Can Skip | Can Go Back | Resume Behavior | Error Handling | Output |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| 1 | System Readiness | Prove the environment can safely initialize. | none, optional setup mode | Env variables, DB connectivity, migration status, storage read/write/delete, upload directory, PDF template asset availability, optional email config. | Run read-only checks and record result. | `GET /api/setup/readiness` | no | no | Resume from latest readiness result but allow re-run. | PASS/WARNING/FAIL with suggested fix per check. | Readiness report. |
|
||||
| 2 | Foundation Install | Install or verify foundation data. | seed mode, target organization context if already created | Foundation seed dependencies present; no pending migration failures. | Run extracted foundation seed services or dry-run. | `POST /api/setup/foundation` | no | yes, before commit only | If already installed, show manifest and allow verify/reapply compatible seed. | Roll back DB transaction on failure; report storage compensation if library write fails. | Foundation seed report. |
|
||||
| 3 | Organization Setup | Create or update tenant organization. | `organization_name`, `organization_code`, `slug`, `tax_id`, `phone`, `email`, `address`, `default_currency`, `timezone`, `logo` | Name/code/slug required; code uppercase; slug lowercase unique; email format; timezone defaults `Asia/Bangkok`; currency resolves. | Create organization and store setup alias. | `POST /api/setup/organization` | no | yes | Existing run loads created organization and locks destructive fields unless reset. | Field errors; duplicate slug/code error; retry safe. | Organization summary. |
|
||||
| 4 | Branch & Product Type Setup | Configure current scope foundations. | Branch rows, product type rows, default branch, default product type | At least one active branch and product type; codes unique; prefixes valid. | Upsert `crm_branch` and `crm_product_type` options. | `POST /api/setup/scope` | no | yes | Resume loads imported/created options. | Row-level validation table. | Scope summary and sequence suggestions. |
|
||||
| 5 | Administrator Setup | Create first administrator and CRM authorization. | Admin name, email, password or existing user, membership role, CRM role, branch/product scope | Email valid; password policy for new user; user membership exists or can be created; role profile resolves. | Create/update user, membership, CRM role assignment. | `POST /api/setup/administrator` | no | yes | Resume masks password and shows resolved user/membership/assignment. | Avoid logging password; show user/role validation errors. | Administrator access summary. |
|
||||
| 6 | Document Sequence Setup | Configure numbering by organization/branch/product/document type. | Document type, branch, product type, prefix, period, current number, padding, format, reset policy | Required sequence coverage for customer, lead, opportunity, quotation; format contains `{running}`; scope resolves. | Preview and upsert sequences. | `POST /api/setup/document-sequences/preview`, `POST /api/setup/document-sequences` | no | yes | Resume loads existing sequence rows and preview samples. | Per-row validation and conflict warnings. | Sequence preview and seed report. |
|
||||
| 7 | Approval Workflow Setup | Configure quotation approval. | Workflow header, steps, matrix rows, SLA fields | Workflow active; steps sequential; matrix resolves to workflow; default quotation matrix exists. | Upsert workflow, steps, matrix. | `POST /api/setup/approval/preview`, `POST /api/setup/approval` | no for quotation install | yes | Resume shows active workflow and matrix status. | Matrix conflict/error report. | Approval configuration report. |
|
||||
| 8 | CSV Import | Import optional master/business data. | CSV files, import mode, upsert mode, partial import toggle | Parseable CSV; required columns; references resolve; duplicates classified; unsupported templates blocked. | Preview, validate, then commit selected files in order. | `POST /api/setup/import/preview`, `POST /api/setup/import/commit` | yes | yes | Resume stores last preview hash and committed manifest. | No commit if preview has blocking errors; partial import only for selected valid files. | Import report. |
|
||||
| 9 | Verification | Confirm install can operate. | check selection, optional email dry-run recipient | Required checks pass; warnings acknowledged. | Run verification matrix. | `POST /api/setup/verify` | no | yes | Resume shows last verification but requires re-run after mutations. | PASS/WARNING/FAIL with suggested fixes. | Verification report. |
|
||||
| 10 | Finish & Report | Close setup and generate summary. | acknowledgement, optional export report | Required setup states completed; blocking failures absent. | Mark setup completed, write manifest/report, optionally lock setup. | `POST /api/setup/complete`, `GET /api/setup/report` | no | yes until complete | Completed run becomes read-only except explicit reset. | Completion blocked when required checks fail. | Setup summary, seed summary, import summary, verification report. |
|
||||
|
||||
## API Behavior
|
||||
|
||||
All setup write APIs should:
|
||||
|
||||
- require authenticated administrator or bootstrap setup token depending on system state
|
||||
- validate request body with Zod or equivalent schema
|
||||
- call `src/features/setup/server/**` services
|
||||
- use existing auth, organization, role, seed, storage, approval, sequence, PDF, and audit foundations
|
||||
- return structured step reports, not raw SQL/provider errors
|
||||
|
||||
## Resume Rules
|
||||
|
||||
- Setup run state is stored in proposed `setup_runs` and `setup_run_steps`.
|
||||
- A completed step can be reviewed.
|
||||
- A completed step can be re-run only when its service supports idempotent upsert and the user confirms conflict behavior.
|
||||
- Later steps become stale if an earlier dependency step changes.
|
||||
- Verification must be re-run after foundation, organization, scope, sequence, approval, or CSV commit changes.
|
||||
|
||||
## Step Outputs
|
||||
|
||||
Every step output should include:
|
||||
|
||||
- `status`: `not_started | running | passed | warning | failed | skipped`
|
||||
- `startedAt`
|
||||
- `completedAt`
|
||||
- `summary`
|
||||
- `items`
|
||||
- `errors`
|
||||
- `warnings`
|
||||
- `nextRecommendedAction`
|
||||
39
docs/setup/verification-matrix.md
Normal file
39
docs/setup/verification-matrix.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Setup Verification Matrix
|
||||
|
||||
Verification checks return `PASS`, `WARNING`, or `FAIL`.
|
||||
|
||||
| Check ID | Area | Check Name | Purpose | Required For | Method | Pass Condition | Warning Condition | Fail Condition | Suggested Fix | API / Service |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `ENV_AUTH_SECRET` | Environment | Auth secret present | Ensure Auth.js can sign sessions. | first login | Read server env. | `AUTH_SECRET` exists and length is acceptable. | Weak-looking local/dev secret. | Missing secret. | Set `AUTH_SECRET` in `.env.local` or deployment secrets. | `setup/readiness.service.ts` |
|
||||
| `ENV_DATABASE_URL` | Environment | Database URL present | Ensure app can connect to PostgreSQL. | all setup | Read server env. | `DATABASE_URL` exists. | Host appears local in non-local environment. | Missing value. | Set `DATABASE_URL`. | `setup/readiness.service.ts` |
|
||||
| `DB_CONNECTIVITY` | Database | Database connectivity | Prove DB is reachable. | all setup | Open DB connection and `select 1`. | Query succeeds. | High latency. | Connection/query fails. | Verify database host, network, credentials. | `src/lib/db.ts` |
|
||||
| `DB_MIGRATIONS` | Database | Migration status | Prevent setup against stale schema. | all setup | Check Drizzle migration metadata/schema tables where available. | Schema matches expected tables. | Migration metadata unavailable but required tables exist. | Required tables missing. | Run `npm run db:migrate`. | setup readiness + Drizzle |
|
||||
| `STORAGE_PROVIDER` | Storage | Storage provider smoke test | Prove seed/document storage can write. | document library/PDF | Write/read/delete test object under setup prefix. | All operations succeed. | Delete cleanup fails but object tracked. | Write/read fails. | Fix local directory/S3 credentials. | `src/features/foundation/storage/**` |
|
||||
| `UPLOAD_DIRECTORY` | Storage | Upload directory readiness | Prove local provider path is writable. | local storage | Check directory exists/create/write/delete. | Directory writable. | Directory created during check. | Not writable. | Create/fix permissions. | storage provider |
|
||||
| `PDF_TEMPLATE_ASSET` | PDF | PDF template assets exist | Ensure quotation PDF can render. | quotation | Check active template version/file/schema. | Active version and schema exist. | Template exists but preview asset missing. | No active template version. | Run foundation/PDF template seed. | document-template/pdf foundations |
|
||||
| `PDF_MAPPING_COVERAGE` | PDF | PDF mappings exist | Ensure placeholders can resolve. | quotation | Count required mappings for active version. | Required mappings present. | Optional mappings missing. | Required mapping missing. | Run PDF mapping seed/audit. | PDF audit services/scripts |
|
||||
| `EMAIL_CONFIG` | Email | Email configuration | Confirm optional email readiness. | optional notifications | Read env/provider config; optional dry-run. | Provider configured and dry-run succeeds. | Email not configured but in-app notifications are available. | Provider configured but dry-run fails. | Fix SMTP/provider settings. | future notification/email service |
|
||||
| `ADMIN_USER` | Auth | First administrator exists | Ensure first login actor exists. | first login | Query `users` by setup admin email. | User exists. | User exists but inactive semantics added later. | Missing user. | Create administrator step. | user/auth service |
|
||||
| `ADMIN_MEMBERSHIP` | Auth | Administrator membership exists | Ensure admin can enter organization. | first login | Query `memberships`. | Membership exists with admin role. | Membership role is user but CRM assignment admin. | Missing membership. | Create membership. | organization/session helpers |
|
||||
| `ADMIN_CRM_ASSIGNMENT` | Authorization | Administrator CRM assignment resolves | Ensure CRM admin permissions resolve. | CRM | Resolve CRM access. | `crm_admin` or equivalent permissions resolve. | Compatibility business role only, no assignment. | No CRM access. | Seed role profiles and assignment. | `resolveCrmAccess()` |
|
||||
| `ORG_ACTIVE` | Organization | Organization active/resolvable | Ensure active org context works. | all setup | Resolve organization and active org for admin. | Organization exists and admin active org set. | Organization exists but active org missing. | Organization missing. | Update `users.active_organization_id`. | `requireOrganizationAccess()` |
|
||||
| `BRANCH_OPTION` | Scope | Branch option exists | Ensure branch scope can resolve. | CRM/quotation | Query `ms_options` category `crm_branch`. | At least one active branch. | Branch exists but no default convention. | No active branch. | Configure branch step. | master-options foundation |
|
||||
| `PRODUCT_TYPE_OPTION` | Scope | Product type option exists | Ensure product scope can resolve. | CRM/quotation | Query `ms_options` category `crm_product_type`. | At least one active product type. | Product type exists but no document prefix metadata. | No active product type. | Configure product types. | master-options foundation |
|
||||
| `SEQUENCE_CUSTOMER` | Document sequence | Customer sequence preview | Ensure customer codes can generate. | CRM | Call sequence preview for customer. | Preview returns code. | Generic branch/product scope only. | Preview fails. | Configure document sequence. | document-sequence foundation |
|
||||
| `SEQUENCE_LEAD` | Document sequence | Lead sequence preview | Ensure lead codes can generate. | CRM | Call sequence preview for `crm_lead`. | Preview returns code. | Generic scope only. | Preview fails. | Configure lead sequence. | document-sequence foundation |
|
||||
| `SEQUENCE_OPPORTUNITY` | Document sequence | Opportunity sequence preview | Ensure opportunity codes can generate. | CRM | Call sequence preview for `crm_opportunity`. | Preview returns code. | Generic scope only. | Preview fails. | Configure opportunity sequence. | document-sequence foundation |
|
||||
| `SEQUENCE_QUOTATION` | Document sequence | Quotation sequence preview | Ensure quotation codes can generate. | quotation | Preview by branch/product type. | Preview returns code for each configured product type. | Missing some branch/product combinations. | No quotation sequence works. | Configure quotation sequences. | document-sequence foundation |
|
||||
| `APPROVAL_WORKFLOW` | Approval | Quotation workflow resolves | Ensure quotation approval can start. | quotation | Query active workflow for quotation. | Active workflow exists. | Multiple active candidates. | Missing workflow. | Configure approval workflow. | approval foundation |
|
||||
| `APPROVAL_MATRIX` | Approval | Approval matrix resolves | Ensure quotation can select workflow by scope/amount. | quotation | Resolve matrix for sample quotation amount. | Matrix resolves. | Default-only fallback. | No matrix resolves. | Configure approval matrix. | approval foundation |
|
||||
| `NOTIFICATION_TEMPLATES` | Notifications | Approval notification templates exist | Ensure in-app approval notifications can render. | CRM/quotation | Query `app_notification_templates`. | Required approval templates active. | Some optional templates missing. | Required templates missing. | Run foundation seed. | notification foundation |
|
||||
| `REPORT_DEFINITIONS` | Reports | Report definitions exist | Ensure report catalog works. | CRM reports | Query `crm_report_definitions`. | Required definitions active. | Definitions exist but categories missing. | No definitions. | Run report foundation seed. | report foundation |
|
||||
| `CSV_PREVIEW` | Import | CSV preview integrity | Ensure uploaded files were validated before commit. | CSV import | Check latest preview hash/status. | Preview exists and matches commit input hash. | Preview stale after dependency change. | Missing preview for commit. | Re-run CSV preview. | setup import service |
|
||||
| `SETUP_MANIFEST` | Setup | Seed manifest recorded | Ensure lifecycle tracking exists. | setup completion | Query proposed manifest tables once implemented. | Manifest recorded with checksums. | Manifest not implemented in early slice. | Manifest required but missing. | Implement D.7.8. | setup manifest service |
|
||||
|
||||
## Required Completion Rule
|
||||
|
||||
Setup can complete only when all required checks for selected setup mode pass:
|
||||
|
||||
- Production foundation mode: all first-login, CRM, quotation, storage/PDF required checks must pass except optional email may warn.
|
||||
- Demo/UAT mode: production required checks plus UAT user/data checks must pass.
|
||||
- Dry-run mode: failures do not write setup completion, but report can be exported.
|
||||
Reference in New Issue
Block a user