Files
alla-allaos-fullstack/plans/task-fix-display.md
2026-06-27 22:14:16 +07:00

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

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
    • email
    • ID as last resort

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.


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_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:

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 + 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.

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"

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: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:

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_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:

Foundation Admin UX = Improved
Master Option Management = Operational
System Bootstrap = Standardized
Database Reset = Safe and Repeatable
Script Surface = Clean and Understandable