Re coaching silver rate column exposure ask; Path A accepted; Coaching will promote rate JSON to typed columns and extend silver face
Schema correction first
Platform's memo assumes lesson_rate and travel_comp are already discrete flat columns on the Coach row. They are not. The Coaching schema currently stores rate data in one JSON column: rate_references (type Json?) with the canonical shape { "hourlyRate": number, "travelComp": number }. Both keys are optional inside the object; the column itself is nullable. An opaque_rate_references repair flag fires in the operator console when a row's JSON does not conform to this shape.
Path A accepted, via column promotion
Coaching accepts Path A. Rather than having Platform extract from JSON in the silver model, Coaching will promote the two rate keys to typed flat Decimal columns on the Coach table. This gives the silver face clean column references and makes the schema more honest about what Coaching owns.
Migration plan:
- Add
lesson_rate Decimal? @map("lesson_rate")andtravel_comp Decimal? @map("travel_comp")to the Coach Prisma model. - In the migration SQL, backfill from the existing JSON:
UPDATE coaching.coach SET lesson_rate = (rate_references->>'hourlyRate')::numeric, travel_comp = (rate_references->>'travelComp')::numeric WHERE rate_references IS NOT NULL. - Update the operator console write path to write both the new flat columns and keep
rate_referencesin sync during a dual-write window; once the silver face is confirmed stable,rate_referencescan be treated as deprecated on Coach. - Extend
coaching_coach.sqlto projectlesson_rateandtravel_compas flat silver columns.
The migration and silver extension are a single Coaching-internal deliverable. No cross-domain handshake is needed beyond this reply confirming the commitment.
Back-to-back threshold
Coaching declares 5 minutes as the contiguous-block threshold for travel_comp eligibility. Two lessons on the same coach on the same day are treated as a single contiguous block (travel_comp does not re-fire between them) when the gap between the first lesson's end_at and the second lesson's start_at is 5 minutes or less. Gaps of 6 minutes or more reset the block. This should be encoded in the mart registry note on coach_cost_per_hour and in the silver model's window-function comment.
Scope note on coach_revenue_share_pct
The existing JSON shape has no revenueSharePct key. coach_revenue_share_pct remains deferred per the 2026-05-19 corrections-accepted memo. This reply does not unblock that metric.
References
coaching/prisma/schema.prismamodel Coach, fieldrateReferences Json? @map("rate_references")coaching/modules/operator-console/actions.tsrateReferencesFromForm(canonical JSON shape at write time)coaching/modules/operator-console/repair.tsrepair flagopaque_rate_references2026-05-19-platform-mart-registry-coaching-corrections-accepted(coach_revenue_share_pct deferral)