# Task Foundation Cleanup: Admin Display Names, MS Option CRUD, Seed & Database Script Standardization ## Status Planned ## Objective Clean up foundational admin experience and system bootstrap workflow before continuing feature development. This task focuses on: * displaying human-readable names instead of raw IDs * adding CRUD management for `ms_options` * consolidating seed scripts * creating a clear system bootstrap script * creating a reset database script for development * auditing old seed/verify/audit scripts * documenting what system admin must run when starting from a fresh database --- ## Problem Current system still exposes raw IDs in some UI/API responses, such as: ```txt createdBy updatedBy assignedBy branchId salesmanId assignedToUserId closedByUserId generatedBy uploadedBy approvedBy ``` This makes admin screens, CRM pages, approval history, audit views, and document settings difficult to read. Current seed/setup scripts are also fragmented: ```json "seed:super-admin" "seed:foundation" "seed:crm-uat" "seed:pdf-template-version" "migrate:membership-business-roles" "seed:task-h1-fixture" "verify:task-h1" "verify:task-h3" "verify:crm-access" "audit:pdf:*" "setup:db" ``` There is no clear single command for: ```txt Fresh system bootstrap Development reset UAT seed PDF template reseed Verification Audit ``` --- # Scope 1: Human-Readable Display Names ## Objective Replace raw ID display with readable names across active UI and API DTOs. ## Required Display Mapping ### User-related fields Fields that should expose display names: ```txt createdBy updatedBy assignedBy assignedToUserId assignedSalesOwnerId salesmanId closedByUserId approvedBy requestedBy actedBy generatedBy uploadedBy voidedBy lockedBy ``` Add readable fields where applicable: ```ts createdByName updatedByName assignedByName assignedToUserName assignedSalesOwnerName salesmanName closedByName approvedByName requestedByName actedByName generatedByName uploadedByName ``` Rules: * Keep raw IDs for system integrity. * Add display fields for UI. * Do not remove ID fields from API unless all consumers are migrated. * Use fallback: * user name * email * ID as last resort --- ### Branch-related fields Fields that should expose readable branch data: ```txt branchId ``` Add: ```ts branchName branchCode ``` If branch master is not a dedicated table and comes from `ms_options`, resolve from master option category. --- ### Option-related fields Fields that should expose labels: ```txt productType status priority stage outcomeStatus lostReason cancelReason noQuotationReason customerType customerStatus leadChannel quotationType discountType currency unit taxRate ``` Add display labels: ```ts productTypeLabel statusLabel priorityLabel stageLabel outcomeStatusLabel lostReasonLabel ``` Rules: * Use `ms_options` as source of display labels. * Do not hardcode labels in UI. * Support fallback to raw code if option label is missing. --- ## Target Areas Review and update active UI/API areas: ```txt src/features/crm/leads/** src/features/crm/opportunities/** src/features/crm/quotations/** src/features/crm/customers/** src/features/crm/approval/** src/features/foundation/approval/** src/features/foundation/notifications/** src/features/crm/dashboard/** src/features/crm/document-templates/** ``` High-priority pages: ```txt Lead list/detail Opportunity list/detail Quotation list/detail Approval history Approval settings Notification inbox Template settings Dashboard widgets Audit-safe activity views ``` --- # Scope 2: Create Shared Display Resolver ## Objective Avoid repeating joins and label mapping everywhere. Create shared foundation utilities: ```txt src/features/foundation/display/server/user-display-resolver.ts src/features/foundation/display/server/option-display-resolver.ts src/features/foundation/display/server/branch-display-resolver.ts src/features/foundation/display/server/display-resolver.ts ``` Recommended APIs: ```ts resolveUserDisplays(ctx, userIds: string[]) resolveOptionLabels(ctx, category: string, codes: string[]) resolveBranchDisplays(ctx, branchIds: string[]) ``` Rules: * batch load to avoid N+1 queries * organization scoped * safe fallback * reusable by CRM services * not tied to one feature --- # Scope 3: MS Option CRUD ## Objective Add admin management for `ms_options`. ## Required APIs Create: ```txt GET /api/foundation/ms-options POST /api/foundation/ms-options GET /api/foundation/ms-options/[id] PATCH /api/foundation/ms-options/[id] DELETE /api/foundation/ms-options/[id] ``` Optional category-specific API: ```txt GET /api/foundation/ms-options/categories GET /api/foundation/ms-options?category=crm_opportunity_stage ``` ## Required UI Create settings page: ```txt /dashboard/settings/master-options ``` or if CRM-scoped: ```txt /dashboard/crm/settings/master-options ``` Recommended UI: * category filter * option table * create option sheet * edit option sheet * soft delete / deactivate * active toggle * sort order * metadata JSON viewer/editor if needed Fields: ```txt category code label value parentId sortOrder isActive metadata ``` Rules: * `category + code + organizationId` must remain unique * cannot hard delete; use soft delete * inactive options should not appear in normal dropdowns * admin can view inactive options * no duplicate code in same category * code should be normalized to snake_case or documented format --- # Scope 4: Seed Script Consolidation ## Objective Create a clear, predictable seed hierarchy. ## Recommended Seed Layers ### 1. System seed Required for system to boot: ```txt organization super admin admin membership base roles/permissions foundation master options document sequences approval default workflow approval matrix default notification templates quotation PDF template metadata ``` Command: ```json "seed:system": "node --experimental-strip-types src/db/seeds/system.seed.ts" ``` --- ### 2. UAT seed Demo/testing data only: ```txt sample customers sample contacts sample leads sample opportunities sample quotations sample approvals sample notifications ``` Command: ```json "seed:uat": "node --experimental-strip-types src/db/seeds/uat.seed.ts" ``` --- ### 3. PDF template seed Template-only reseed: ```json "seed:pdf-template": "node --experimental-strip-types scripts/reseed-pdf-template-version.ts" ``` --- ### 4. Verification scripts Keep as verification, not seed: ```json "verify:encoding" "verify:crm-access" "verify:pdf" ``` --- ## New Standard Commands Recommended `package.json` script structure: ```json { "db:migrate": "drizzle-kit migrate", "db:generate": "drizzle-kit generate", "db:studio": "drizzle-kit studio", "db:reset": "node --experimental-strip-types scripts/db/reset-database.ts", "db:setup": "npm run db:migrate && npm run seed:system", "db:setup:uat": "npm run db:setup && npm run seed:uat", "db:fresh": "npm run db:reset && npm run db:migrate && npm run seed:system", "db:fresh:uat": "npm run db:reset && npm run db:migrate && npm run seed:system && npm run seed:uat", "seed:system": "node --experimental-strip-types src/db/seeds/system.seed.ts", "seed:uat": "node --experimental-strip-types src/db/seeds/uat.seed.ts", "seed:pdf-template": "node --experimental-strip-types scripts/reseed-pdf-template-version.ts", "verify:encoding": "node scripts/verify-encoding.mjs", "verify:crm-access": "node --experimental-strip-types scripts/security/verify-crm-access.ts", "verify:pdf": "npm run audit:pdf", "audit:pdf": "npm run audit:pdf:inventory && npm run audit:pdf:coverage && npm run audit:pdf:runtime && npm run audit:pdf:versions && npm run audit:pdf:placeholders && npm run audit:pdf:parity && npm run audit:pdf:snapshot && npm run audit:pdf:report && npm run audit:pdf:integrity" } ``` --- # Scope 5: Reset Database Script ## Objective Create a controlled development reset script. Create: ```txt scripts/db/reset-database.ts ``` Behavior: * connect to configured database * confirm environment is not production * drop public schema * recreate public schema * drop drizzle schema if present * exit cleanly Required safety guard: ```txt NODE_ENV must not be production DATABASE_URL must not include production host/name ALLOW_DB_RESET=true required ``` Example command: ```bash ALLOW_DB_RESET=true npm run db:reset ``` Recommended SQL: ```sql DROP SCHEMA IF EXISTS public CASCADE; CREATE SCHEMA public; DROP SCHEMA IF EXISTS drizzle CASCADE; ``` Rules: * never run reset without explicit env flag * log target database before reset * fail fast if DATABASE_URL missing --- # Scope 6: Existing Script Audit ## Objective Classify existing scripts into keep, rename, merge, or remove. Current scripts to audit: ```json "seed:super-admin": "node scripts/seed-super-admin.js", "seed:foundation": "node --experimental-strip-types src/db/seeds/foundation.seed.ts", "seed:crm-uat": "node --experimental-strip-types src/db/seeds/crm-uat.seed.ts", "seed:pdf-template-version": "node --experimental-strip-types scripts/reseed-pdf-template-version.ts", "migrate:membership-business-roles": "node --experimental-strip-types scripts/migrate-membership-business-roles.ts", "seed:task-h1-fixture": "node scripts/seed-task-h1-fixture.js", "verify:task-h1": "node scripts/verify-task-h1.js", "verify:task-h3": "node --experimental-strip-types scripts/verify-task-h3.js", "verify:crm-access": "node --experimental-strip-types scripts/security/verify-crm-access.ts", "audit:pdf:inventory": "node --experimental-strip-types scripts/audit-pdf-template-inventory.ts", "audit:pdf:coverage": "node --experimental-strip-types scripts/audit-pdf-mapping-coverage.ts", "audit:pdf:runtime": "node --experimental-strip-types scripts/audit-pdf-runtime-payload.ts", "audit:pdf:report": "node --experimental-strip-types scripts/generate-pdf-audit-report.ts", "verify:encoding": "node scripts/verify-encoding.mjs", "audit:pdf:versions": "node --experimental-strip-types scripts/audit-template-version-integrity.ts", "audit:pdf:placeholders": "node --experimental-strip-types scripts/audit-placeholder-integrity.ts", "audit:pdf:parity": "node --experimental-strip-types scripts/audit-payload-parity.ts", "audit:pdf:snapshot": "node --experimental-strip-types scripts/audit-approved-snapshot-parity.ts", "audit:pdf:integrity": "node --experimental-strip-types scripts/generate-pdf-integrity-report.ts", "audit:pdf": "npm run audit:pdf:inventory && npm run audit:pdf:coverage && npm run audit:pdf:runtime && npm run audit:pdf:versions && npm run audit:pdf:placeholders && npm run audit:pdf:parity && npm run audit:pdf:snapshot && npm run audit:pdf:report && npm run audit:pdf:integrity", "setup:db": "npm run migrate && npm run seed:super-admin && npm run seed:foundation" ``` ## Recommended Classification ### Rename / merge ```txt seed:super-admin seed:foundation ``` Merge into: ```txt seed:system ``` --- ### Rename ```txt seed:crm-uat ``` to: ```txt seed:uat ``` --- ### Rename ```txt seed:pdf-template-version ``` to: ```txt seed:pdf-template ``` --- ### Keep but mark legacy/dev fixture ```txt seed:task-h1-fixture verify:task-h1 verify:task-h3 ``` Move under: ```txt scripts/legacy/task-fixtures/ ``` or rename: ```txt legacy:seed:task-h1-fixture legacy:verify:task-h1 legacy:verify:task-h3 ``` If no longer used, remove after confirming no docs/CI references them. --- ### Review migration script ```txt migrate:membership-business-roles ``` If this was one-time historical migration, move to: ```txt scripts/legacy/migrations/ ``` and remove from common package scripts. If still needed after reset, fold into migration or seed. --- ### Keep ```txt verify:crm-access verify:encoding audit:pdf:* audit:pdf ``` These are still useful. --- ### Replace ```txt setup:db ``` with: ```txt db:setup db:setup:uat db:fresh db:fresh:uat ``` --- # Scope 7: Bootstrap Documentation Create: ```txt docs/operations/system-bootstrap.md ``` Must explain: ## Fresh local development ```bash npm install npm run db:fresh npm exec tsc --noEmit npm run dev ``` ## Fresh UAT/demo data ```bash npm run db:fresh:uat ``` ## Existing database upgrade ```bash npm run db:migrate npm run seed:system ``` ## PDF template reseed only ```bash npm run seed:pdf-template ``` ## Verification ```bash npm exec tsc --noEmit npm run build npm run verify:encoding npm run verify:crm-access npm run audit:pdf ``` ## Script guide Explain: ```txt db:* = database lifecycle seed:* = data bootstrap verify:* = validation audit:* = diagnostics legacy:* = old task-specific tools ``` --- # Scope 8: Acceptance Criteria ## Display names * Created by / Updated by / Assigned by display as readable names * Branch displays as branch name/code * Option fields display labels * Raw IDs are not shown in normal user-facing UI unless intentionally technical ## MS option CRUD * Admin can list options * Admin can create option * Admin can update option * Admin can deactivate / soft delete option * Dropdowns continue to use active options * Duplicate category/code is blocked ## Seed and setup * `seed:system` exists * `seed:uat` exists * `db:reset` exists with safety guard * `db:fresh` works * `db:fresh:uat` works * old scripts are classified or removed * system bootstrap docs exist ## Verification Run: ```bash npm exec tsc --noEmit npm run build npm run verify:encoding ``` Optional: ```bash npm run db:fresh npm run db:fresh:uat npm run verify:crm-access npm run audit:pdf ``` --- # Definition of Done Task is complete when: * active UI no longer exposes raw user/branch/option IDs where display names are expected * `ms_options` has CRUD API and settings UI * system seed is consolidated * UAT seed is separated * database reset script exists and is guarded * package scripts are organized and understandable * old scripts are documented, renamed, moved, or removed * bootstrap documentation is available Result: ```txt Foundation Admin UX = Improved Master Option Management = Operational System Bootstrap = Standardized Database Reset = Safe and Repeatable Script Surface = Clean and Understandable ```