Skip to content

2026-07-17 — XP-142 clone-academic-year drops COUNT wave

  • packages/service/src/academic-years/clone-academic-year.ts refactored: the 5 count(*) selects (old step 2) plus a conditional re-fetch of the 4 amount tables (old step 4) and a second subject_tingkat_applicability fetch (old step 10) collapse into a single 5-table Promise.all. Counts now come from .length. Net code deletion, one round-trip instead of three inside the money transaction.
  • Always fetch all 5 tables (empty tables return []) rather than the old count-then-maybe-fetch branching — simpler and one fewer round-trip; rowsCopied derived from .length is byte-identical to the old COUNT-derived values (source row counts, pre-bump).
  • Wrapped the rewritten reads in withQueryName(...) per service-conventions.md (they had been unwrapped); tx mutations left as-is (apply-when-touching, not a sweep).
  • The 0-row guard UNIT test in pricing/__tests__/pricing-guards.test.ts was implementation-coupled to the COUNT wave (its fake tx queued [{count:0}] per count select). The mock had to switch to returning row arrays (Array.from({length:n})) — same behavioural assertion, new fetch shape.
  • Empty-year guard reordered to run BEFORE the new-year INSERT (fetch → guard → create) so “reject empty before any write” is preserved.

None. Clone semantics per domain-academic-year.md unchanged (5 tables, +1yr shift, UPCOMING, level axis carried) — only round-trip count dropped. No new academic-year fixture (integration-test-shared-fixtures trap #2 respected).