2026-07-17 — XP-139 pricing read-path wave hoist
What shipped
Section titled “What shipped”packages/service/src/pricing/list-price-change-batches.ts— the 5 human-label lookups (academicYears / segmentasi / tingkat / subjects / golongan) hoisted out of the old trailing wave into wave 1 as a nestedPromise.allbesiderowsByTable; the id→labelMapbuild moved up with them. Independent-blocking waves 3 → 2.auditByTable(needs batched row ids) stays wave 2.packages/service/src/pricing/freeze-sesi-pricing.ts— the conditional tutor-golongan read now rides wave 1 (session.golongan_id ? Promise.resolve(null) : read) alongsideresolveStudentPrice+ the 4 label reads; onlyresolveTutorPrice(the sole golongan-dependent read) stays gated as a micro wave 2.
Key decisions
Section titled “Key decisions”- Behavior-preserving reorder only, zero logic/formula/column-set change — freeze/list output byte-identical, guarded by the existing money + pricing integration suites (583 integration tests green). No new tests per YAGNI.
- Common-path trade-off: when
session.golongan_idIS set,resolveTutorPricenow defers to micro-wave 2 rather than running concurrently — implemented exactly as the perf-sweep ticket prescribed; the real win is the null-session-golongan branch.
Gotchas / lessons
Section titled “Gotchas / lessons”freeze-sesi-pricing.tssits on the money-freeze/snapshot path (domain-pricing-snapshot.md). Confirmed scheduling-only:frozenPriceColumns,buildUnpricedCell, resolve call args, andarchived_axesderivation all untouched; unpriced-tutor (null golongan → no throw) semantics preserved. TS narrowsgolonganIdtostringinside the truthy ternary, so the oldas stringcast onresolveTutorPricedropped — net readability gain.
Reference changes
Section titled “Reference changes”None. No canonical doc (plans/ARCHITECTURE.md, plans/scope/*.md, .claude/rules/*.md) changed.