Skip to content
Small robotic builders connect a purchase event, a product BOM, a plan revision, visit items, and resource allocations into one business flow
A product BOM does not put a visit on the calendar by itself. The purchase contract must be preserved as a plan, and visit candidates and item-level resources must be calculated from that plan.

The previous article turned Patient A’s package into an execution graph connecting consultation, examination, treatment, and follow-up. This article follows how that graph is translated into real reservation models.

The first step is to keep four facts separate:

Purchase-completed event ≠ product BOM event ≠ AppointmentPlan revision ≠ confirmed visit commitment

A purchase is the beginning of a contract. The product BOM fixes which treatment items should be performed and how they relate. An AppointmentPlan preserves the fulfillment obligations of one purchase, while an Appointment represents one physical visit. Agreement to come at a specific time belongs to a separate commitment axis.

Assume Patient A buys a package that follows consultation → examination → main treatment → follow-up. The names and clinic policies are generalized; only the scheduling structure matters.

TimePatient A’s action or eventBusiness meaningWhat the appointment service preserves
T1Buys the package and completes paymentA purchase contract existssourcePurchaseAuthority, purchase ID, clinic scope, and product version at purchase time
T2A purchase-completed event reaches the appointment serviceThe purchase contract is connected to a plan rootAppointmentPlan, catalog version and payload hash, repeated items, and dependencies
T3Product or purchasing publishes a product BOM with choices and repetition expandedThe work to be performed is fixedPackageExecutionSnapshot, component versions, choices, and snapshotHash
T4The product BOM event convergesA new execution revision is appended to the existing planPlannedTreatment, dependencies, visit-grouping constraints, and revision history
T5Visit candidates are calculatedThe service decides what can share a visit and what must be separatedProposed times, item-level resource candidates, and a policy snapshot
T6Patient and clinic agree on the scheduleA specific time, item set, and resources become a commitmentAppointment, AppointmentItem, ResourceAllocation, and commitment status
T7An item completes or the schedule breaksCompleted facts and unfinished work are separatedCompletion provenance, a new attempt, and follow-up proposal history

If T2 and T4 become one write, the purchase contract and the execution contract owned by the product or purchasing service become indistinguishable. If T6 is performed in the same step, “a plan exists” is incorrectly read as “the patient agreed to come at a specific time.”

authority identifies the owner of a source fact

Section titled “authority identifies the owner of a source fact”

Here, authority is not a login role or a permission tier. It is the stable identifier of the system that publishes and owns a source fact. The same purchase or product ID can exist in several clinics and services, so an ID alone cannot identify its origin.

Identity scopeRepresentative fieldsQuestion answered
Purchase facttenantGroupId + clinicId + sourcePurchaseAuthority + sourcePurchaseIdWhich service owns this purchase contract in which clinic scope?
Product sourcecatalogSourceAuthority + productId + catalogVersionWhich product owner published which version?
Execution contractpackageProductVersionId + selected component versions + snapshotHashWhich BOM was fixed for this purchase?
Visit commitmentproposalId + revision + proposal hash + consent evidenceWhich exact terms did patient and clinic accept?

The service therefore never finds a plan using sourcePurchaseId=42 alone. Tenant, clinic, and authority must match first. A different payload under the same authority is a conflict or quarantine candidate, not a successful replay. This is why the appointment service does not reinterpret product-management or purchasing source data.

First translation: from a purchase event to AppointmentPlan

Section titled “First translation: from a purchase event to AppointmentPlan”

In the current foundation, PurchaseCompletedHandler receives the purchase-completed event, checks the active catalog projection, and uses the deterministic AppointmentPlanFactory to create a plan aggregate draft. The factory performs no I/O and does not confirm a booking time.

The plan root keeps these facts together:

Preserved valueBusiness meaning
sourcePurchaseAuthority, sourcePurchaseIdThe source scope of the purchase that created the plan
catalogSourceAuthority, productId, catalogVersionThe product source used to create the plan
catalogPayloadHashA hash for verifying replay against the same catalog snapshot
bookingPreferenceA patient preference captured at purchase time, not a confirmed time
PlannedTreatmentFulfillment obligations expanded from BOM items by repetition count
TreatmentDependencyPredecessor, successor, and interval relationships

A catalog repeatCount=5 becomes five PlannedTreatment records. Each keeps its sequence number, display treatment, detailed codes, expected duration, practitioner qualifications, equipment, and room requirements. The service does not store the package as “180 minutes,” because consultation rooms, procedure rooms, and recovery spaces can occupy different intervals and resources.

The result is an ACTIVE plan with PLANNED obligations. It is not an Appointment, a resource hold, or patient consent yet.

