Commit Graph

5 Commits (b146de990f54a31e2c8c0b38a0e89966258877da)

Author SHA1 Message Date
Thomas Joise 4ee8f17b37 fix(onboarding-migration): preserve ad-hoc custom steps across the template swap
Final whole-branch review FIX 3.

migrateOnboardingTemplates previously DELETEd every project_milestone row and
reinserted only template keys, so a project-specific step added via
addProjectMilestone ("+ Add step", custom_* keys) vanished with no trace if
un-ticked, or was miscounted as `dropped` if ticked.

Old rows are now partitioned before the DELETE into template-mapped vs
ad-hoc custom (not a template key, not in KEY_MAP, and not a known old
generic FRONT_FALLBACK/TAIL_FALLBACK key like amc_start — those keep their
existing drop behavior). Custom rows are re-inserted unchanged after the
template block, sort continuing past it, preserving
label/done/done_on/payment_id/document_id. The return type and the audit
`after` payload both gained a `preserved` count/list.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 day ago
Thomas Joise 7838ced6c2 feat(client-detail): quotation-step document link + ticket classification (backend)
Backend half of the Client Detail redesign follow-ups (#7, #6, #4).

#7 — quotation step links its document
- project_milestone gains a nullable `document_id`, landed on BOTH engines:
  a PRAGMA-guarded ALTER in db.ts migrate() and pg migration 016.
- setMilestone(..., doneOn?, paymentId?, documentId?) validates the document
  belongs to the same client as the project (mirroring the paymentId check),
  stores it on tick and clears it on untick; Milestone gains `documentId`.
- POST /client-modules/:id/milestones accepts `documentId`.
- migrateOnboardingTemplates carries document_id across the template swap so a
  linked quotation is not lost.

#6 — ticket classification
- ticket gains `type TEXT NOT NULL DEFAULT 'service'` (db.ts SCHEMA + guarded
  ALTER, pg migration 017); imported APEX rows fall to the default.
- Config over code: the list is the `ticket.types` setting (seeded on first
  boot) resolved by ticketTypes(), with TICKET_TYPE_FALLBACK in code.
- GET /tickets/types; create/update accept + validate `type`; list rows carry
  it and GET /tickets?type= filters (blank/omitted = every type).

#4 — cleanup
- Refreshed the stale file comment atop repos-milestones.ts and the
  project_milestone comment in db.ts: both now describe the composed
  front + per-module tail model (they still described the old flat template).
- Migration tests for the interim keys advance_payment / balance_payment ->
  payment_received, plus the document-link carry.

npm run typecheck clean; npm test 473 passed / 5 skipped (was 453/5).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 day ago
Thomas Joise f1a7eac9dd feat(onboarding): composed milestone templates (shared front + per-module tail)
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>
2 days ago
Thomas Joise 4b2e44c3ea test(onboarding-migration): add coverage for dropped ticked milestone keys
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>
2 days ago
Thomas Joise 6bce248c2e feat(onboarding): one-time migration swapping seeded modules to new templates (ticks preserved)
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>
2 days ago