Caregiver Matching Assignment Gap Mining
Caregiver Matching Assignment Gap Mining
Section titled “Caregiver Matching Assignment Gap Mining”Scope: source-mining continuation only. Legacy source-refs/ code is behavior
evidence, not implementation code to copy. This page stays separate from
source-feature-checklist.md and caregiver-settlement-gap-mining.md; it is
merge-ready evidence for caregiver matching, assignment, multi-caregiver
contract, caregiver grade, and wage settlement migration gaps.
Ubiquitous Names
Section titled “Ubiquitous Names”Use these modern names when migrating the source behavior:
CaregiverMatchingProfile: mother preference, pet, personality, and free-text matching inputs.CaregiverCandidateSnapshot: ranked caregiver card with score, branch scope, grade, distance, transport evidence, profile text, and exclusion facts.RequestedCaregiverSelection: mother-selected named caregiver path requiring branch consultation and service-grade uplift.CaregiverAssignmentDecision: branch/HQ final selected caregiver, candidate evidence shown at decision time, actor, reason, and policy version.CareTeamContract: one reservation care team with primary caregiver, ordered assistant caregiver member terms, provider-count basis, service period, and contract document projection.CaregiverAssignmentTerm: date-bounded caregiver assignment, role, handoff order, grade snapshot, and replacement link.CaregiverGradeSnapshot: grade code and score basis frozen when used for matching, assignment, quote, or payout.CaregiverWageQuoteLine: calculated wage basis by assignment key, role, tax policy, service days, options, and overrides.CaregiverPayoutInstruction: frozen payable instruction with amount, tax, bank account reference, memo, and payout status.CaregiverPayoutAcknowledgement: branch deposit and caregiver receipt state, separated from reservation status.
flowchart LR MotherInputs[CaregiverMatchingProfile] --> Candidate[CaregiverCandidateSnapshot] Requested[RequestedCaregiverSelection] --> Policy[RequestedCaregiverPolicyDecision] Candidate --> Decision[CaregiverAssignmentDecision] Candidate --> Conflict[CaregiverAssignmentConflictPolicy] Conflict --> Decision Policy --> Decision Decision --> Team[CareTeamContract] Team --> Term[CaregiverAssignmentTerm] Term --> Grade[CaregiverGradeSnapshot] Grade --> GradeHistory[CaregiverGradeRecalculationHistory] Term --> Wage[CaregiverWageQuoteLine] Wage --> Payout[CaregiverPayoutInstruction] Payout --> Ack[CaregiverPayoutAcknowledgement] Team --> Docs[CareTeamDocumentProjection]
Source Evidence
Section titled “Source Evidence”Smart-Matching Intake And Recommendation
Section titled “Smart-Matching Intake And Recommendation”- Customer smart-matching step 1 persists religion, pet information,
pet-together flag, and ranked preferences, then advances process state.
Evidence:
source-refs/sanmopia_web/application/controllers/api/Service.php:576-640. - Customer smart-matching step 2 deletes and rewrites caregiver personality
answers plus free-text preference memo. Evidence:
source-refs/sanmopia_web/application/controllers/api/Service.php:643-670. - Customer apply/check-data chooses recommendation grades by service detail:
special/live-in allows special or premium, premium allows premium, else all
grades; it asks
Manager_matching_model::getRecommendManagerWithDueTime(...)for five branch-scoped candidates. Evidence:source-refs/sanmopia_web/application/controllers/Service.php:594-623. - Customer recommendation screen explicitly says recommended caregivers are not
directly selected by the customer, and final caregiver is confirmed two days
before service. Evidence:
source-refs/sanmopia_web/application/views/service/reservation_check_data.php:33-56,source-refs/sanmopia_web/application/views/service/reservation_check_data.php:150-205. - Legacy survey screen still exposes a named caregiver search; choosing one
posts
reservation[manager_no], while the page warns that selecting a named caregiver automatically applies one service-grade uplift. Evidence:source-refs/sanmopia_web/application/views/survey/a19.php:27-107,source-refs/sanmopia_web/application/views/survey/a19.php:146-190.
Modern gap: split customer-visible CaregiverCandidateSnapshot from final
CaregiverAssignmentDecision. A recommendation card is a provisional customer
display artifact. It cannot become a final assignment without branch actor,
availability proof, selected-caregiver policy proof, and service-date proof.
Candidate Ranking And Assignment Detail
Section titled “Candidate Ranking And Assignment Detail”- Web
Manager_matching_model::getRecommendManagerByReservationId()ranks by preference plus personality score, requires active/non-deleted preference rows, checksMANAGER_SCHEDULE_CHECK_FN(...), filters branch and grade, uses random tie seed by user id, then sorts by distance when coordinates exist. Evidence:source-refs/sanmopia_web/application/models/Manager_matching_model.php:166-228,source-refs/sanmopia_web/application/models/Manager_matching_model.php:248-307. - Admin
Matching_model::getRecommendManagerByReservationId()does similar ranking and additionally excludes pet-allergy caregivers when reservation pet info exists. Evidence:source-refs/sanmopia-admin/application/models/Matching_model.php:44-124. - Admin
Matching_model::getRecommendManagerWithDueTime()loads cached transport times, calculates missing times viaodsaylib, but the DB replace is commented out and final ordering currently uses score, not transport time. Evidence:source-refs/sanmopia-admin/application/models/Matching_model.php:724-862. - Admin candidate detail modal reads selected reservation id, caregiver id,
displayed score, matching info, preference answer matching, distance, and
cached transport time. Evidence:
source-refs/sanmopia-admin/application/controllers/ajax/Reservation.php:31-65. - Admin search path rebuilds candidate filters from reservation service detail,
branch, search string, and date window. Evidence:
source-refs/sanmopia-admin/application/controllers/Reservation.php:538-577. - Admin ranking still uses random tie ordering and score-first ordering while
transport-time persistence is incomplete. Evidence:
source-refs/sanmopia-admin/application/models/Matching_model.php:752-862. Migration must make tie-breaker seed, distance, transport provider, and score-vs-travel priority explicit policy inputs instead of hidden SQL ordering.
Progress 2026-07-04: backend now has
sanmopia_caregiver_candidate_snapshots plus
SupabaseCaregiverCandidateSnapshotRepository, so score components, distance,
transport provider result, fallback reason, pet exclusion, schedule check,
grade filter, branch scope, source request key, and ranking policy version are
persisted as frozen evidence. Later assignment detail can now read this
snapshot instead of mutable caregiver profile rows.
Improvement note: transport evidence is mixed into a function named for due
time, but source ranking still sorts by score. Modern optimizer inputs should
store both transportDurationMinutes and rankingPolicyVersion, then make
score-vs-transport priority explicit.
Final Assignment And Change History
Section titled “Final Assignment And Change History”- Admin reservation detail loads five matching candidates and matching
preferences for the reservation detail screen. Evidence:
source-refs/sanmopia-admin/application/controllers/Reservation.php:330-360. Reservation::saveReservationData()saves broad reservation edits in one action, including main caregiver id, assistant caregiver ids, service dates, payment dates, address coordinates, add-days, and baby details. Evidence:source-refs/sanmopia-admin/application/controllers/Reservation.php:650-875.Reservation_model::saveReservationManager()marks other-area assignments when caregiver branch differs, logs main caregiver replacement, and mutatesRESERVATION_TB.MANAGER_ID_FK. Evidence:source-refs/sanmopia-admin/application/models/Reservation_model.php:2170-2222.ajax/Reservation::manager_history()reads separate main and sub-caregiver log tables, withSORTfor assistant slots. Evidence:source-refs/sanmopia-admin/application/controllers/ajax/Reservation.php:180-209.
Modern gap: CaregiverAssignmentDecision needs command-specific writes instead
of one broad reservation-save action. Assignment should emit decision id,
actor, selected candidate snapshot id, assignment reason, source rerun id,
branch scope, other-area flag, replacement chain, and impacted payout/contract
effects. Current backend collaboration path now applies
caregiver_assignment.roster into
sanmopia_reservation_caregiver_assignments, keyed by
contract_assignment_key and preserving role, handoff order, grade, planned
service days, term dates, and assigned Supabase user id. Assignment conflict
policy now blocks explicit unavailable-window, overlap, and replacement
continuity violations before final assignment. assignment_optimizer_inputs
now prepares travel freshness, fairness/rotation workload, replacement
continuity, assistant slot order, and same-caregiver cross-slot exclusion as
backend-owned facts instead of UI arithmetic. Candidate snapshot Supabase
persistence is now present. Remaining gap is durable assignment-decision source
exposure, OR-Tools adapter/API ingestion, and generated OpenAPI/TypeScript/
frontend conflict UX. Next backend slice: assignment command accepts
candidateSnapshotId, expected revision, idempotency key, and reason; loads
CaregiverCandidateSnapshotRepository.find_by_snapshot_id(); rejects missing,
stale, or caregiver-mismatched snapshots; and copies frozen score components,
branch scope, grade, distance, transport duration, matching request key, and
ranking policy version into CaregiverCandidateEvidence without rereading
mutable caregiver profile rows. Legacy "0점" must become explicit zero-score
override evidence, not null recomputation.
Additional source-mined optimizer evidence:
Reservation_manager_trans_info_model.php:13-87owns the real travel-time cache write path: missing cache calls ODSAY and storesTIME, while the matching list can still fall back toODSAY_MAX_TIME.Reservation.php:538-577maps service detail strings to manager classes (GENERAL,SPECIAL,PREMIUM) during modal search. This must become server-owned class eligibility, not UI/search endpoint branching.Reservation_model.php:2166-2303writes primary assignment, other-area flag, primary replacement log, assistantSORT, assistant replacement log, and assistant deletion side effects.reservation_detail.js:586-629blocks duplicate primary/sub caregiver picks only in the browser. Backend optimizer and assignment command validation must enforce uniqueness across all primary/assistant slots.- Hidden source constants still needing abstraction: candidate limit
5,RAND(userId)/RAND(reservationId)seed behavior,"0점"score sentinel,greenUI marker, earth radius6371,ODSAY_MAX_TIME, and Korean service-detail/baby-count strings such as바우처,스페셜,입주,프리미엄,쌍둥이,삼둥이,사태아,셋째아 이상, and넷째아 이상.
Multi-Caregiver Contract
Section titled “Multi-Caregiver Contract”- Admin reservation detail treats voucher twins/triplets/quadruplets and
DELIVERY_COUNTas the source of provider count. The UI shows fixed “다태아 제공인력 선택” radio buttons and computes sub-caregiver count from셋째아 이상,넷째아 이상, and넷째아 이상(관리사4명). Evidence:source-refs/sanmopia-admin/application/views/reservation_status/reservation_detail.php:45-60,source-refs/sanmopia-admin/application/views/reservation_status/reservation_detail.php:840-861. - Main caregiver label changes to “선임 관리사” when a multi-caregiver voucher
case exists; assistant slots render as “담당 관리사 A/B/…” with change
history buttons and
fsenior-manager-name[i]fields. Evidence:source-refs/sanmopia-admin/application/views/reservation_status/reservation_detail.php:1145-1188. Reservation_model::saveReservationSubManager()stores assistant caregivers inRESERVATION_SUB_MANAGER_TBbySORT, logs replacements inRESERVATION_SUB_MANAGER_LOG_TB, and deletes linked sub payment/salary rows when clearing a slot. Evidence:source-refs/sanmopia-admin/application/models/Reservation_model.php:2224-2303.- Customer mypage concatenates selected primary and sub-caregiver names in the
caregiver header, renders cards for each assigned caregiver, creates
sub-caregiver report data, and exposes separate sub-caregiver bank account
info for direct service-balance payment. Evidence:
source-refs/sanmopia_web/application/controllers/MyReservation.php:120-144,source-refs/sanmopia_web/application/views/mypage/reservation_detail.php:260-380,source-refs/sanmopia_web/application/views/mypage/reservation_detail.php:470-568. - Contract/export code writes provider count and main/sub caregiver names into
voucher documents and export forms. Evidence:
source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:872-930,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:3528-3650.
Modern migration: CareTeamContract now has backend domain/application and
TS-client contract foundations for one ordered roster, not source-specific
main/sub tables. It validates exactly one primary caregiver, unlimited ordered
assistant member terms, assignment-key uniqueness, handoff-order uniqueness,
effective windows, provider-count basis, grade snapshot reference, and document
member projection. Remaining work is Supabase persistence/API binding,
document-template integration, report obligation binding, account references,
and payout terms that all share the stable assignment keys.
Improvement note: clearing a sub-caregiver slot in source filters linked delete
queries by the posted empty $subManagerId, not clearly by the previous slot
caregiver. Migration should model explicit RemoveAssistantCaregiver with
slot id, previous assignment key, and expected current caregiver.
Caregiver Grade And Score
Section titled “Caregiver Grade And Score”- Manager detail reads manual class code, Korean class label, legacy
GRADE_SCORE, star score, branch/headquarters score fields, and additive grade score fromGET_MANAGER_GRADE_SCORE_FN(...). Evidence:source-refs/sanmopia-admin/application/models/Manager_model.php:115-152. - Manager list computes display grade score as
GRADE_SCORE + ADD_SCOREfor old caregivers, but onlyADD_SCOREfor new caregivers. Evidence:source-refs/sanmopia-admin/application/models/Manager_model.php:677-725. - Grade class is mutable through
Manager_model::updateClass()and read fromMANAGER_CLASS_TB. Evidence:source-refs/sanmopia-admin/application/models/Manager_model.php:1618-1630,source-refs/sanmopia-admin/application/models/Manager_model.php:2182-2192. - Admin manager detail screen separately edits HQ score, branch score, and
grade class. Evidence:
source-refs/sanmopia-admin/application/views/manager/manager_detail.php:400-470. - Evaluation aggregation caps each score item by max score and intends to cap
combined career/other-working score, but the final cap mutates the local
$rowvariable rather than writing back to$result[$managerId]. Evidence:source-refs/sanmopia-admin/application/models/Manager_evaluation_model.php:641-724. - Ajax score-detail rendering recalculates capped score history in the
controller before returning table rows. Evidence:
source-refs/sanmopia-admin/application/controllers/ajax/ManagerEvaluation.php:146-228. Migration must expose backend-ownedCaregiverPerformanceScorecardentries with original score, capped score, before/after totals, score-type cap, and policy version so UI never recomputes grade history.
Modern gap: CaregiverGradeSnapshot should freeze grade code, grade label,
manual override, scorecard id, score components, old/new caregiver rule, and
policy version at the moment a grade is used for matching, contract, or wage.
Backend now persists recalculation history and exposes API/HTTP reads for
operator audit. 2026-07-07 follow-up: backend commit baa1a1a adds
CaregiverProfileScoreRevisionPolicy and
PlanCaregiverProfileScoreRevisionPayload so profile-save branch/HQ score
clamps and old/new caregiver grade-score basis are backend-owned. Source
GRADE_SCORE, ADD_SCORE, OLD_MANAGER_FL, manager_score_branch, and
manager_score_danbee are rejected at the contract boundary. Remaining gap is
scheduled recalculation execution, mismatch warning UX, class-change command
audit, and tying history entries to every grade snapshot used by assignment or
payout.
Improvement note: move score aggregation into a tested
CaregiverPerformanceScorecard policy. Do not let mutable MANAGER_CLASS_CD_FK
silently change already-issued recommendations, contracts, or payout quotes.
Ubiquitous naming now separates CaregiverPerformanceScorecard capped rows from
CaregiverPerformanceSeasonScorecard published season snapshots and
CareDeliveryPerformanceScorecard care-delivery earned points, so later matching
and payout code does not bind to the wrong scorecard concept.
2026-07-05 Explorer A Delta
Section titled “2026-07-05 Explorer A Delta”| Priority | Status | Modern ubiquitous name | Hidden source evidence | Feature gap |
|---|---|---|---|---|
| P0 | Partial | CaregiverPerformanceSeasonScorecard | source-refs/sanmopia-admin/application/controllers/cli/Manager.php:22-120, source-refs/sanmopia-admin/application/controllers/cli/Manager.php:123-237 | Legacy daily cron grants score rows from PHP and DB-trigger sources, then auto-adjusts caregiver class from current score thresholds while skipping premium caregivers. Modern scorecard recalculation still needs scheduled execution, class-adjustment proposal/audit, premium-exclusion reason, mismatch warning rows, and idempotent rerun control. |
| P1 | Pending | CaregiverAwardScoreboard | source-refs/sanmopia-admin/application/controllers/cli/Cache.php:12-33, source-refs/sanmopia-admin/application/models/Win_the_race_model.php:163-315, source-refs/sanmopia-admin/application/models/Win_the_race_model.php:318-441, source-refs/sanmopia-manager/application/models/Win_the_race_model.php:28-57, source-refs/sanmopia-manager/application/models/Win_the_race_model.php:87-110, source-refs/sanmopia-manager/application/views/winTheRace/index.php:158-260 | ”Win the Race” is a yearly caregiver award scoreboard, not normal matching grade. It caches per-year rankings in Redis, uses work score, rating score, and referral score, gives tie ranks, exposes caregiver-facing rank/points/award rules, and keeps prior-year cache for about one year. Modern backend needs a published award-season projection with cache/version metadata, tie policy, award bands, referral-settlement eligibility, and caregiver-visible read model. |
Wage Settlement And Payout State
Section titled “Wage Settlement And Payout State”- Caregiver app pay list includes only completed or settlement reservations,
covers both primary and sub caregivers, then calculates salary at read time.
Evidence:
source-refs/sanmopia-manager/application/models/Reservation_model.php:13-82,source-refs/sanmopia-manager/application/controllers/Other.php:223-294. calcSalary(...)identifies primary vs sub caregiver, reads main/sub payment info, tax type, voucher add price, service-balance overrides, Saturday/holiday additions, custom main pay, custom sub pay, and returns display lines without freezing them. Evidence:source-refs/sanmopia-manager/application/helpers/salary_helper.php:8-227.- Caregiver pay detail displays base pay, after-tax base pay, voucher add pay,
option pay, total pay, final pay, and memo. Evidence:
source-refs/sanmopia-manager/application/views/pay_info_detail.php:167-263. - Admin salary tax/memo persistence only stores reservation id, caregiver id,
TAX_TYPE,MEMO, and update date; missing rows default tax type to four insurance and memo to blank for primary plus sub caregivers. Evidence:source-refs/sanmopia-admin/application/models/Reservation_manager_salary_model.php:21-52,source-refs/sanmopia-admin/application/models/Reservation_manager_salary_model.php:112-180. - Tax constants define four insurance, 3.3% income tax, and the 0.033 tax rate.
Evidence:
source-refs/sanmopia-admin/application/config/constants.php:272-274,source-refs/sanmopia-manager/application/config/constants.php:144-152. - Admin salary completion changes main payment rows or sub payment rows, stamps
deposit dates, can insert missing payment rows as a fallback, and auto-moves
reservation to done when salary and service-balance flags are complete.
Evidence:
source-refs/sanmopia-admin/application/controllers/Manager.php:986-1027,source-refs/sanmopia-admin/application/controllers/Manager.php:1300-1335,source-refs/sanmopia-admin/application/models/Reservation_model.php:2945-3146. - Caregiver app service-balance confirmation has separate primary and
sub-caregiver acknowledgement paths. Evidence:
source-refs/sanmopia-manager/application/models/Reservation_model.php:352-410,source-refs/sanmopia-manager/application/views/schedule/schedule_info.php:130-175. - The manager portal acknowledgement is a raw
PUT /reservation/dataswitch: JavaScript poststype=paymentortype=sub_paymentplusservice_type, the controller dispatches on the string, and the model stamps type-3 customer payment rows plus branch-manager payment flags. The sub-caregiver path updatesSUB_PAYMENT_STATUS_ID_FKby reservation id only, so modern acknowledgement must require assignment key/current roster revision instead of reservation-id-only mutation. Evidence:source-refs/sanmopia-manager/static/js/schedule/schedule_info.js:1-95,source-refs/sanmopia-manager/application/controllers/Reservation.php:6-77,source-refs/sanmopia-manager/application/models/Reservation_model.php:247-270,source-refs/sanmopia-manager/application/models/Reservation_model.php:351-411.
Modern migration: CaregiverCompensationQuoteLine and
CaregiverPayoutInstruction freeze amount basis before caregiver display.
CareTeamContract can now feed compensation quote seeds directly, so ordered
care-team member terms become backend-owned quote lines by assignment key,
role, handoff order, grade, planned days, rate rule, tax terms, and explicit
override inputs. Bank-account edit proof now persists as
CaregiverPayoutDestinationChangeAudit; remaining work is API/auth/runtime
binding for manager, branch, and HQ screens plus richer tax formula
explainability.
Improvement note: source salary completion can create missing payment rows at button click time. Modern code should create payout instructions idempotently when settlement enters payout-ready state, then block completion if required instructions or acknowledgements are missing.
Missing Migration Checklist
Section titled “Missing Migration Checklist”- Add
CaregiverMatchingProfileintake events for pet, religion, preference ranking, personality answers, and free-text memo. - Add backend
CaregiverCandidateSnapshotandMatchingOptimizationInputfoundation with score, grade, branch, pet exclusion, schedule conflict, distance, transport, deterministic tie-breaker facts, and ranking-policy evidence. Profile preference answers now exportMatchingProfileCompatibilityInput, so profile compatibility signals are not confused with reservation-level optimizer inputs. Backend assignment-decision foundation now stores selected candidate snapshot id and evidence references; durable candidate snapshot persistence and recommendation-set persistence now freeze per-candidate evidence plus operator-visible ordered result sets. Profile-text projection, API/client exposure, and assignment-decision binding remain open. - Add
CaregiverCandidateOrderingPolicyparity foundation for legacy score, distance, and transit ordering. Backend commit05832cdmakesCaregiverCandidateOrderingPolicythe canonical domain name while keepingCandidateRankingPolicyas a compatibility alias. The policy freezes score, distance, travel-duration, deterministic tie-breaker component order, source evidence keys, and the replacement for sourceRAND(userId)/RAND(reservationId)ties. Source paths still limit candidate count after score ordering, then distance-sort in one path while due-time matching computes transit but can still score-sort; backend commitf07313baddsCaregiverCandidateRecommendationSetpersistence for reservation revision, service dates, branch/class/search scope, candidate limit, optimization input, optimization decision, ranked/excluded counts, and full snapshot payloads. Remaining runtime work must add travel freshness/failure policy, remove raw SQL search/date interpolation, and bind assignment API/UI to ordered recommendation sets. Persistent-worker evidence:source-refs/sanmopia-admin/application/models/Matching_model.php:44-124,source-refs/sanmopia-admin/application/models/Matching_model.php:724-862, andsource-refs/sanmopia-admin/application/models/Reservation_manager_trans_info_model.php:13-87show pet exclusion, candidate limit, random tie seeds, branch/class filters, ODSAY fallback, cache replacement, and score-first ordering all need explicit policy fixtures and snapshot fields. - Add
CaregiverMatchingPolicyfor grade/class eligibility and ranking chain. Status:Partial. Evidence:source-refs/sanmopia_web/application/controllers/api/Service.php:576-640,source-refs/sanmopia-admin/application/controllers/Reservation.php:538-577,source-refs/sanmopia_web/application/models/Manager_matching_model.php:166-228,source-refs/sanmopia-admin/application/models/Matching_model.php:44-124. Source behavior: service detail strings and age tiers decide class filters (바우처,입주,스페셜,프리미엄,쌍둥이/셋째아 이상/넷째아 이상) in query paths and ranking keeps score-first logic while transport is advisory. Modern migration now moves this into backend-ownedCaregiverServiceProfile,CaregiverClassEligibilityPolicy,CaregiverClassEligibilityRule,CaregiverClassEligibilityDecision, andCaregiverMatchingPolicywith source-parity policy versionsource_caregiver_matching_v1. The TS contract exposes the same policy shape throughpackages/ts-client/src/types/caregiver-matching.tsso UI cannot branch on raw Korean service-detail strings. Supabase now persists policy versions insanmopia_caregiver_matching_policiesand class eligibility rules insanmopia_caregiver_class_eligibility_rules, with generated DB types and a source-parity seed for the legacy score/distance/transport policy. Backend now exposesGET /caregiver-matching-policies/activeand the TS contract validates the active policy response pluseffectiveOnquery path so UI and optimizer clients consume the same Supabase-backed policy snapshot. Remaining work: operator policy editor, OR-Tools adapter ingestion, and assignment command binding. - Add
RequestedCaregiverSelectionandRequestedCaregiverPolicyDecisionfoundation for named caregiver search, service-grade uplift, consultation-required uncertainty, and hard rejection. Backend domain reusesCaregiverMatchingPolicy.candidate_fit_forinstead of duplicating grade/availability/segment/day/branch checks, and contract payloads exposedecision_code, blocking codes, consultation reasons, andaccepted_for_assignment. - Add backend
CaregiverAssignmentDecisionfoundation for branch/HQ final assignment with actor, source candidate snapshot, reason, audit evidence, and replacement link. Append-only persistence, authenticated branch/HQ command API, current-roster/history reads, broad-save rejection, and downstream invalidation now exist. Caregiver-owned accept/reject is implemented on the P06 readiness branches; strict phase acceptance still needs a live actor run and retained media packet. - Add backend
CaregiverAvailabilityWindowandCaregiverAssignmentConflictfoundation with explicit unavailable and overlapping-assignment reason codes before final assignment. - Add
CareTeamContractwith provider count basis, primary caregiver, ordered assistant member terms, role labels, handoff order, grade snapshot reference, effective windows, and document projection. Backend domain/application models and TS-client validators now reject duplicate assignment keys, duplicate handoff orders, missing primary caregiver, and overlapping same-caregiver terms without imposing a hard provider limit. - Add backend
CaregiverAssignmentTermreplacement-continuity and slot invalidation foundation so primary/assistant replacements target stable assignment keys without source slot naming leaking into the domain. - Add
CaregiverGradeSnapshot, recalculation history linkage, and tested scorecard policy before using grade in matching, assignment, quote, or payout. Backend scorecard cap projection now exists underbackend-repo/src/sanmopia_modernization/domain/caregiver_performance_recognition/features/caregiver_scorecard/and application read models expose capped rows without UI recomputation. The published season contract now usesCaregiverPerformanceSeasonScorecard, while grade recalculation inputs useCareDeliveryPerformanceScorecard. Backend profile-score revision foundation now clamps branch/HQ submitted scores, freezes configured max-score evidence, freezes old/new caregiver additive grade basis, rejects source score fields, and emits matching/payout invalidation flags. Backend evaluation ledger foundation now sorts score rows byapplied_onthenfact_code, preserves original-vs-capped score evidence, exposes before/after cumulative totals, rejects legacy ajax display fields, and keeps monthly-career plus other-working under one combined cap without UI recomputation. Remaining work: persist score-revision audit rows and capped ledger rows, add class-change command audit, and connect grade snapshots to matching, assignment, quote, and payout reads. - Add
CaregiverCompensationQuoteLineandCaregiverPayoutInstructionso caregiver pay pages never recalculate from mutable reservation rows. Backend quote/payout/read-model foundations exist, andQuoteCareTeamCaregiverCompensationCommandnow quotes directly fromCareTeamContractmember terms without the legacy reservation-assignment aggregate.SupabaseCareTeamCompensationSourceReadernow reads accepted rows fromsanmopia_reservation_caregiver_assignmentsas ordered, compensation-ready care-team facts, rejecting missing grade or non-integral planned-day data instead of allowing UI fallback math. The authenticatedCareTeamCompensationSourceApiand/care-team-compensation-sources/{reservationBookingId}HTTP route now build the reader from the caller access token so Supabase RLS remains caller-scoped instead of service-role scoped. Runtime composition now wires the route intobuild_sanmopia_backend_app_from_env()and prefersSUPABASE_PUBLISHABLE_KEY/SUPABASE_ANON_KEYfor caller-JWT Data API reads when present. Remaining work: generated OpenAPI/client exposure and manager/branch/HQ operational screens. - Add
CaregiverPayoutAcknowledgementfor branch deposit and caregiver receipt, including main/sub role and reservation completion continuation. Evidence:source-refs/sanmopia-manager/application/helpers/salary_helper.php:8-227andsource-refs/sanmopia-manager/application/views/pay_info_detail.php:167-263. Source behavior: manager pay display is calculated from current reservation rows, role/sort, custom pay overrides, service-balance overrides, voucher pure add-ons, Saturday/holiday option labels, tax election, and the 2022-03-29 tax/add-on cutover. Modern gap: payout acknowledgement must reference immutableCaregiverPayoutInstructionandCaregiverCompensationQuoterows, not rerun salary helper math at read time. - Add regression tests for transport ranking policy, assistant slot removal, grade cap behavior, named-caregiver service uplift, multi-caregiver document names, and payout instruction idempotency.
2026-07-07 Crew Mining: Matching Runtime Gaps
Section titled “2026-07-07 Crew Mining: Matching Runtime Gaps”| feature_id | lane_owner | source_evidence | ddd_aggregate | command_query | persistence | contract | e2e_proof | status |
|---|---|---|---|---|---|---|---|---|
SFC-20260707-MATCH-001 | backend | source-refs/sanmopia-admin/application/models/Matching_model.php:44-124, :144-173, :724-862; source-refs/sanmopia-admin/application/controllers/Reservation.php:542-577 | caregiver_assignment / CaregiverCandidateRecommendationSet | FindCaregiverCandidateRecommendationsQuery | sanmopia_caregiver_candidate_recommendation_sets exists; runtime search writer missing | CaregiverCandidateRecommendationSetPayload | none | foundation |
SFC-20260707-MATCH-002 | backend | source-refs/sanmopia-admin/application/models/Reservation_manager_trans_info_model.php:13-87; source-refs/sanmopia-admin/application/models/Matching_model.php:782-834 | caregiver_assignment / CaregiverTravelEvidenceSnapshot, TravelEvidenceFreshnessPolicy | RefreshCaregiverTravelEvidenceCommand pending | Backend foundation: a93332b; sanmopia_caregiver_travel_evidence_snapshots exists; runtime provider writer missing | CaregiverTravelEvidenceSnapshotPayload, TravelEvidenceFreshnessPolicyPayload | none | foundation |
SFC-20260707-MATCH-003 | backend | source-refs/sanmopia-admin/application/controllers/Reservation.php:332-360, :542-577; source-refs/sanmopia-admin/application/models/Matching_model.php:101-118, :743-753 | caregiver_assignment / CaregiverClassEligibilityDecision | ResolveCaregiverClassEligibilityQuery | policy foundation only | CaregiverMatchingPolicyPayload | none | foundation |
SFC-20260707-MATCH-004 | backend | source-refs/sanmopia-admin/application/models/Matching_model.php:50-78, :126-140, :232-288, :724-758; source-refs/sanmopia-admin/application/models/Manager_model.php:2038-2088, :2146-2180; source-refs/sanmopia-admin/application/controllers/Reservation.php:650-681, :834-875; source-refs/sanmopia-admin/application/models/Reservation_model.php:2165-2222, :2224-2303 | caregiver_assignment / CaregiverScheduleProof, CaregiverScheduleConflictPolicy, CaregiverAvailabilityWindowRevision | CheckCaregiverAssignmentConflictQuery; RecordCaregiverAvailabilityWindowCommand pending | Backend foundation: 66f6afa; Supabase persistence: 251ab72; sanmopia_caregiver_schedule_proofs exists | CaregiverScheduleProofPayload, CaregiverScheduleConflictPolicyPayload | none | runtime_wired |
SFC-20260707-MATCH-005 | backend | source-refs/sanmopia-admin/application/models/Reservation_model.php:2165-2222, :2224-2303; source-refs/sanmopia-admin/application/models/Reservation_model.php:57-115 | caregiver_assignment / CaregiverAssignmentDecision, CareTeamAssignmentHistoryReadModel, CareTeamCurrentRosterReadModel | AssignCaregiverFromCandidateSnapshotCommand; GetCareTeamAssignmentHistoryQuery; GetCareTeamCurrentRosterQuery; GET /care-team-assignment-histories/{reservationBookingId}; GET /care-team-current-rosters/{reservationBookingId}; POST /care-team-assignment-decisions/assign-from-candidate-snapshot | Backend foundation: 1258920; Supabase persistence: fc90660; Command binding: 5d5514a; History read model: 66ff4cd; History API: df11386; Current roster API: 2c52e1b; Downstream invalidation dispatch: 39a8eba; Protected command API: 6758b30; sanmopia_caregiver_assignment_decisions exists; sanmopia_care_team_document_projection_invalidations exists | CaregiverAssignmentDecisionPayload; CareTeamAssignmentHistoryReadModelPayload; CareTeamAssignmentHistoryResponse; CareTeamCurrentRosterResponse; AssignCaregiverFromCandidateSnapshotRequest; CareTeamAssignmentCommandResponse; public OpenAPI/TS contracts 24497f0, 19892e2, 495d5cc | focused backend tests for protected assignment command API, assignment invalidation dispatch, payout refresh queue handoff, document invalidation receipt persistence, and contract pnpm check | runtime_wired |
SFC-20260707-MATCH-006 | backend | source-refs/sanmopia-admin/application/models/Reservation_model.php:2240-2303; source-refs/sanmopia-admin/application/models/Reservation_sub_manager_model.php:23-45 | caregiver_assignment / CareTeamRosterAssignmentDecision, CareTeamAssignmentHistoryReadModel, CareTeamCurrentRosterReadModel | AssignCaregiverFromCandidateSnapshotCommand; ClearAssistantCaregiverSlotCommand; GetCareTeamAssignmentHistoryQuery; GetCareTeamCurrentRosterQuery; GET /care-team-assignment-histories/{reservationBookingId}; GET /care-team-current-rosters/{reservationBookingId}; POST /care-team-assignment-decisions/clear-assistant-slot | Backend foundation: 1258920; Supabase persistence: fc90660; Command binding: 5d5514a; Clear binding: e0ff283; History read model: 66ff4cd; History API: df11386; Current roster API: 2c52e1b; Downstream invalidation dispatch: 39a8eba; Protected command API: 6758b30; sanmopia_caregiver_assignment_decisions stores roster id per row; sanmopia_care_team_document_projection_invalidations stores document stale signals | CareTeamRosterAssignmentDecisionPayload; CareTeamAssignmentHistoryReadModelPayload; CareTeamAssignmentHistoryResponse; CareTeamCurrentRosterResponse; ClearAssistantCaregiverSlotRequest; CareTeamAssignmentCommandResponse; public OpenAPI/TS contracts 24497f0, 19892e2, 495d5cc | focused backend tests for protected clear command API, assignment invalidation dispatch, payout refresh queue handoff, document invalidation receipt persistence, and contract pnpm check | runtime_wired |
SFC-20260707-MATCH-002 Travel Evidence Notes
Section titled “SFC-20260707-MATCH-002 Travel Evidence Notes”Source cache fields are only RESERVATION_ID_FK, MANAGER_ID_FK, and TIME.
Reservation_manager_trans_info_model::getReservationManagerTransInfo() reads
TIME by reservation and caregiver, otherwise calls ODSAY and replace() writes
those three fields. ODSAY input is the first reservation service address
LONGITUDE/LATITUDE as start coordinates and caregiver MANAGER_TB.LONGITUDE
/ LATITUDE as end coordinates. Provider output uses status and totalTime;
provider failure becomes ODSAY_MAX_TIME, while missing reservation address
returns false and the public getter returns 0.
The matching list path reads RESERVATION_MANAGER_TRANS_INFO_TB rows for the
candidate caregiver ids and reservation id. Missing rows trigger inline ODSAY
calls using the candidate row coordinates, but the DB replace() is commented
out there, so those computed values are request-local only. Existing
ODSAY_MAX_TIME rows do not refresh because the re-fetch flag is commented out.
Final ordering in this path still sorts by resultScore, not travel time, so
travel evidence is advisory source data unless the modern policy explicitly
weights it.
Modern acceptance proof: CaregiverTravelEvidenceSnapshot must persist provider,
reservation booking id, caregiver profile id, reservation address evidence key,
caregiver address evidence key, start/end coordinate facts, duration minutes,
fallback code, provider status, source cache key, freshness deadline, and
computed-at timestamp. RefreshCaregiverTravelEvidenceCommand must invalidate or
supersede snapshots when reservation service address, caregiver address/profile
coordinates, assignment policy version, or provider failure policy changes.
Consumers must reject stale travel evidence, distinguish missing-address from
provider-failure fallback, and copy the selected travel evidence id into
CaregiverCandidateEvidence before assignment.
Backend foundation a93332b adds CaregiverTravelEvidenceSnapshot,
TravelEvidenceFreshnessPolicy, Pydantic payloads, Supabase migration
sanmopia_caregiver_travel_evidence_snapshots, generated Supabase table types,
and repository save/load tests. The replacement freezes reservation/caregiver
address revisions, coordinate fingerprints, provider result/failure evidence,
fallback reason, measured/expiry timestamps, and source evidence keys so old
ODsay cache values cannot silently survive address/profile changes. Remaining
proof: provider-neutral travel refresh command, live ODSay/adapter binding,
recommendation-set integration, final assignment evidence copy, and E2E matching
smoke.
SFC-20260707-MATCH-004 Schedule Proof Notes
Section titled “SFC-20260707-MATCH-004 Schedule Proof Notes”Source candidate search calls MANAGER_SCHEDULE_CHECK_FN(...) = 1, while the
older PHP denied-date and checkManagerSchedule() filters are commented out.
Manager_model::checkManagerSchedule() scans primary assignment rows only and
uses weak edge checks that collapse some overlap cases to equality. Denied-window
mutation (addDenied / updateDenied) writes MANAGER_DENIED_TB directly with
reason/start/end only; it has no actor, expected revision, invalidation event, or
assignment-proof refresh. Final manager and sub-manager assignment writes service
dates and caregiver ids directly without rechecking the same schedule proof.
Backend foundation 66f6afa adds CaregiverScheduleInterval,
CaregiverScheduleProof, CaregiverScheduleConflictPolicy, and Pydantic
payloads. The replacement uses one inclusive date-overlap rule for unavailable
windows and existing assignment intervals, freezes schedule revision and source
evidence, and returns typed blocking codes instead of a raw boolean DB function.
Runtime follow-up 251ab72 persists schedule proofs in
sanmopia_caregiver_schedule_proofs with generated Supabase table types and a
repository keyed by proof id or candidate/service window. Remaining proof:
availability-window event persistence, assistant-slot overlap evidence,
availability-window mutation commands with actor/revision, recommendation API
integration, final assignment command guard, and E2E matching smoke.
SFC-20260707-MATCH-005/006 Assignment Decision Notes
Section titled “SFC-20260707-MATCH-005/006 Assignment Decision Notes”Source final assignment is written through broad reservation save paths. The
primary caregiver write posts fmanager-id and mutates
RESERVATION_TB.MANAGER_ID_FK; assistant caregivers are stored in
RESERVATION_SUB_MANAGER_TB by positional SORT and can be inserted, updated,
or deleted by array index. The source history table records old/new manager ids
but does not carry candidate snapshot, schedule proof, actor reason, policy
version, roster revision, or downstream payout/document invalidation evidence.
The assistant-slot clear path has a concrete migration defect: after deleting the sub-manager row, the source code attempts to delete branch-sub-manager and salary rows using the empty submitted manager id instead of the previous slot caregiver. Modern clear/replacement must therefore key downstream invalidation by stable assignment key and previous assignment key, never by a browser slot index or an empty posted id.
Backend foundation 1258920 adds CaregiverAssignmentDecision,
CareTeamRosterAssignmentDecision, typed decision kinds for primary assignment,
assistant replacement, and assistant clear, assignment-scope invalidation
targets, expected reservation/roster revisions, actor/reason/idempotency
evidence, candidate snapshot and schedule proof requirements, and strict
Pydantic payloads that reject legacy manager_id, sub_manager_sort,
fmanager-id, and related source field names. Remaining proof: Supabase
append-only assignment-decision persistence, current roster projection, later
broad-save guard, recommendation writer binding, payout/document
projection invalidation worker, assignment-history read model, and E2E
branch/HQ assignment smoke.
Runtime follow-up fc90660 adds CareTeamAssignmentDecisionRepository,
SupabaseCareTeamAssignmentDecisionRepository, Supabase table
sanmopia_caregiver_assignment_decisions, generated Supabase table types,
schema/codegen/access-control tests, and repository save/load tests. The table
keeps assignment decision id, roster decision id, reservation booking id,
decision kind, role, handoff order, target/previous assignment key, expected
reservation and roster revisions, actor/reason/idempotency, selected candidate
snapshot, schedule proof, invalidation count, and full decision snapshot under
service-role-only RLS.
Runtime follow-up 5d5514a adds
AssignCaregiverFromCandidateSnapshotCommand under
application/caregiver_assignment/features/care_team_contract. The command
loads the frozen CaregiverCandidateSnapshot, rejects missing, stale,
caregiver-mismatched, or matching-request-mismatched snapshots, then writes a
CareTeamRosterAssignmentDecision through
CareTeamAssignmentDecisionRepository. Orchestration-side
DecideCaregiverAssignmentFromCandidateSnapshotHandler stays limited to legacy
care-delivery evidence compatibility, so reservation_orchestration no longer
cross-imports the caregiver_assignment application/domain ownership. Primary
assignment and assistant replacement now persist with target assignment key,
previous assignment key when applicable, selected candidate snapshot, schedule
proof, expected reservation/roster revisions, actor/reason/idempotency, and
payout/document invalidation targets. Verification: focused assignment pytest,
care-team domain/contract pytest, Supabase repository pytest, ruff, Tach
dependency/interface/external gates, and Vulture confidence-100 scan. Remaining
runtime follow-up: current roster projection, later broad-save guard,
payout/document invalidation worker, assignment-history read model, assistant
clear command binding, and E2E branch/HQ assignment smoke.
Runtime follow-up e0ff283 adds ClearAssistantCaregiverSlotCommand under the
same care-team contract application slice. The command accepts a
cleared_assignment_key, maps it to both target and previous assignment key, and
persists a CLEAR_ASSISTANT_SLOT roster decision without candidate snapshot or
schedule proof. This blocks the source defect where assistant clear side effects
could be keyed by an empty submitted manager id instead of the previous slot
identity. care_team_assignment_invalidation_targets() is now shared by assign
and clear commands, removing duplicated projection-target construction.
Verification: focused assignment pytest, care-team domain/contract pytest,
Supabase repository pytest, ruff, Tach dependency/interface/external gates,
and Vulture confidence-100 scan. Remaining runtime follow-up: current roster
projection, later broad-save guard, payout/document invalidation
worker, assignment-history read model, and E2E branch/HQ assignment smoke.
Runtime follow-up 66ff4cd adds CareTeamAssignmentHistoryReadModel,
GetCareTeamAssignmentHistoryQuery, GetCareTeamAssignmentHistoryHandler, and
CareTeamAssignmentHistoryReadModelPayload. The read model uses
CareTeamAssignmentDecisionRepository.find_roster_decisions_by_reservation_booking_id()
to expose assignment decisions already persisted by assign/clear commands, then
orders entries by roster revision, roster decision id, and assignment decision
id. It carries decision kind, role, handoff order, target/previous assignment
key, candidate snapshot id, schedule proof id, actor/reason/idempotency,
evidence keys, invalidation targets, and latest roster revision. Shared
candidate-snapshot test support removes duplicate candidate fixture code across
assignment-command and history tests. Verification: focused assignment/history
pytest, care-team domain/contract pytest, Supabase repository pytest, ruff,
Tach dependency/interface/external gates, and Vulture confidence-100 scan.
Remaining runtime follow-up: current roster projection, later broad-save guard,
payout/document invalidation worker, and E2E branch/HQ assignment
smoke.
Runtime follow-up df11386 exposes assignment history through
CareTeamAssignmentHistoryApi and
GET /care-team-assignment-histories/{reservationBookingId}. The route derives a
Supabase user through bearer auth, rejects withdrawn member sessions, then reads
sanmopia_caregiver_assignment_decisions with a caller-scoped Supabase token so
RLS remains active instead of bypassing operator visibility. It returns camelCase
history entries with decision kind, role, assignment keys, roster revisions,
actor/reason/idempotency, evidence keys, and invalidation targets. Shared
assignment-history test support now feeds both application and HTTP tests,
removing duplicated primary/replacement/clear setup code. Public contract commit
24497f0 adds CareTeamAssignmentHistoryResponse, path helper
careTeamAssignmentHistoryPath(), response validators, JSON Schema, and OpenAPI
path coverage. Verification: focused assignment-history API/HTTP pytest,
care-team compensation boundary regression tests, Supabase assignment-decision
repository tests, main_test, ruff, Tach dependency/interface/external gates,
Vulture confidence-100 scan, and contract pnpm check. Later current-roster
API and broad-save guard follow-ups leave payout/document invalidation worker
and E2E branch/HQ assignment smoke open.
Runtime follow-up 2c52e1b adds CareTeamCurrentRosterReadModel,
GetCareTeamCurrentRosterQuery, GetCareTeamCurrentRosterHandler,
CareTeamCurrentRosterApi, and
GET /care-team-current-rosters/{reservationBookingId}. The projection folds
append-only assignment decisions into active roster slots: assign_primary
replaces any prior active primary, replace_assistant_slot removes the previous
assignment key and same assistant handoff slot before adding the replacement,
and clear_assistant_slot removes the target/previous assistant assignment
without relying on source SORT, empty submitted manager ids, or browser state.
The route uses the same caller-scoped Supabase assignment-decision repository as
history, so RLS remains active for operator-visible current roster reads.
Contract follow-up 19892e2 exposes CareTeamCurrentRosterResponse,
careTeamCurrentRosterPath(), response validators, JSON Schema, OpenAPI, and
generated dist artifacts. Verification: current-roster application/API/HTTP
pytest, assignment-history regression tests, Supabase assignment-decision
repository pytest, main_test, ruff, Tach dependency/interface/external
gates, Vulture confidence-100 scan, and contract pnpm check. Remaining runtime
follow-up after the later broad-save guard: payout/document invalidation worker
and E2E branch/HQ assignment smoke.
Runtime follow-up ef0a510 retires caregiver assignment broad-save writes from
ReservationCollaborationCommand: mutation kind caregiver_assignment and any
caregiver_assignment.* change-set field now fail with
ReservationCollaborationError before collaboration commit persistence. This
closes the source path where a one-submit reservation save could overwrite
MANAGER_ID_FK or positional assistant SORT data after care-team assignment
facts had already been modeled as append-only decisions. Public contract
follow-up 936ed47 adds the same rejection to the TypeScript commit validator
and reservation_collaboration_commit.schema.json; journal/read schemas keep
historical enum compatibility. Runtime backstop 068632e adds adapter and SQL
wrapper guards so direct SupabaseReservationCollaborationCommitStore or
sanmopia_commit_reservation_collaboration(...) calls also reject
caregiver_assignment broad-save payloads before touching Supabase RPC
persistence. Verification: reservation-collaboration domain/application/HTTP
and Supabase adapter pytest, SQL migration assertions, ruff, Tach
dependency/interface/external gates, Vulture confidence-100 scan, and contract
pnpm check. Remaining runtime follow-up: payout/document invalidation worker
and E2E branch/HQ assignment smoke.
Runtime follow-up 39a8eba adds standardized care-team assignment downstream
invalidation. AssignCaregiverFromCandidateSnapshotHandler and
ClearAssistantCaregiverSlotHandler dispatch typed invalidation requests only
after roster persistence succeeds. The application model now has stable
CareTeamAssignmentDownstreamInvalidationTargetCode and
CareTeamAssignmentDownstreamInvalidationStatus enums instead of raw bridge
strings. CareTeamAssignmentProjectionInvalidationRequester fail-fast rejects
unknown targets, queues care_team_assignment_changed refreshes through the
existing admin caregiver payout projection PGMQ requester, and records document
projection invalidation through
RecordCareTeamDocumentProjectionInvalidationCommand in the
document_reporting/features/service_use_contract slice. Backend follow-up
5dd338b keeps that receipt and also queues a typed
render_care_team_document_projection workload to Supabase PGMQ queue
sanmopia_document_rendering, carrying assignment key, source evidence, actor,
reason, and render idempotency key. Backend follow-up 3cdc86a consumes those
messages through SupabaseCareTeamDocumentRenderProcessor, retries while the
frozen render source row is not ready, renders through the printable document
handler, and stores the artifact after source/idempotency/definition checks.
Verification: assignment/clear dispatch pytest, document invalidation receipt
pytest, payout queue handoff pytest, render processor pytest, ruff, Tach
dependency/interface/external gates, and Vulture confidence-100 scan. Remaining
runtime follow-up: E2E branch/HQ assignment smoke, render-source producer
binding from roster/projection revision, and storage/access grant issuance.
Runtime follow-up 6758b30 binds the final assignment command surface to
FastAPI. POST /care-team-assignment-decisions/assign-from-candidate-snapshot
and POST /care-team-assignment-decisions/clear-assistant-slot derive the actor
from Supabase bearer auth, reject withdrawn sessions, check SpiceDB
assign_caregiver on the reservation booking, then write through service-role
Supabase repositories for frozen candidate snapshots and append-only assignment
decisions. The command API does not accept actorId from the request body.
Document projection invalidation receipts are now persisted in
sanmopia_care_team_document_projection_invalidations with RLS enabled and
service-role-only grants, so later document render workers can consume durable
stale-contract signals instead of hidden UI state. Public contract follow-up
495d5cc exposes the two command paths, bearer header helper, assign/clear
request validators, command response validator, JSON Schema, and OpenAPI paths.
Verification: protected command API/HTTP pytest, document invalidation Supabase
adapter pytest, assignment invalidation regressions, document render queue
processor pytest, ruff, Tach dependency/interface/external gates, Vulture
confidence-100 scan, and contract pnpm check. Remaining runtime follow-up:
live E2E branch/HQ assignment smoke against a seeded reservation plus frozen
render-source producer and access-grant binding.
2026-07-20 P06 Caregiver Response Readiness
Section titled “2026-07-20 P06 Caregiver Response Readiness”Backend 952bccca and contract b881604 add caregiver-owned assignment
accept/reject after branch assignment. New assignment starts at
pending_acceptance; only accepted assignment creates one schedule obligation
per billable service occurrence and binds the primary caregiver to the booking.
Revision checks, advisory-lock idempotency, altered-replay rejection, actor
ownership, append-only evidence, RLS, and service-role-only RPC execute are
server-owned. Schedule, reservation worklist, and compensation readers now
consume only accepted assignments.
Verification: contract pnpm check passed 485 tests; backend focused gate
passed 45; Tach exact returned zero diagnostics; Tach impact selection passed
2,853 and deselected 3,660 unaffected tests; Vulture confidence 100 found no
production candidate. Supabase PostgreSQL transaction smoke printed
P06 caregiver assignment response smoke passed, then rolled back. Post-check
proved response tables and revision column absent and original stage assignment
counts unchanged.
Status remains technical readiness, not P06 PASS. Missing strict evidence: seeded branch operator assignment, authenticated caregiver accept/reject, cross-actor denial, replay/stale conflict, retained UI screenshots/WebP, and cleanup manifest.
2026-07-21 P06 Self-Scoped Task UI Readiness
Section titled “2026-07-21 P06 Self-Scoped Task UI Readiness”Backend 443c989c adds authenticated self-scoped
GET /caregiver-assignment-response-tasks, persists the source assignment
decision on the pending projection, and rejects a response whose decision no
longer owns the current assignment. Contract d232992 publishes the additive
task list path, types, validators, JSON Schema, and OpenAPI after merging the
latest P04 contract lineage. Frontend 8183ed9 adds an Astro SSR mobile card,
same-origin accept/reject endpoint, server-side cookie token binding, and
contract-validated response handling.
Focused frontend tests passed 8; Astro check reported zero errors and production build passed. Backend Tach selected 1,132 affected tests and deselected 5,394; all selected tests passed. Vulture confidence 100 found no production candidate. Contract check passed 524 TypeScript and 91 Python tests.
The retained PNG and animated WebP are documented in P06 관리사 배정 응답 UI 준비. They are isolated browser harness evidence, not an actual Supabase actor run. P06 therefore remains BLOCKED until branch assignment, caregiver accept and reject, denial, replay/conflict, primary-state, and cleanup are proved together.
Top Gaps
Section titled “Top Gaps”- Candidate snapshot, branch assignment decision, and caregiver response are separated in backend/contract readiness. Missing proof is live actor HTTP/UI execution, retained media, and cleanup evidence.
- Named caregiver selection has backend policy decisions, but still needs Supabase persistence/API binding and source survey/search UI wiring.
CareTeamContractfoundation, Supabase compensation-source reader, caller-JWT HTTP binding, and accepted-assignment gating exist. Document-template, mother/caregiver workspace, daily-report, and payout projections still need the same stable assignment keys.- Caregiver grade is mutable and score logic has policy drift; freeze grade snapshots and move score math into tested policy.
- Caregiver wage settlement recalculates at read time and backfills payment rows during completion; migrate to payout-ready instructions plus separate acknowledgements.