Supersedes the flat per-module onboarding templates: milestoneTemplate(db, code)
now returns [...front, ...tail]. front is a shared setting
(project.milestone_template.front, FRONT_FALLBACK code default: enquiry ->
visit/meeting -> quotation sent -> quotation approved) prepended to every
module's checklist. tail resolves per-module setting -> global setting ->
TAIL_FALLBACK (the old generic list), unchanged in precedence.
- STEP_STATUS gains quotation_approved -> ordered (never-downgrade guard kept).
- seed.ts seeds the front once plus SMS/RTGS/MOBILEAPP tails (advance/balance
payment steps collapsed into a single payment_received tail step); no longer
seeds a bare project.milestone_template default.
- migrate-onboarding-templates.ts KEY_MAP updated so advance_paid, balance_paid,
advance_payment and balance_payment all carry forward to payment_received;
its idempotency check holds against the longer composed list.
- Updated seed-templates, milestones-templates, milestone-status,
migrate-onboarding-templates, milestones and milestone-payment tests to the
composed content/mappings (TDD: reverted the implementation, confirmed the
updated tests red, restored the implementation, confirmed green).
Backend + tests only; the live-DB migration run is a separate step.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add one test case to cover the scenario where old milestone keys that
don't map to the new template (amc_start, setup_done for SMS) are ticked
and should be counted in the migration's dropped tally. Verifies both
dropped and carried counts are accurate.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Idempotent migrateOnboardingTemplates(db): for every client_module whose module
has a per-module onboarding template (task 2), rebuilds its milestone rows from
that template, carrying mapped ticks (installed->installation, go_live->go_live,
advance_paid->advance_payment, balance_paid->balance_payment, setup_done->
setup_configuration when present) with done_on and payment_id intact. Unmapped
ticks (amc_start, or setup_done where the new template has no matching step) are
dropped and counted. Audited per project; a second run is a no-op via an
identical-key-set short-circuit. Adds the CLI wrapper (mirrors
apply-name-fixes.ts's open-DB idiom, Postgres or SQLite) for the real one-time
run against production data.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>