Second translation: from a product BOM to a plan revision

Section titled “Second translation: from a product BOM to a plan revision”

Product management or purchasing expands package choices and repetition at purchase time. The appointment service does not recursively fetch the original product later and rebuild it from the latest catalog. The publisher sends an immutable execution contract as a PackageExecutionSnapshot.

The snapshot groups these inputs:

Execution-contract partWhy scheduling needs it
Exact package and component versionsPrevents a later catalog change from rewriting an existing purchase
Selected components and quantitiesFreezes the M-of-N choice and repetition count in the contract
Expanded ExecutionTreatment recordsPreserves preparation, treatment, recovery, and resource provenance per item
BLOCKING and NON_BLOCKING dependenciesSeparates the effect of a completion fact on later work
MUST_SAME_VISIT, MAY_SAME_VISIT, and MUST_SEPARATE_VISITPreserves a visit-grouping axis distinct from execution dependency
snapshotHashVerifies that the payload for a source version is the same execution contract
A package product containing consultation, examination, treatment, soothing care, and follow-up becomes a product BOM snapshot, an AppointmentPlan revision, PlannedTreatment records, AppointmentItems, and a physical visit
The product BOM is the composition contract frozen at purchase time. The appointment service expands that contract into a plan and item-level visit units without redefining its meaning.

PackageExecutionPlanner validates selection counts, repetition, item and edge limits, provenance, references, and cycles. It then copies the validated snapshot into an AppointmentPlanRevisionDraft. This is not code that decides what a product “should mean”; it verifies and preserves the contract already published by the product or purchasing service.

VisitPlanningEventHandler finds the existing plan in the authority-qualified purchase scope and appends the draft as a new revision. Replaying the same source version and payload hash converges to a duplicate. A different hash for the same version, or an event that arrives out of order, is quarantined or held for a bounded gap retry instead of being treated as success. The inbox, revision rows, outbox, and processed marker converge within one transaction boundary.

The important question is not merely “how do we stop duplicate events?” It is how do we decide that an execution contract is the next revision of the same purchase? Idempotency is the condition that lets that decision be retried safely.

Why AppointmentItem belongs between a plan and a visit

Section titled “Why AppointmentItem belongs between a plan and a visit”

The approved relationship is:

Purchase 1 ──> AppointmentPlan 1 ──> PlanRevision 1..N
└─> PlannedTreatment N
Appointment 1 ──> AppointmentItem N ──> PlannedTreatment 1
└──────────> ResourceAllocation N

AppointmentPlan preserves all fulfillment obligations from one purchase. PlannedTreatment is the executable expansion of those obligations. Appointment is one physical visit, and AppointmentItem records a particular PlannedTreatment being performed or attempted during that visit.

One visit can therefore contain several AppointmentItem records, while one package plan can span several visits. Items from another plan for the same patient can also share a visit when they are clinically compatible and their resources can coexist. The model avoids a direct one-to-many shortcut between a plan and a visit for that reason.

Visit grouping is a separate constraint axis

Section titled “Visit grouping is a separate constraint axis”

Consider Patient A’s execution items:

Execution itemExecution dependencyVisit-grouping hintPossible visit
Pre-treatment consultationNoneMUST_SAME_VISIT with examination is allowedVisit 1
Pre-treatment examinationAfter consultationMUST_SAME_VISIT or separate visitVisit 1 or 2
Main treatmentBLOCKING after examinationMAY_SAME_VISIT with soothing careVisit 2
Soothing careRequires compatible treatment resourcesMAY_SAME_VISIT with main treatmentVisit 2
Follow-up checkInterval after actual treatment completionMUST_SEPARATE_VISITVisit 3

BLOCKING means that an actual completion fact limits the later item’s eligible window. MUST_SAME_VISIT forces a connected component, while MAY_SAME_VISIT remains an optimizer hint. If a required-same component conflicts with a required-separate relation or an incompatible resource pair, the planner rejects the candidate instead of forcing an unsafe grouping.

The natural proposal for Patient A is consultation and examination in visit 1, treatment and soothing care in visit 2, and follow-up in visit 3. If the clinic’s resources and safety rules allow visits 1 and 2 to merge, the items still retain their own preparation, treatment, recovery, and resource requirements.

Compare the package composition in the Package Product Composition companion and the BOM-to-visit expansion in the Product BOM to Appointment Flow companion. These companions explain the approved design; they do not replace the normative Markdown or the source repository.

AppointmentItem and ResourceAllocation explain a real visit

Section titled “AppointmentItem and ResourceAllocation explain a real visit”

