Skip to content

DDD Application Contract Folder Audit

Audit date: 2026-07-05 KST.

Source of truth: standard.md. Fixed architecture priority is DDD, bounded context, feature slice, CQRS, contract-first, Tach boundaries, and Supabase-first platform choices.

Inspected scope:

  • backend-repo/src/sanmopia_modernization/application
  • backend-repo/src/sanmopia_modernization/adapters as current infrastructure surface. Requested backend-repo/src/sanmopia_modernization/infrastructure does not exist.
  • contract-repo/schemas
  • contract-repo/openapi
  • backend-repo/tach.toml

Not run: full pytest. Not edited: backend, contract, frontend. Existing backend and contract dirty work was left untouched.

SurfaceObserved
Application Python files416
Application feature folders70
Adapter Python files273
Adapter feature folders33
Contract JSON schemas105
Public OpenAPI paths / operations69 paths / 68 operations
Internal OpenAPI paths / operations3 paths / 3 operations
Tach dependency/interface gatetach check --dependencies --interfaces --exact passed
Tach external gateParent verification uv run tach check-external passed
  1. Infrastructure naming drift exists. The task asked for infrastructure/, the repo uses adapters/, and standard.md contains both adapter-shaped backend trees and final wording that says infrastructure. Decide one canonical term before tightening Tach layers.
  2. Tach does not cover all adapter contexts. tach.toml has modules for broad adapters, branch_operations, platform, document_reporting, care_delivery, and pricing_settlement, but no modules for current adapters.customer_engagement, member_management, reservation_booking, reservation_operations, caregiver_assignment, service_calendar, notification, or flat reservation.
  3. External dependency metadata needs continued watch. Worker-local audit initially flagged ReState/OTEL metadata drift, but parent verification on the current worktree passed uv run tach check-external. Keep ReState/OTEL imports behind platform adapters and rerun the parent gate after Tach module expansion.
  4. Application has no direct application -> adapters/interfaces imports, which is good. The first payment provider naming leak was reduced on 2026-07-05: the application port is now application/pricing_settlement/features/payment/payment_gateway_client.py, with PaymentGatewayClient and PaymentGatewayResult names. Remaining provider names should stay in provider adapters, internal APIs, webhooks, and source-evidence docs only.
  5. Contract folder aliases are now explicit in scripts/check_contract_layout.mjs. reservation-settlement is a stable public API alias for backend pricing_settlement; reservation-booking spans reservation_orchestration and reservation_operations; and caregiver-portal maps to care_delivery caregiver work-schedule projections. New schema groups must declare their backend-context alias.
  6. Contract $id drift was resolved on 2026-07-05. Schema ids now use canonical https://contracts.sanmopia.local/schemas/<schema-relative-path>, and scripts/check_contract_layout.mjs rejects mismatched $id values.
  7. OpenAPI auth scheme drift was resolved on 2026-07-05. Components define supabaseBearerAuth, /killbill-payment-admin-operations now uses that same scheme, and scripts/check_contract_layout.mjs rejects undefined OpenAPI security scheme references in public and internal API specs.
  8. Campaign publication domain storage validation was reduced on 2026-07-05: campaign_publication.py now validates provider-neutral managed storage artifact references instead of Supabase-specific media URLs. Supabase object mapping remains an adapter/CMS concern.
