Document Reporting Gap Mining
Document Reporting Gap Mining
Section titled “Document Reporting Gap Mining”This mining pass covers the legacy reservation document center, receipt handoff, daily report flows, service records, print/export generation, template registry risks, download access, A4/HTML/PDF requirements, and OSS replacement candidates.
- Reservation documents and customer-facing downloads.
- Customer receipts and payment receipt handoff.
- Customer daily surveys, caregiver daily reports, sub-caregiver reports, and service records.
- Admin print/export generation, bundled downloads, and scheduled document delivery.
- Template identifier drift, static PDF/XLSX templates, A4 layout needs, and render engine replacement choices.
Reservation Documents And Receipts
Section titled “Reservation Documents And Receipts”Legacy behavior:
- The customer reservation page builds a short-lived document download token, renders a document list, and opens a tokenized download URL through the customer API. Evidence:
source-refs/sanmopia_web/application/controllers/MyReservation.php:352-372,source-refs/sanmopia_web/application/views/mypage/reservation_document.php:38-139,source-refs/sanmopia_web/application/models/User_model.php:461-489,source-refs/sanmopia_web/application/controllers/api/ReservationDocument.php:1-55. - The customer document view hardcodes service-type document sets, numeric document IDs, end-date/status visibility, and
?token=URL construction in the view. Evidence:source-refs/sanmopia_web/application/views/mypage/reservation_document.php:38-139. - The customer API validates token ownership and delegates PDF generation to an admin-side document interface. Evidence:
source-refs/sanmopia_web/application/models/Reservation_model.php:2769-2820,source-refs/sanmopia-admin/application/controllers/SanmoInterface.php:37-51. - The customer document list excludes receipt, service record, customer daily survey, and caregiver daily report artifacts. Those are available only through other screens or admin export flows. Evidence:
source-refs/sanmopia_web/application/views/mypage/reservation_document.php:38-139,source-refs/sanmopia-admin/application/controllers/DataRoom.php:311-420. - The customer receipt screen opens a card gateway receipt URL from payment context instead of serving a stored receipt artifact. Evidence:
source-refs/sanmopia_web/application/controllers/MyReservation.php:329-350,source-refs/sanmopia_web/application/views/mypage/reservation_receipt.php:49-128. - The customer receipt view decodes payment context, exposes gateway order and transaction identifiers, and builds the KCP provider URL client-side. Evidence:
source-refs/sanmopia_web/application/views/mypage/reservation_receipt.php:37-128. - Receipt notification behavior was removed from the payment model while document notification behavior remained. Evidence:
source-refs/sanmopia_web/application/models/Payment_model.php:131-138. - Scheduled service-start and end-notice delivery generates attachments, sends mail, records delivery status, and deletes temporary files. Evidence:
source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:1-130,source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:175-227,source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:330-365.
Gaps to migrate:
- Add
ReservationDocumentCatalogas the single policy source for customer-visible documents, admin-only exports, service-type eligibility, and required payment/service-state gates. - Add
PrintableDocumentAccessGrantwith actor, reservation, document kind, format, expiry, revocation, and audit state. A two-hour token alone is not enough for artifact access. - Add
CustomerReceiptArtifactthat can reference an external gateway receipt and optionally persist a rendered receipt fallback. The cash-receipt tax-evidence foundation now exists asCustomerReceiptTaxEvidenceArtifact(d247aba), visibility is backend-owned (e5a1571), printable access handoff exists (04690fa), receipt render data/render-plan binding exists (24c5f40), stored printable artifact binding exists (2c0ce95), legacy KCP cash-receipt backfill command exists (203e179), and the internal import-run HTTP binding exists (c48bbfc). Remaining work is source extractor/runbook execution that feeds the import endpoint from reviewed historical rows while following payment ledger state, not only a gateway URL assembled in a view. - Add
VoucherSelfPayReceiptArtifactfor legacy admin document id7/type7.xlsx. SourceSpreadsheet_model::excelVoucherPaymentReceipt()fills branch, mother, consume-type split, service-day type, branch stamp, mother signature, reservation number fallback, service/government/self-pay amounts, and deposited date from voucher payment rows. Modern render source must freeze these facts asVoucherReceiptPaymentEvidenceSnapshotandVoucherReceiptRenderSource, not reload live spreadsheet rows. DocumentDeliveryAttemptnow has a backend slice for recipient/channel attempt status, retry scheduling, provider message/code/payload response audit, Supabase persistence, and API facade. Remaining delivery gaps are scheduled batch orchestration, bundle-version linkage, provider cleanup policy, and operator resend screens.- Customer document access and admin export access should both point at stored artifacts or signed object URLs, not a live cross-service render call.
- Public document/read models must expose typed document/template keys and signed handoff references only. They must not expose source numeric document IDs, token query parameters, storage object paths, gateway order IDs, transaction IDs, or provider URL construction facts.
- Service-use contract render worker consumption now exists in backend commit
3cdc86a: queuedrender_care_team_document_projectionmessages load a frozensanmopia_service_use_contract_render_sourcesrow, retry when the source is not ready, render through the printable document handler, and store a versioned artifact. The remaining gap is the producer side: persistCareTeamDocumentProjection/roster revision render sources and access grants before render, without reloading liveRESERVATION_MANAGER_LOG_TB,MANAGER_TB,MANAGER_INFO, orSUB_MANAGER, and without transient XLSX/PDF temp files as the artifact record. Evidence:source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:167-376,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:3507-3664,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:4434-4598,source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:19-132,source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:624-688. - Backend commit
e7972ccrecordsServiceUseContractEvidenceSnapshotPayloadasServiceUseContractRenderSourcerows and adds render-source readiness:waiting_for_required_factsrows make workers retry instead of rendering incomplete artifacts, whileready_for_renderrows must have no missing fact codes. Remaining producer-side data must freeze the inputs currently pulled from live reservation/payment/caregiver/asset rows: service-use template year fromSERVICE_START_DT; service period/type; mother name, contact, registered/service addresses, masked birth date from voucher resident-number fragments; branch legal/contact fields plus stamp asset reference; mother signature asset reference; deposit/contract date from payment rows; current or previous primary caregiver name/phone from manager-change logs orMANAGER_TB; adjacent voucher/intake document provider count, primary/sub caregiver names, manager personality text, service balance/custom balance, and add-day facts. Evidence:source-refs/sanmopia-admin/application/models/Reservation_model.php:10-48,source-refs/sanmopia-admin/application/models/Reservation_model.php:160-276,source-refs/sanmopia-admin/application/models/Reservation_model.php:408-470,source-refs/sanmopia-admin/application/models/Reservation_model.php:938-963,source-refs/sanmopia-admin/application/models/Payment_model.php:3149-3179,source-refs/sanmopia-admin/application/models/Manager_model.php:2366-2372,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:167-376,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:3507-3664. ServiceUseContractRenderSourceProducermust freeze payment and asset provenance separately from printable cell values. Source scheduled mail chooses service-use contract bundle membership fromBEFORE_PAYMENT_DEPOSITED_DTand service type, while the contract footer date readsgetPaymentInfoByReservationId()with no"before"argument, so the default source row is payment type2. Branch stamp comes from mutableBRANCH_TB.STAMP_IMG_URL, can be uploaded/deleted through office-management actions, and is converted to JPEG during render. Mother signature is captured as browser base64 during payment request, overwritesRESERVATION_TB.SIGN_IMG_URL, deletes the previous file, then the renderer dereferences that mutable path. Modern producer targets:ServiceUseContractPaymentEvidenceSnapshot,BranchStampAssetSnapshot,MotherSignatureAssetSnapshot, andServiceUseContractAssetReferenceSnapshotwith storage object version, checksum, source revision, and readiness codes. Evidence:source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:37-108,source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:633-670,source-refs/sanmopia-admin/application/models/Payment_model.php:3149-3179,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:183-225,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:316-332,source-refs/sanmopia-admin/application/models/Branch_model.php:157-166,source-refs/sanmopia-admin/application/models/Branch_model.php:481-504,source-refs/sanmopia-admin/application/models/Branch_model.php:561-575,source-refs/sanmopia-admin/application/controllers/OfficeManagement.php:118-166,source-refs/sanmopia-admin/application/controllers/OfficeManagement.php:270-276,source-refs/sanmopia_web/static/js/reservation_payment.js:40-66,source-refs/sanmopia_web/application/controllers/api/Service.php:869-882,source-refs/sanmopia_web/application/models/Payment_model.php:12-42.- Backend commit
1ff144eaddsServiceUseContractEvidenceSnapshotFactReader,ProjectServiceUseContractRenderSourceCommand, andProjectServiceUseContractRenderSourceHandler. Complete fact sets now project ready render-source rows; incomplete fact sets projectwaiting_for_required_factsrows with exact missing fact codes. Backend commit9f16fc1adds a concrete Supabase fact reader for available service-calendar plan, paid payment, care-team assignment decision, finalized charge snapshot, and finalized charge line facts. Backend commitc7ad654wires care-team assignment invalidation to project a service-use contract render source before queuing render work, and the fact reader now records an enabled document definition asContractTemplateEffectiveVersionDecisionwhen its active window covers the service start date. Backend commitaa92fceadds branch-stamp/mother-signature asset readiness facts plus backend-owned document-center download readiness so UI cannot synthesize render request codes or bundle handoff members. Backend commit92aed4freads safe redacted resident identity evidence rows and completesidentity_evidenceonly when the snapshot supplies birth date, evidence kind, and redaction profile without raw resident-number fields. Backend commit544c27fadds the producer foundation that records voucher recipient identity evidence into backend-ownedsanmopia_redacted_resident_identity_evidencesrows with no raw resident-number storage. Contract commit7cb680dexposes the document-center projection and makes printable render request codes snapshot-revision aware. Remaining gaps are runtime voucher-intake/API binding for the producer, immutable branch stamp/mother signature asset snapshots with grants/checksums, stored artifact/access grants, backfill, and live render E2E without mutable row reload. - Document-center projection exposure is now a typed backend/contract surface, not a browser catalog recipe. Backend
aa92fceprojectsDocumentCenterProjectionfrom the active document catalog plus latest stored artifact facts, including per-item eligibility, artifact metadata, download handoff descriptors, bundle members, missing definition keys, and bundle availability. Backend695943abinds that projection to authenticated FastAPI routeGET /document-center-projections/{reservationBookingId}with camelCase response aliases and Supabase Auth bearer-token enforcement. Contract7cb680dexposesDocumentCenterCatalogItem,DocumentCenterStoredArtifact,DocumentCenterDownloadHandoffDescriptor, andDocumentCenterBundleDownloadso frontend code should consume typed projection rows through Nanostores state and call the described handoff endpoints. Browser code must not compose numeric document ids, token query strings, render request codes, bundle members, missing-artifact status, or service-kind eligibility. Remaining runtime gaps are signed-storage handoff implementation, frontend Nanostores adapter/view-model consumption, and guard/reroute of old live numeric document-id render entrypoints. Evidence:backend-repo/src/sanmopia_modernization/application/document_reporting/features/document_center/project_document_center.py,backend-repo/src/sanmopia_modernization/interfaces/document_center_http.py,backend-repo/src/sanmopia_modernization/interfaces/document_center_http_test.py,contract-repo/packages/ts-client/src/types/document-reporting.ts:806-864. - Remaining producer gaps after
c7ad654have concrete legacy sources. Legacy template effective version was selected inside render fromSERVICE_START_DTyear (>= 2024used the current type-1 spreadsheet, otherwisetype1_old_20240122.xlsx); the modern producer now reads the enabled document definition and active window instead. Mother birth evidence is still rebuilt during render from raw voucher resident-number fragmentsUSER_NUMBER1/USER_NUMBER2, not from a redacted identity evidence snapshot. Branch stamp and mother signature still flow as mutable file paths: branch stamp readsBRANCH_TB.STAMP_IMG_URL, converts that file to JPEG, and office-management upload/delete overwrites or deletes the previous file; mother signature posts browser base64 to the payment request endpoint, writesRESERVATION_TB.SIGN_IMG_URL, and deletes the previous file. Contract access/storage remains token/live-render based: customer UI gets a two-hourUSER_TOKEN_TBtoken, builds a?token=download URL, calls the adminmakePdfDocumentinterface, decodes base64 PDF bytes, and streams them directly; scheduled mail writes converter output to temp files and deletes attachments after send. Modern producer targets:RedactedMotherIdentityEvidenceSnapshot,BranchStampAssetSnapshot,MotherSignatureAssetSnapshot,StoredPrintableDocumentArtifact, andPrintableDocumentAccessGrant. Evidence:source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:167-179,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:251-260,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:316-332,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:4284-4297,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:4434-4600,source-refs/sanmopia-admin/application/models/Reservation_model.php:938-963,source-refs/sanmopia-admin/application/models/Branch_model.php:157-166,source-refs/sanmopia-admin/application/models/Branch_model.php:481-518,source-refs/sanmopia-admin/application/models/Branch_model.php:561-586,source-refs/sanmopia-admin/application/controllers/OfficeManagement.php:118-166,source-refs/sanmopia-admin/application/controllers/OfficeManagement.php:270-276,source-refs/sanmopia_web/static/js/reservation_payment.js:40-66,source-refs/sanmopia_web/application/controllers/api/Service.php:869-882,source-refs/sanmopia_web/application/models/Payment_model.php:12-42,source-refs/sanmopia_web/application/controllers/MyReservation.php:352-372,source-refs/sanmopia_web/application/views/mypage/reservation_document.php:118-139,source-refs/sanmopia_web/application/models/User_model.php:461-489,source-refs/sanmopia_web/application/controllers/api/ReservationDocument.php:21-55,source-refs/sanmopia_web/application/models/Reservation_model.php:2769-2820,source-refs/sanmopia-admin/application/controllers/SanmoInterface.php:37-51,source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:104-132,source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:200-227,source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:330-365,source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:666-688. - Redacted mother identity evidence now has a backend producer foundation. Backend
42f7ed0records redacted-identity readiness without reloading raw resident-number fragments, backend92aed4fconsumes safesanmopia_redacted_resident_identity_evidencesrows when they exist, and backend544c27faddsRecordVoucherRecipientIdentityEvidenceHandlerplus the Supabase store/migration for service-role-owned evidence rows. Source voucher intake shows raw resident-number fields in the customer form, stores them asUSER_NUMBER1andUSER_NUMBER2inRESERVATION_SERVICE_VOUCHER_TB, and admin reservation creation writes the same raw columns. One extension path explicitly unsets those fields before returning a cloned reservation, proving raw fragments are known sensitive but still available to renderers. The service-use contract renderer reconstructs birth date from the raw fragments at render time. Modern readiness now recordsidentity_readinessfrom voucher recipient identity decision metadata, and the fact reader fillsidentity_evidenceonly from a redacted snapshot that suppliesbirth_date,evidence_kind, andredaction_profile_key; if the row is missing or incomplete, render source remainswaiting_for_required_facts. Runtime follow-up: bind the producer into voucher intake/customer/admin command paths, backfill legacy voucher rows, and reject any render-source producer that reloadsUSER_NUMBER1,USER_NUMBER2, orresident_identity_digits.document_reportingshould own only the frozen redacted snapshot and evidence reference; it must not parse voucher resident-number fragments or expose raw identity fields in render-source rows. Evidence:source-refs/sanmopia_web/application/views/service/step3_voucher.php:70-90,source-refs/sanmopia_web/application/models/Reservation_model.php:488-510,source-refs/sanmopia_web/application/models/Reservation_model.php:2448-2458,source-refs/sanmopia-admin/application/models/Reservation_model.php:5058-5066,source-refs/sanmopia-admin/application/models/Reservation_model.php:938-963,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:251-260,backend-repo/src/sanmopia_modernization/application/document_reporting/features/service_use_contract/service_use_contract_evidence_snapshot_projection.py,backend-repo/src/sanmopia_modernization/adapters/document_reporting/features/service_use_contract/supabase_service_use_contract_evidence_snapshot_fact_reader.py,backend-repo/src/sanmopia_modernization/application/member_management/features/redacted_resident_identity_evidence/record_voucher_recipient_identity_evidence.py,backend-repo/supabase/migrations/20260707150000_redacted_resident_identity_evidences.sql. - Branch stamp and mother signature need asset-snapshot producers, not path copying. Legacy upload helpers return relative paths and original names but no checksum, object version, grant id, or immutable artifact row. Admin branch stamp upload/delete updates
BRANCH_TB.STAMP_IMG_URLand unlinks the previous file; customer payment signature upload writes a random PNG path intoRESERVATION_TB.SIGN_IMG_URLand unlinks the previous signature. The service-use contract renderer reads those current paths and only checks file existence. Implementation recommendation: persistBranchStampAssetSnapshotandMotherSignatureAssetSnapshotwith storage bucket/object key, object generation/version, sha256 checksum, byte size, media type, source row revision, actor/source command evidence, access grant reference, and missing/expired readiness codes; renderers should consume snapshots only. Evidence:source-refs/sanmopia-admin/application/libraries/Uploadlib.php:47-90,source-refs/sanmopia-admin/application/libraries/Uploadlib.php:123-170,source-refs/sanmopia_web/application/libraries/Uploadlib.php:40-76,source-refs/sanmopia_web/application/libraries/Uploadlib.php:110-124,source-refs/sanmopia-admin/application/models/Branch_model.php:481-518,source-refs/sanmopia-admin/application/models/Branch_model.php:561-586,source-refs/sanmopia_web/application/models/Payment_model.php:12-42,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:183-207,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:316-332. - Stored artifact/access grant needs a runtime seam that rejects live mutable render for service-use contracts. Admin data-room and customer document paths still call numeric document-id renderers;
makePdfData()andmakePdfDataToSendMail()reload mutable reservation/service/rental rows, write temp XLSX/PDF names from current mother name/reservation id, call the external converter, return base64 or temp path, and scheduled mail deletes attachments after send. Customer access is a two-hour token overUSER_TOKEN_TB, not a grant over a persisted artifact. Implementation recommendation: service-use contract render requests should read onlyServiceUseContractRenderSource, writeStoredPrintableDocumentArtifactwith artifact checksum/storage version/source-render-source revision, then issuePrintableDocumentAccessGrantfor customer/admin/scheduled-mail surfaces; legacy live-render entrypoints should be guarded or routed to stored artifacts for document id1. Evidence:source-refs/sanmopia-admin/application/controllers/DataRoom.php:80-96,source-refs/sanmopia-admin/application/controllers/DataRoom.php:311-376,source-refs/sanmopia-admin/application/controllers/ajax/DataRoom.php:66-86,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:3914-3940,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:4284-4423,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:4434-4600,source-refs/sanmopia_web/application/controllers/MyReservation.php:352-372,source-refs/sanmopia_web/application/views/mypage/reservation_document.php:118-139,source-refs/sanmopia_web/application/models/User_model.php:461-489,source-refs/sanmopia_web/application/controllers/api/ReservationDocument.php:21-55,source-refs/sanmopia_web/application/models/Reservation_model.php:2769-2820,source-refs/sanmopia-admin/application/controllers/SanmoInterface.php:37-51,source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:104-132,source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:200-227,source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:330-365,source-refs/sanmopia-admin/application/controllers/cli/ReservationDocument.php:666-688. ServiceUseContractRenderSourceProduceralso needs frozen charge and occurrence inputs before render. Legacy price attachment buildsadditionalServicePriceList, voucher special/live-in add price, rental/delivery totals, discount/coupon effects, user-fee rows, andleftPricefrom mutable reservation, price-version, service-day, address, coupon, rental, and additional-service rows. Legacy spreadsheet renderers then readSERVICE_PRICE_LATEST,OWN_PRICE_LATEST,DISCOUNT_GOVERNMENT_PRICE_LATEST,SERVICE_PRICE,PRICE_TABLE['voucherSpecialPrice'], andPRICE_TABLE['additionalServicePriceList'], and adjacent down-payment sheets still recompute Saturday/holiday added-day counts, non-SAT/HOLI add-on multipliers overSERVICE_DAY + addDays, rental delivery hardcodes, voucher surcharge, and first SAT/HOLI display date. Modern producer targets:ChargeComponentRevisionSnapshotandServiceOccurrenceSetwith price version, component revision, occurrence-set revision, selected additional-day source rows, extension/holiday evidence, and readiness codes. Evidence:source-refs/sanmopia-admin/application/models/Reservation_model.php:644-923,source-refs/sanmopia-admin/application/models/Reservation_model.php:4013-4045,source-refs/sanmopia-admin/application/models/Reservation_model.php:4110-4137,source-refs/sanmopia-admin/application/models/Reservation_model.php:4748-4764,source-refs/sanmopia-admin/application/models/Reservation_model.php:4992-5014,source-refs/sanmopia-admin/application/models/Reservation_model.php:5200-5208,source-refs/sanmopia-admin/application/models/Reservation_model.php:5455-5496,source-refs/sanmopia-admin/application/models/Reservation_model.php:5644-5658,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:335-373,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:629-780,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:3570-3607.
Daily Reports And Service Records
Section titled “Daily Reports And Service Records”Legacy behavior:
- Customer daily survey forms validate service date, ownership, service range, stop day, and first/middle/last question sets. Evidence:
source-refs/sanmopia_web/application/controllers/MyReservation.php:193-258,source-refs/sanmopia_web/application/views/mypage/daily_report.php:1-197. - Sub-caregiver customer survey forms are separate but mirror the primary caregiver flow. Evidence:
source-refs/sanmopia_web/application/controllers/MyReservation.php:261-326,source-refs/sanmopia_web/application/views/mypage/daily_sub_report.php:1-172. - Caregiver daily report forms validate caregiver ownership, notification state, first/progress/last question sets, and save structured answers plus essay text. Evidence:
source-refs/sanmopia-manager/application/controllers/Report.php:1-108,source-refs/sanmopia-manager/application/models/Report_model.php:1-101,source-refs/sanmopia-manager/application/views/report/report.php:1-137,source-refs/sanmopia-manager/static/js/report/report.js:1-70. - Service record save accepts primary or sub caregiver ownership, validates
respiratory symptom comments, mother temperature, and URL-supplied service
date shape, then writes primary rows to
MANAGER_SERVICE_TBand sub rows toMANAGER_SUB_SERVICE_TB. Duplicate suppression is per table byRESERVATION_ID_FK + SERVICE_DT, not caregiver/role/handoff; duplicates return success without insert or error. Evidence:source-refs/sanmopia-manager/application/controllers/Service.php:58-180,source-refs/sanmopia-manager/application/models/Service_model.php:10-135. - Service record route/date handling is inconsistent: routes expose
/service/{notifyIndex}while controller requires notify id plus date; schedule passes/service/index/{notifyIndex}/{date}. Notify read creates attendance rows as a hidden side effect. Evidence:source-refs/sanmopia-manager/application/config/routes.php:56-57,source-refs/sanmopia-manager/application/views/notify/notify_main.php:51-57,source-refs/sanmopia-manager/application/views/home/main.php:253-258,source-refs/sanmopia-manager/application/views/schedule/schedule_info.php:227-230,source-refs/sanmopia-manager/application/models/Notify_model.php:380-437. - Scheduled notification creation and push dispatch are separate flows.
Fcm.phpfirst insertsREPORT_FIRST,REPORT_PROGRESS,REPORT_LAST, andSERVICEnotify rows, then a separate push flow derives manager ids and sends FCM. Manual repair is CLI-only, takes one reservation id, inserts missing report/service notify rows up to today, and does not push. Evidence:source-refs/sanmopia-manager/application/controllers/cli/Fcm.php:24-41,source-refs/sanmopia-manager/application/controllers/cli/Fcm.php:90-104,source-refs/sanmopia-manager/application/controllers/cli/Fcm.php:237-287,source-refs/sanmopia-manager/application/models/Reservation_model.php:559-580. - Report obligation date filters differ by kind: first report uses
SERVICE_START_DT == today, progress uses start before today and end after today, last usesSERVICE_END_DT == today, and service record uses start/end containing today. Current report/service queries include reservation statuses0,3,4,5,6,11,12; status13is excluded, while older repair helpers still include it. Evidence:source-refs/sanmopia-manager/application/models/User_model.php:1603-1643,source-refs/sanmopia-manager/application/models/User_model.php:1858-1901,source-refs/sanmopia-manager/application/models/User_model.php:1941-1982,source-refs/sanmopia-manager/application/models/User_model.php:2070-2106,source-refs/sanmopia-manager/application/models/Notify_model.php:70-260. - Customer report-date readers infer stopped intervals from reservation change
logs. The stop transition date is included as a report date and marked as the
last report day, suspended in-between dates are filtered out, and the service
end date remains eligible. Evidence:
source-refs/sanmopia_web/application/models/Report_model.php:267-391andsource-refs/sanmopia_web/application/models/Report_model.php:394-518. - The FCM sender reads
USER_TOKEN_TBwhereTYPE = 'fcm'andPUSH_FL = 1for multi-recipient sends, butsendByIdcan ignorePUSH_FLand sends only the first token. Provider calls return rawhttp_code/responsevalues with no token id, durable attempt row, retry, dead-letter, or repair state. Evidence:source-refs/sanmopia-manager/application/models/Fcm_model.php:60-88,source-refs/sanmopia-manager/application/models/Fcm_model.php:91-124,source-refs/sanmopia-manager/application/models/Fcm_model.php:161-188,source-refs/sanmopia-manager/application/models/User_model.php:1514-1540. - Admin exports resolve customer survey and caregiver report data during export,
then choose first/middle/last templates by service date and stop day. Stop day
uses the last-day daily report template even when it is not
SERVICE_END_DT. Evidence:source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:4017-4096,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:4040-4045,source-refs/sanmopia-admin/application/models/Reservation_model.php:3262-3272,source-refs/sanmopia-admin/application/models/Reservation_model.php:3323-3358.
Gaps to migrate:
- Add
CaregiverReportObligationgenerated from the service calendar and assignment history. Reminder jobs should be idempotent commands over obligations, not one-off notification scans. CareDeliveryNotificationWorkQueueProjectionnow exposes obligation key, reservation id, service date, caregiver id, obligation kind, due time, attempt state, retry state, oldest attempt age, attempt count, retry due time, last provider code/status, suppression reason, repair action set, and backend-owned action set. Remaining proof: Supabase persistence, queue worker binding, Novu/FCM adapter audit events, and operator API. The browser should render this projection and submit commands withexpectedRevisionand an idempotency key; it must not derive recipients, due dates, retry/backoff, token filtering, or missing-report math.- Add
DailyCareReportSubmissionkeyed by reservation, service date, care team member, role, question set, and submission status. Primary and sub-caregiver variants should be role-scoped records, not duplicated flows. - Add
CustomerDailySurveySubmissionwith first/middle/last/stop-day question set versioning and explicit edit/lock rules. - Stop-day acceptance:
CustomerDailySurveySubmissionandDailyCareReportSubmissionmust consume durable suspension intervals, mark the effective stop date as the last-day question set/template for mother and caregiver lanes, exclude dates between stop and resume, keep the actual service end date eligible, and avoid read-time inference from rawRESERVATION_CHANGE_LOGJSON. CaregiverServiceRecordSubmissionnow owns primary/assistant identity, handoff order, service-date access window, respiratory/temperature facts, meal/feeding/recovery fields, explicit duplicate replay, correction revision, route date, sequential write action, and attendance outbox key. Remaining proof: Supabase persistence, API route wiring, baby bootstrap facts, frozen export snapshots, and document IDs6/20for primary/sub service records.- Admin exports should read frozen submission snapshots and artifact metadata. They should not recalculate question-set classification or row grouping during download.
2026-07-06 Explorer A Print/Export Delta
Section titled “2026-07-06 Explorer A Print/Export Delta”| Priority | Status | Modern ubiquitous name | Hidden source evidence | Feature gap |
|---|---|---|---|---|
| P0 | Partial | DailyReportPrintableSeriesManifest | source-refs/sanmopia-admin/application/controllers/ajax/DataRoom.php:108-123, source-refs/sanmopia-admin/application/models/Reservation_model.php:3323-3358, source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:4017-4057, source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:1966-2010, source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:2859-2903 | Admin export lists customer daily-report reservations by joining live report tables, then export builds one printable series from REPORT_TB service dates and a separate sub-caregiver series from REPORT_SUB_MANAGER_TB. Template choice is recomputed at export time from first/middle/last/stop-day rules and fixed spreadsheet slots. Modern print/export needs a frozen manifest per reservation, service date, care-team member role, report lane, question-set version, template version, and artifact build request before download. |
| P1 | Pending | CaregiverDailyReportPrintableSeriesManifest | source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:4058-4096, source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:1449-1548, source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:1530-1572, source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:1700-1730 | Caregiver daily-report print export discovers first/middle/last pages by question ids (1-1, 2-1, 3-1) and CREATED_DT, mutates $reservation->MIDDLE_DATE for middle pages, then maps answer codes directly to fixed cells. Modern export should publish a role-scoped caregiver report print-series manifest with service occurrence key, submitted-at timestamp, question/answer snapshot, essay answer, template section key, and deterministic page ordering. |
| P0 | Pending | ContractPrintPricingSnapshot | source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:644-660, source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:663-700, source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:705-724, source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:728-780 | The contract/deposit print renderer recalculates additional-service totals, treats Saturday/holiday add-ons differently from per-service-day add-ons, hardcodes rental delivery/add-on amounts, and writes government support, customer share, voucher service price, special add price, child/adult add-ons, and rental fee totals directly into spreadsheet cells. Modern print/export needs a frozen pricing snapshot from accepted quote and payment ledger facts before render; template code should not own add-on multiplication, hardcoded rental fees, or amount classification. |
| P0 | Partial | VoucherReceiptPrintableSettlementSnapshot | source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:1057-1077, source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:1104-1132, source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:1221-1237, source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:1243-1290 | The voucher receipt renderer queries branch/caregiver data, re-derives short/standard/extended service-day classification from positional SERVICE_DAY_LIST, falls back from gateway transaction number to reservation number, recomputes service price as government support plus customer share, and reads deposited date from payment rows while filling receipt cells. Existing backend receipt/catalog foundations must be bound to printable artifact generation so renderer input is a ledger-backed settlement snapshot with receipt date, service-day classification, amount components, and identifier policy already frozen. |
| P1 | Pending | VoucherServiceEndNoticeSnapshot | source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:1396-1446 | The voucher service-end notice renderer derives birthday from resident-number fragments, formats service period text, maps SERVICE_TYPE_DETAIL string literals to public service labels, and injects branch name/phone at render time. Modern notice generation needs a backend-owned service-end notice snapshot with privacy-safe birth date, service-period facts, service package label, branch contact snapshot, and template version before scheduled delivery or admin export. |
Print And Export Generation
Section titled “Print And Export Generation”Legacy behavior:
- A numeric document registry maps reservation document kinds, daily report kinds, service record kinds, receipts, bundled downloads, and notices. Evidence:
source-refs/sanmopia-admin/application/config/constants.php:217-257. - Spreadsheet generation uses a positional template array with static XLSX/PDF files and inconsistent file naming. Evidence:
source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:1-39,source-refs/sanmopia-admin/static/dist/excel/type8.xlsx,source-refs/sanmopia-admin/static/dist/excel/type8.pdf,source-refs/sanmopia-admin/static/dist/excel/type15.pdf. - The static template directory includes current and old XLSX/PDF variants for document, receipt, daily report, and notice output. Evidence:
source-refs/sanmopia-admin/static/dist/excel/type6_old.xlsx,source-refs/sanmopia-admin/static/dist/excel/type7_old.xlsx,source-refs/sanmopia-admin/static/dist/excel/type10_3_old_20240125.xlsx,source-refs/sanmopia-admin/static/dist/excel/type21.xlsx. - Admin download generation fills spreadsheets, copies static PDFs for some kinds, creates ZIP bundles, writes temporary files, deletes temporary files, and exits the request. Evidence:
source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:3914-4199. - Customer PDF generation supports only a subset of document kinds and returns base64 PDF data. Evidence:
source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:4284-4598. - XLSX-to-PDF conversion was moved from a local office conversion path to a network conversion service with an authorization header. Evidence:
source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:4368-4408,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:4524-4579. - Admin bundle selection builds different integrated bundles by service type, then posts selected reservations to a hidden iframe download. Evidence:
source-refs/sanmopia-admin/application/controllers/DataRoom.php:311-420,source-refs/sanmopia-admin/static/js/data_room/form_reservation_list.js:1-149,source-refs/sanmopia-admin/static/js/data_room/form_reservation_list.js:219-247.
Gaps to migrate:
- Add
PrintableTemplateRegistrykeyed by document kind, template version, locale, paper format, render format, storage object key, and supported service types. Reject registry entries when declared format and stored file extension disagree. - Add
PrintableRenderRequestfor one artifact at a time, with reservation snapshot hash, template version, renderer, requested format, output object key, status, error reason, and retry count. - Backend printable policy now models a versioned template registry decision with document kind, template version/revision, A4 page policy, render format, renderer, supported service kinds, repeat-section flow policy, snapshot revision, readiness, and missing reasons. Storage references remain domain-internal and are excluded from public read models.
- Add
PrintableDocumentBundlethat references artifact IDs instead of building ZIP files from live render side effects. Bundle policy should report missing artifacts and ineligible document kinds. - Move from positional template IDs to versioned document kinds. Migration must include a manifest from every legacy numeric value to a modern document kind and template version.
- Keep the numeric/template-file mapping in migration docs and import scripts only. The modern backend catalog should store stable document definition keys, template versions, renderer/page policy, service-kind eligibility, and internal template storage references without source-audit fields.
- Stop using request-time temporary files as the artifact system of record. Persist HTML/PDF output, checksum, byte size, content type, and generated-at time.
A4, HTML, PDF, And OSS Candidates
Section titled “A4, HTML, PDF, And OSS Candidates”Legacy behavior:
- Customer and caregiver report forms are mobile HTML screens, not print-specific A4 layouts. Evidence:
source-refs/sanmopia_web/static/css/mypage.css:1-130,source-refs/sanmopia_web/application/views/mypage/daily_report.php:1-197,source-refs/sanmopia-manager/application/views/report/report.php:1-137. - Printable output relies on fixed spreadsheet coordinates, static PDFs, ZIP assembly, and network conversion. Evidence:
source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:3914-4199,source-refs/sanmopia-admin/application/models/Spreadsheet_model.php:4284-4598. - Modern docs and tests already point toward HTML/PDF render requests, A4 repeat sections, stored templates, and stored artifacts. Evidence:
apps/docs/src/content/docs/migration-source-map/sanmopia-feature-backlog.md:502-542,apps/docs/src/content/docs/frontend/document-output-ux.mdx:15-50,backend-repo/src/sanmopia_modernization/adapters/document_reporting/features/printable_document/html_print_renderer.py:7-155,backend-repo/src/sanmopia_modernization/adapters/document_reporting/features/printable_document/html_print_renderer_test.py:22-129,backend-repo/src/sanmopia_modernization/adapters/document_reporting/features/printable_document/supabase_printable_template_test.py:94-139,contract-repo/packages/ts-client/src/types/document-reporting_test.ts:250-333,frontend-repo/src/features/document-center/document-center-view-model.ts:33-840.
Replacement candidates:
- Use Jinja2 plus WeasyPrint as the server-side PDF baseline for deterministic A4 artifacts and testable HTML templates.
- Use Paged.js for browser preview and standard A4 print behavior in the document center.
- Use Vivliostyle for long report series with repeat sections that must flow across pages.
- Keep browser print CSS and print-js as a fallback path only, not the canonical renderer.
- Use object storage for source templates, rendered HTML, rendered PDF, and bundle artifacts.
- Keep office-based conversion only as a transitional compatibility bridge for imported spreadsheet templates. It should not be the target renderer for new templates.
Top Gaps For Migration Backlog
Section titled “Top Gaps For Migration Backlog”- Unify customer-visible documents, admin export-only documents, receipts, service records, daily surveys, and caregiver reports under a single document catalog.
- Replace token-only live PDF generation with access grants over persisted artifacts and signed object URLs.
- Convert receipt display from gateway-only view behavior into a receipt artifact/access model tied to payment ledger state.
- Replace positional template IDs and mixed XLSX/PDF static files with a versioned template registry and migration manifest.
- Replace live ZIP generation with bundle artifacts that reference rendered artifact IDs and expose missing/ineligible item diagnostics.
- Model daily report obligations, submissions, and service records as role-scoped service-date records, including sub-caregiver variants.
- Standardize A4 HTML/PDF rendering with repeat-section support and stored artifacts before migrating fixed spreadsheet templates.