If consultation and examination share a visit, the patient-facing label might be “consultation and examination.” Internally, the appointment service still needs two AppointmentItem records and item-level ResourceAllocation records.

ModelBusiness fact preserved
AppointmentThe time and lifecycle unit for one patient visit
AppointmentItemWhich plan revision and treatment obligation was attempted, and which attempt number it was
ResourceAllocationWhich practitioner, equipment, treatment space, or capacity bucket is occupied and when
AppointmentCommitmentWhether a proposal is PROPOSED, HELD, or CONFIRMED for patient and clinic

CONFIRMED combines an exact proposal revision, proposal hash, resource allocation, and patient consent. A new candidate does not clear the existing confirmedProposalId and allocations first. If the candidate fails or the patient declines it, the existing commitment remains protected.

This distinction matters in clinic operations. Consultation may finish while an examination is interrupted by equipment downtime. The main treatment may complete while follow-up remains. If the whole visit is reduced to one completion flag, the next booking and customer counseling services cannot tell which obligation is still open.

Partial completion and product changes do not rewrite history

Section titled “Partial completion and product changes do not rewrite history”

Suppose Patient A’s main treatment completes during visit 2 but soothing care is interrupted. The appointment service:

  1. Freezes the completed AppointmentItem and its clinical provenance.
  2. Calculates remaining work from the unfinished PlannedTreatment only.
  3. Creates a new AppointmentItem attempt when needed and uses the predecessor’s actual completion time for later windows.
  4. Creates a new proposal and resource allocation, then requires patient consent before CONFIRMED.

Product version changes follow the same rule. New purchases can use the new version, but Patient A’s existing plan and completed items are not expanded again from the latest catalog. Only an exceptional product-team transition mapping with customer consent can create a new revision for the same plan, and only unfinished future items are carried forward. Prior revisions and completion facts remain intact.

Service ownership divides at the plan and visit boundary

Section titled “Service ownership divides at the plan and visit boundary”

Putting a product BOM into the appointment service does not transfer ownership of the product definition or the clinical outcome.

Product management and commerce hand product BOM and purchase facts to AppointmentPlan, commitments, and AppointmentItems, while clinical, CRM, notification, and statistics services consume visit facts at their own boundaries
The appointment service owns time, capacity, consent, state, and history. Clinical completion, CRM policy, and notification or statistics consumption remain separate responsibilities.
ServiceSource-of-record factsBoundary with the appointment service
Product management and developmentProduct versions, component graph, BOM, choice and repetition rulesPublishes validated projections and product BOM provenance
Purchasing and commercePurchase contract, choices, refunds, source purchase IDPublishes purchase and refund events and owns the contract
Appointment servicePlans, revisions, proposals, commitments, items, allocationsOwns time, capacity, consent, appointment state, and reservation history
Clinical and treatmentActual start, completion, and partial completionPublishes completion evidence and owns the clinical result
Customer counseling and CRMProfile, counseling, complaints, compensation, service-tier decisionsUses objective no-show, delay, and rescheduling facts for counseling decisions
Notification and statistics consumersContact consent, delivery history, projections, metricsConsume outbox and read models outside the reservation transaction

The appointment service therefore does not invent a permanent blacklist or force-cancel a visit when a patient has repeated no-shows. If a clinic needs different follow-up conditions or a VIP priority policy, CRM and clinic operations define the policy and its evidence. The reservation service protects confirmed commitments and records the inputs and outcomes required by its capacity and safety boundaries. The concrete fairness policy belongs to a later article.

Read current implementation and approved design separately

Section titled “Read current implementation and approved design separately”

Seeing a model name in this article does not mean every path has completed production rollout.

Evidence labelScope used in this article
Current implementationCatalog projections, the purchase-completed Plan factory, PackageExecutionEvent validation and revision append, duplicate/stale/gap/quarantine handling, and their source tests
Approved designMultiple AppointmentItem records in one visit, item-level ResourceAllocation, proposal and consent, commitment states, and post-partial-completion flow
Awaiting operationsBroker transport, live clinical and commerce event integration, outbox canary, and production backfill, replay, and recovery proof
RoadmapA patient channel for choosing later proposals, concrete no-show penalties, and an explainable VIP-priority policy

This article distinguishes the current implementation from the approved design. A persisted plan and a visit confirmed only after capacity and consent checks are separate stages.

Having a plan and visit model does not confirm Patient A’s preferred date. The next article will follow the sequence from a patient’s desired date through a clinic proposal, a resource HELD, consent, and a CONFIRMED commitment.

Comments

Leave a note or reaction with your GitHub account.