FolderFindingBoundary / CQRS action
application/branch_operationsGood context/features shape. Contract group branch-operations exists.Keep command-style branch mutations separate from profile/snapshot reads.
application/business_reportingReporting context exists, but no matching contract schema group.Add contract group only for public reporting API. Otherwise keep internal read models out of contract repo.
application/care_deliveryBroad context with daily report, attendance, confirmation, notification obligation, and caregiver work schedule.Split read projections such as caregiver_work_schedule from write commands such as attendance/report submission.
application/caregiver_assignmentMatching feature contains repository/query ports and contracts.Separate optimizer input query models from command-side snapshot persistence ports.
application/caregiver_managementSmall credential dossier slice. No matching contract group.If exposed externally, create caregiver-management schemas; otherwise keep internal.
application/caregiver_performance_recognitionSeparate context exists while care_delivery/features/caregiver_performance_recognition also exists.Resolve duplicate bounded-context ownership before adding more scorecard/grade APIs.
application/content_managementAttachment lifecycle context exists, but no matching contract group.Decide if this belongs under customer_engagement/content_authoring or remains independent content context.
application/customer_engagementCampaign, guidance, communication, authoring, and lead intake live together. Communication code has Novu vocabulary in application contracts/tests.Keep provider-specific Novu concerns in adapters; expose generic communication dispatch ports from application.
application/document_reportingMature feature-slice shape around catalog, delivery, document room, printable document, and access.Split document read catalogs/rooms from signed-access and render commands.
application/member_managementFamily account and privacy lifecycle exist. Contract group member-management exists. Privacy lifecycle mixes plan, purge workflow, repair history, and receipt projection.Split member withdrawal command, receipt query, purge workflow, and repair command files.
application/migration_governanceSource evidence reconciliation exists. Internal OpenAPI has source evidence endpoint.Keep internal-only; avoid public contract expansion unless migration evidence becomes product API.
application/operator_accessOperator identity session exists without contract group.Decide whether this is auth/session bounded context or platform concern.
application/platformSupabase platform ports exist, but OPA, SpiceDB, and Restate vocabulary also live in application platform.Supabase-first exception required for OPA/SpiceDB/ReState. Keep concrete HTTP and SDK details in adapters.
application/pricing_settlementLargest app area. Payment and settlement carry many commands, workflows, read models, contracts, and provider events. Contract group reservation-settlement is an explicit stable public alias for this backend context.High priority CQRS split: payment commands/events, payment queries/projections, settlement commands, settlement read boards, export workflows.
application/reservation_operationsWide operational context with booking facts, collaboration, service calendar, suspension, admin lifecycle, continuation.Split collaboration command/query, service calendar read model vs decisions, suspension command vs persistence port.
application/reservation_orchestrationCross-context orchestration imports many domains and the provider-neutral PaymentGatewayClient application port. Tach explicitly allows pricing_settlement.features.payment.Treat as process manager. Keep only orchestration commands/workflows here; avoid owning payment provider or adapter details.
application/service_calendarSeparate service calendar context exists while reservation operations also owns service-calendar features.Resolve ownership: shared calendar policy context or reservation-scoped calendar feature, not both without clear rule.
application/shared_kernelSmall shared reference model.Keep small. Do not let shared kernel become cross-context dumping ground.

Application checks:

  • No direct imports from sanmopia_modernization.adapters or sanmopia_modernization.interfaces were found under application/.
  • *_persistence.py and repository files checked in sampled slices are Protocol ports, not concrete SQL/Supabase implementations. Keep that rule.
  • test_*.py files were not found in scoped application/adapters paths; *_test.py naming is used.

2026-07-05 CaveCrew follow-up queue:

