14 KiB
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:
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:
"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:
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:
createdBy
updatedBy
assignedBy
assignedToUserId
assignedSalesOwnerId
salesmanId
closedByUserId
approvedBy
requestedBy
actedBy
generatedBy
uploadedBy
voidedBy
lockedBy
Add readable fields where applicable:
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
- ID as last resort
Branch-related fields
Fields that should expose readable branch data:
branchId
Add:
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:
productType
status
priority
stage
outcomeStatus
lostReason
cancelReason
noQuotationReason
customerType
customerStatus
leadChannel
quotationType
discountType
currency
unit
taxRate
Add display labels:
productTypeLabel
statusLabel
priorityLabel
stageLabel
outcomeStatusLabel
lostReasonLabel
Rules:
- Use
ms_optionsas 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:
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:
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:
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:
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:
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:
GET /api/foundation/ms-options/categories
GET /api/foundation/ms-options?category=crm_opportunity_stage
Required UI
Create settings page:
/dashboard/settings/master-options
or if CRM-scoped:
/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:
category
code
label
value
parentId
sortOrder
isActive
metadata
Rules:
category + code + organizationIdmust 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:
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:
"seed:system": "node --experimental-strip-types src/db/seeds/system.seed.ts"
2. UAT seed
Demo/testing data only:
sample customers
sample contacts
sample leads
sample opportunities
sample quotations
sample approvals
sample notifications
Command:
"seed:uat": "node --experimental-strip-types src/db/seeds/uat.seed.ts"
3. PDF template seed
Template-only reseed:
"seed:pdf-template": "node --experimental-strip-types scripts/reseed-pdf-template-version.ts"
4. Verification scripts
Keep as verification, not seed:
"verify:encoding"
"verify:crm-access"
"verify:pdf"
New Standard Commands
Recommended package.json script structure:
{
"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:
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:
NODE_ENV must not be production
DATABASE_URL must not include production host/name
ALLOW_DB_RESET=true required
Example command:
ALLOW_DB_RESET=true npm run db:reset
Recommended 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:
"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
seed:super-admin
seed:foundation
Merge into:
seed:system
Rename
seed:crm-uat
to:
seed:uat
Rename
seed:pdf-template-version
to:
seed:pdf-template
Keep but mark legacy/dev fixture
seed:task-h1-fixture
verify:task-h1
verify:task-h3
Move under:
scripts/legacy/task-fixtures/
or rename:
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
migrate:membership-business-roles
If this was one-time historical migration, move to:
scripts/legacy/migrations/
and remove from common package scripts.
If still needed after reset, fold into migration or seed.
Keep
verify:crm-access
verify:encoding
audit:pdf:*
audit:pdf
These are still useful.
Replace
setup:db
with:
db:setup
db:setup:uat
db:fresh
db:fresh:uat
Scope 7: Bootstrap Documentation
Create:
docs/operations/system-bootstrap.md
Must explain:
Fresh local development
npm install
npm run db:fresh
npm exec tsc --noEmit
npm run dev
Fresh UAT/demo data
npm run db:fresh:uat
Existing database upgrade
npm run db:migrate
npm run seed:system
PDF template reseed only
npm run seed:pdf-template
Verification
npm exec tsc --noEmit
npm run build
npm run verify:encoding
npm run verify:crm-access
npm run audit:pdf
Script guide
Explain:
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:systemexistsseed:uatexistsdb:resetexists with safety guarddb:freshworksdb:fresh:uatworks- old scripts are classified or removed
- system bootstrap docs exist
Verification
Run:
npm exec tsc --noEmit
npm run build
npm run verify:encoding
Optional:
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_optionshas 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:
Foundation Admin UX = Improved
Master Option Management = Operational
System Bootstrap = Standardized
Database Reset = Safe and Repeatable
Script Surface = Clean and Understandable