FolderDriftTarget
application/platformSupabase/SpiceDB/ReState names define application ports and types.Rename toward WorkflowPort, AuthorizationPort, QueuePort, and keep provider implementations in adapters.
application/customer_engagement/features/communication_deliveryWorkflow catalog validates Supabase row, Strapi authoring, and Novu workflow terms together.Split provider-neutral CommunicationWorkflowCatalog from CommunicationProviderSeedAdapter.
application/pricing_settlement/features/paymentKill Bill ExtBusEvent normalization, internal callback admission, atomic Supabase inbox/PGMQ registration, conflict quarantine, and gateway orchestration share one application slice. Kill Bill provides no callback signature.Keep provider payload parsing in adapter ACL, application acceptance/ingestion in the payment feature, and business payment/refund decisions in domain/application policies. Extract a provider-neutral inbox only when a second provider proves shared semantics.
application/pricing_settlement/features/financial_lifecycleMother-visible charges, payment totals, discounts, balances, and mismatch calculations live in application read model code.Promote arithmetic to domain CustomerChargePaymentProjectionService; application maps query output only.
application/pricing_settlement/features/settlementSettlement arithmetic repeats across contract validators, operator-board reads, and calculation snapshots.Promote SettlementArithmeticService and BranchSettlementCalculator; contracts display validated facts.
application/member_management/features/member_privacy_lifecycle and settlement workflowsstart/transition/fail/complete workflow patterns repeat.Extract provider-neutral DurableWorkflowLifecycle port/service and let slices provide payload/action policy.
application/branch_operations/features/office_profileProfile update, lifecycle, settlement account, fee policy, credential, and query share one contract surface.Split into office_profile_update, settlement_account, membership_fee_policy, operator_credential, and office_profile_query.
application/pricing_settlement/features/settlement_data_room_workspaceMany commands, query handler, grant, repair, and build concerns share one file; DataRoom/Workspace is weak domain language.Split artifact request/build/grant/handoff/query/repair slices; domain target is SettlementArtifactCollection.
application/reservation_operations/features/reservation_collaborationOpen workspace query, journal query, and browser-event command are mixed.Split open_workspace_query, collaboration_journal_query, and record_workspace_event_command.
application/caregiver_assignment/features/care_team_contractcare_team_contract/care_team_contract_contract.py repeats contract terminology.Rename payload file or feature toward care_team_contracting; keep domain contract and application payload distinct.
FolderFindingBoundary / Supabase-first action
adapters/branch_operationsMostly context/features aligned, Supabase-backed. Tach covers this broad context.Keep aligned with application/branch_operations/features/*.
adapters/care_deliveryContext/features aligned, Supabase-backed. Tach blocks care delivery adapters from pricing app/adapters.Good guardrail. Extend same pattern to other adapter contexts.
adapters/caregiver_assignmentMatching adapters exist, but Tach has no explicit module for this adapter context.Add Tach module and block unrelated adapter contexts.
adapters/customer_engagementCommunication delivery mixes Supabase persistence and Novu HTTP adapter. It imports pricing payment application types and payment adapter row helpers.Add Tach module. Keep cross-context payment facts behind application ports or shared contract DTOs.
adapters/document_reportingContext/features aligned. Contains Supabase document adapters and HTML print renderer. Tach covers broad document reporting adapter.Keep renderer as infrastructure. Ensure storage/output remains Supabase Storage first.
adapters/member_managementFamily account and privacy lifecycle Supabase adapters exist, but Tach has no explicit module.Add Tach module and make privacy lifecycle workflow boundaries explicit.
adapters/notificationFlat in_memory_notification_gateway.py; no bounded context/features shape.Move to test/support or create owned notification adapter context with Tach boundary.
adapters/platformSupabase HTTP plus OPA, SpiceDB, Restate, OTEL adapters.Supabase-first exceptions need ADRs. Tach should separate platform ports from concrete external provider adapters.
adapters/pricing_settlementRich feature adapters for payment, settlement, financial lifecycle, pricing, imports. Tach covers several pricing subfeatures.Continue subfeature Tach coverage; check KillBill adapter isolation and avoid leaking provider types into application APIs.
adapters/reservationFlat repository/schema files outside context/features.Move under adapters/reservation_operations/features/reservation or mark legacy with migration checklist.
adapters/reservation_bookingFlat composition root and stores. Imports interfaces.reservation_booking_api, pricing payment app ports, and reservation orchestration app service. Tach has no module.High risk. Move toward adapters/reservation_orchestration/features/reservation_booking or define reservation_booking bounded context consistently across app/domain/contracts/Tach.
adapters/reservation_operationsFeature adapters exist, including OR-Tools matching and Supabase service calendar/read models. Tach has no explicit module.Add Tach module. Treat OR-Tools as compute adapter, not data-platform replacement.
adapters/service_calendarHoliday audit Supabase adapters exist. Tach has no explicit module.Add Tach module after service-calendar ownership decision.
FolderFindingAction
schemas/branch-operationsMatches backend branch_operations.Good; keep schema IDs normalized.
schemas/care-deliveryMatches backend care_delivery but only small coverage.Add only externally exposed care-delivery schemas; avoid dumping every internal model.
schemas/caregiver-portalStable public portal alias mapped to backend care_delivery caregiver work-schedule projection.Keep alias mapped in layout:check; split later only if caregiver portal grows beyond care-delivery read models.
schemas/commonShared money schema.Keep small and versioned.
schemas/member-managementMatches backend context; $id host/path is normalized and guarded.Keep schema ids path-derived.
schemas/reservation-bookingStable public booking alias mapped to backend reservation_orchestration and reservation_operations.Keep alias mapped in layout:check; split later if command/process-manager contracts diverge from reservation-operation read models.
schemas/reservation-settlementStable public settlement alias mapped to backend pricing_settlement. Most OpenAPI refs point here.Keep alias mapped in layout:check; do not introduce pricing-settlement without a migration plan for public refs and generated clients.
schemas/workflow-statusPlatform workflow projection schema.Keep platform-facing; avoid leaking ReState if workflow engine can change.
openapi/public-api.yamlCustomer, branch, operator, and workflow-facing operations only. layout:check rejects provider/internal KillBill paths here.Keep provider webhook/admin paths out of the public API.
openapi/internal-api.yamlInternal settlement build/ready-artifact operations, source evidence, and provider-owned KillBill webhook/admin operations.Keep provider-specific operations here unless a separate provider API spec is introduced.

Missing OpenAPI refs: none found.

Prioritize these because they mix commands, queries, workflows, provider events, contracts, and persistence ports inside one feature folder:

CandidateWhy splitSuggested split
application/pricing_settlement/features/settlement38 files; commands, read boards, export workflow, data room, statements, contracts.commands/*, queries/*, workflows/reconciliation_export, contracts/*, then map adapters one-to-one.
application/pricing_settlement/features/paymentPayment pre-registration, receipts, change adjustment, workflow, provider event/admin operations. The payment gateway port is now provider-neutral; KillBill remains adapter/internal-provider vocabulary.Payment command handlers, payment read models, provider webhook ingestion, workflow start/status.
application/member_management/features/member_privacy_lifecycleWithdrawal planning, receipt status, purge workflow, repair history.Withdrawal command, receipt query, purge workflow, repair command.
application/reservation_operations/features/reservation_collaborationOpen workspace, events, journal, commit, conflict resolution.Workspace query/read model, event command, commit command, conflict command.
application/reservation_operations/features/service_calendarCompatibility decisions, snapshots, policy profile, impact query, holiday provider.Calendar impact query, compatibility decision command, policy profile read model.
application/service_calendar/features/holiday_auditCommand, contract, persistence port, decision, impact preview.Audit command, impact preview query, publication decision, persistence port.
application/reservation_orchestration/features/reservation_operation_commandCommand board and follow-up workflow share one feature.Command-board query, operation advance command, follow-up workflow.
application/caregiver_assignment/features/caregiver_matchingCandidate snapshot repository, matching policy query, contracts.Matching query/read model, snapshot persistence port, matching command if mutation exists.
application/customer_engagement/features/communication_deliveryWorkflow catalog, dispatch planning, payment dispatch side effects, Novu provider vocabulary.Workflow catalog query, dispatch command, provider-neutral delivery result read model.

These are read-only audit findings from the 2026-07-05 folder pass. Each item is an implementation queue entry, not a decision to copy source structure.

PriorityFindingPromotion target
P0Actor vocabulary split across hq_admin, headquarters_admin, headquarters_administrator, branch_operator, branch_manager, and branch_owner.shared_kernel / ActorKindAliasCatalog plus context-specific capability policies.
P0Settlement data-room API still accepts request-side actor identity and raw export format strings.SettlementActorContextResolver and SettlementDataRoomExportFormat.
P0Payment delegation exists, but payment-change/refund authority remains mother/requester-centric.PaymentParticipantAuthority and RefundRecipientAuthority.
P0Reservation lifecycle predicates are reimplemented as raw string sets in care-delivery projections.ReservationLifecyclePredicate read policy.
P1Branch coverage has parallel service-area, managed-area, office-profile, and matching-area models.BranchCoverageDecision and AddressScopeKey owned by branch_operations.
P1Caregiver matching vocabulary still uses CandidateRankingPolicy, while checklist uses CaregiverCandidateOrderingPolicy; the public backend and contract travel-time weight is now standardized as travel_duration_minutes_weight / travelDurationMinutesWeight, with legacy Supabase storage column mapping isolated in the adapter.Decide whether the ubiquitous name should be CaregiverCandidateOrderingPolicy and rename the remaining ranking-policy symbol family in one backend/contract pass.
P1Care-team assignment, payout acknowledgement, payout adjustment, destination change, and admin payout projection were importing a reservation-booking SpiceDB permission helper from settlement-named settlement_actor_authorization.Resolved 2026-07-07 by backend commit 38dd9ec: generic interfaces.reservation_booking_authorization.has_reservation_booking_permission owns reservation-booking object checks, while settlement_actor_authorization keeps only settlement actor-kind helpers.
P1Document render queue consumption needed application printable contracts from a Supabase service-use-contract adapter, but the printable application slice was not declared as an explicit Tach module.Resolved 2026-07-07 by backend commit 3cdc86a: application.document_reporting.features.printable_document is a declared feature slice, the Supabase adapter depends on that slice explicitly, and the service-use-contract application command stays platform-neutral while queue payload parsing remains in the adapter.
P1Care team role value object is bypassed by raw caregiver_role strings in care delivery.Exported CareTeamMemberRole consumed by care-delivery projections.
P1Document delivery/grant flows use multiple actor vocabularies and raw boundary strings.DocumentAuthorityActor shared with family/proxy/payment authority.
AreaFindingTarget
Domain/application provider leakdomain/operator_access/features/operator_identity_session/operator_identity_session.py had SupabaseIdentityMetadataFact, SpiceDbRelationshipFact, OpaStatusGateFact, and app_metadata vocabulary.Renamed to IdentityAuthorizationMetadataFact, AuthorizationRelationshipFact, PolicyStatusGateFact, and authorization_metadata; provider mapping stays in platform/interface/adapters.
Domain provider leakdomain/pricing_settlement/features/payment/payment_refund.py previously exposed KillBillRefundCommand with adapter HTTP method/path/body shape.Renamed to provider-neutral PaymentRefundGatewayCommand; adapter now owns KillBill payload construction. 2026-07-05 follow-up renamed the persisted refund command column to billing_gateway_refund_command and keeps Kill Bill payload shape inside the Supabase adapter/provider boundary.
Domain/application provider leakdomain/pricing_settlement/features/payment/killbill_admin_operation.py and the matching application use case used provider brand as core vocabulary.Renamed domain/application files and symbols to PaymentProviderAdminOperation*; KillBill-specific gateway/store names remain in adapters and internal provider API. Remaining work: interface facade and persisted DB naming migration.
Source-era settlement vocabulary leakSettlement board transition provenance and matching application contract exposed source-era labels as core naming.Renamed to SettlementBoardTransitionProvenance, ImportedSettlementBoardTransitionRow, source_branch_marker, and settlement_board_statuses; source evidence stays explicit in import rows, while domain/application contract language stays modern.
Domain provider leakdomain/customer_engagement/features/campaign_publication/campaign_publication.py validated supabase:// media references directly.Renamed the rule to managed storage artifact references and allowed provider-neutral artifact:// / storage:// refs. CMS/Supabase object mapping stays in adapters.
Domain CQRS driftdomain/pricing_settlement/features/settlement/cqrs/{commands.py,queries.py} stores command/query DTOs in domain.Move application DTOs to application/pricing_settlement/features/settlement; keep domain policy value objects only.
Domain command driftdomain/document_reporting/features/branch_resource_post/branch_resource_post.py duplicates application command payloads.Application commands plus mapper; domain BranchResourcePostDraft and BranchResourceAttachmentChange.
Legacy status leakdomain/shared_kernel/features/reservation_lifecycle/source_reservation_status.py and reservation state transition expose source status.Core ReservationLifecycleStatus; source-code mapper in migration anti-corruption layer.
Duplicated bounded contextdomain/care_delivery/features/caregiver_assignment duplicates domain/caregiver_assignment.caregiver_assignment owns assignment; care delivery emits assignment facts.
Duplicated bounded contextdomain/care_delivery/features/caregiver_performance_recognition duplicates domain/caregiver_performance_recognition.caregiver_performance_recognition owns grades/scorecards; care delivery emits performance facts.
Calendar ownershipdomain/reservation_operations/features/service_calendar overlaps domain/service_calendar/features/holiday_audit.service_calendar owns holiday/policy; reservation operations consumes reservation-scoped calendar policy.
Application context gapapplication/reservation_orchestration has no matching domain bounded context.Fold process manager into reservation_operations or add a real domain/reservation_orchestration.
Oversized use caseapplication/reservation_orchestration/features/reservation_booking/booking.py has a large ReservationBooking orchestration service.Split into BookReservationUseCase plus process-manager steps: pricing, payment, notification, content/statistics projections.
CQRS naming driftGetReservationOperationBoardCommand, ReadRecipientDocumentAccessHistoryCommand, and settlement data-room *LookupKeyCommand are reads.Rename to *Query or *Selection and separate read handlers.
Platform provider leakapplication/platform/supabase_*.py, spicedb_*.py, restate_workflow.py expose provider names in application ports.Provider-neutral AuthPort, RelationshipAuthorizationPort, WorkflowEnginePort; SDK details in adapters/platform.
Interface provider leakKillBill admin/event API names, public Restate status fields, Supabase/SpiceDB API payload names, and source address-provider fields.Daum/Kakao branch service-area address fields were neutralized on 2026-07-05 with addressEvidenceSourceKind and evidencePayloadFingerprint; remaining public/operator APIs should keep provider evidence internal-only.
DB contract leakSupabase migrations still persist sanmopia_killbill_admin_operation_audits; refund ledger command storage now uses billing_gateway_refund_command.New tables/columns should use provider-neutral names such as payment_provider_admin_operation_audits and billing_gateway_refund_command; old provider-branded table names need a migration plan.
Duplicate adapter mapping67 local row coercion clones remain despite adapters/platform/supabase_row_value.py.Promote to shared row codec helpers and feature-specific mappers only.
Duplicate settlement audit insertjsonb_to_recordset(p_transition_audits) insert blocks repeat across settlement migrations.append_settlement_transition_event() / SettlementTransitionEventLedger.
Duplicate payout event mappingCaregiver payout acknowledgement, adjustment, and destination-change adapters repeat audit/event mapping.CaregiverPayoutChangeEvent and PayoutInstructionTargetMapper.
  • Decide adapters vs infrastructure naming, then update standard.md, tach.toml, docs, and folders consistently.
  • Add explicit Tach modules for every live adapter context, especially adapters.reservation_booking and adapters.customer_engagement.
  • Add feature-level Tach modules for read/write-heavy slices before more code is migrated: pricing_settlement/payment_conversion, pricing_settlement/reservation_price_version_adjustment, pricing_settlement/settlement_data_room_workspace, reservation_operations/customer_action_availability, reservation_operations/customer_reservation_lifecycle_view, reservation_operations/reservation_collaboration, and reservation_operations/reservation_continuation.
  • Add Tach checks that forbid flat adapter folders except documented platform support modules.
  • Decide if reservation_booking is a bounded context, an orchestration feature, or an API adapter. Current repo uses all three meanings.
  • Keep payment provider ports provider-neutral. The application payment port was renamed to PaymentGatewayClient; next cleanup is moving the concrete DebugPaymentGatewayClient fake out of the application layer or documenting it as test-support composition.
  • Replace provider/runtime vocabulary in public/internal interface names: /killbill-payment-admin-operations, attach_killbill_payment_event_http_routes, public restate DTO fields, and provider-shaped branch service area payloads.
  • Deduplicate adapter mapping code. Highest-impact targets are Supabase row coercion clones, settlement transition audit insert blocks, and caregiver payout audit/event mappers.
  • Keep workflow kinds in one source. workflow_status_http.py and supabase_workflow_status_projection.py currently disagree on reservation_operation_follow_up.
  • Keep OPA, SpiceDB, ReState, KillBill, Novu, and OR-Tools as explicit exceptions. None should silently become default platform choices under Supabase-first rules.
  • Reconcile Pydantic application contract models with JSON Schema contract repo. Contract repo should remain API SSOT; backend models should be generated or compatibility-checked against schemas.
  • Keep contract schema group aliases mapped in layout:check; add no new schema group without an explicit backend bounded-context owner.
  • Keep schema $id values path-derived and guarded by layout:check.
  • Keep OpenAPI auth scheme references guarded by layout:check; do not add provider-specific schemes without defining them in the same API spec.
  • Keep provider/internal KillBill webhook/admin endpoints out of public-api.yaml; layout:check enforces this split.
  • Keep CQRS shape consistent. Either standardize large application slices on features/<feature>/cqrs/{commands,queries}.py or keep suffix-only command/query modules and remove one-off CQRS folders. Do not mix both patterns without a documented feature-level reason.
  • Keep UI-side calculations out of frontend migrations. Booking, payment, settlement, and document workspaces should request backend projections or command payload builders; frontend state stores may assemble existing backend contract fields but must not recompute money, status, or eligibility.
  • Pick canonical infrastructure folder term: adapters or infrastructure.
  • Remove or document the non-existing backend-repo/src/.../infrastructure assumption.
  • Add exact = true, layers_explicit_depends_on = true, and layer names to tach.toml if config should match standard.md directly.
  • Add Tach modules for all live adapter contexts.
  • Add Tach modules for high-risk feature slices found in the 2026-07-05 DDD follow-up audit.
  • Keep tach check-external green after ReState/OTEL/platform Tach module expansion.
  • Rename payment application provider port to provider-neutral PaymentGatewayClient / PaymentGatewayResult.
  • Neutralize campaign publication storage validation so domain rules do not require Supabase-specific object schemes.
  • Add Tach guard for application provider names: no concrete provider class names unless file is a provider-neutral port with no implementation.
  • Split high-risk CQRS folders listed above.
  • Move concrete debug/test adapters out of application layer.
  • Rename or isolate provider/runtime API vocabulary in public interfaces and DB contracts: KillBill webhook/admin, ReState status payloads, Supabase/SpiceDB identity port names, Daum/Kakao address source fields, and raw provider payment method literals.
  • Promote duplicate adapter helpers: SupabaseRowValue, settlement transition append, and caregiver payout event mapping.
  • Align contract schema group names with bounded-context names or document stable public aliases, with layout:check enforcement.
  • Normalize all schema $id hosts to one contract host and one /schemas/ path style, with layout:check enforcement.
  • Fix OpenAPI undefined bearerAuth and add layout:check guard for undefined security scheme references.
  • Move provider webhook/admin operations to internal-api.yaml; future separate provider API must replace, not duplicate, that ownership.
  • Add contract compatibility tests that compare backend application contract models to contract-repo/schemas.
  • Add migration checklist item for every external-platform exception: reason, owner, Supabase alternative considered, and rollback path.
  • Keep frontend untouched for this audit.
Terminal window
sed -n '1,1700p' standard.md
find backend-repo/src/sanmopia_modernization/application -path '*/__pycache__' -prune -o -type f -name '*.py' -print
find backend-repo/src/sanmopia_modernization/adapters -path '*/__pycache__' -prune -o -type f -name '*.py' -print
find contract-repo/schemas contract-repo/openapi -type f -print
tach check --dependencies --interfaces --exact
tach check-external
rg -n "sanmopia_modernization\\.(adapters|interfaces)" backend-repo/src/sanmopia_modernization/application
rg -n "bearerAuth|supabaseBearerAuth" contract-repo/openapi/public-api.yaml contract-repo/openapi/internal-api.yaml
rg -n "/killbill-payment" contract-repo/openapi/public-api.yaml contract-repo/openapi/internal-api.yaml
rg -n "contracts\\.sanmopia\\.yamon\\.io|contract\\.sanmopia\\.local|contracts\\.sanmopia\\.local/(reservation-|member-|branch-|workflow-|care-)" contract-repo/schemas
pnpm layout:check
pnpm check