Repository navigation
feat(orders): partial fulfilment dispense and route remaining items (… - #168
Conversation
|
@Bolajiomo99 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
|
@Bolajiomo99 Thanks for the PR. It can't be merged yet. To unblock it: Merge conflicts: this branch conflicts with Push to this same branch and CI will re-run. Once it's green and conflict-free, it'll be reviewed for merge. |
|
@Bolajiomo99 This PR now has merge conflicts with git fetch upstream # upstream = https://github.com/DocForum/docforum-web.git
git rebase upstream/main
# resolve the conflicts, re-run the tests, then:
git push --force-with-leaseThe usual culprits are shared docs like Automated message. It won't repeat unless the PR conflicts again after your next push. |
|
@Bolajiomo99 CI is failing on this branch against the latest Frontend (typecheck + test + build)
This PR also conflicts with |
|
@Bolajiomo99 This PR now has merge conflicts with git fetch upstream # upstream = https://github.com/DocForum/docforum-web.git
git rebase upstream/main
# resolve the conflicts, re-run the tests, then:
git push --force-with-leaseThe usual culprits are shared docs like Automated message. It won't repeat unless the PR conflicts again after your next push. |
Resolve conflicts with main, keeping both sides: - src/types/models.ts: drop the duplicate `Order` the branch carried (its services all speak `PatientOrder`), and rename the partial-fulfilment item row to `OrderItemFulfillment` so it no longer collides with main's `OrderItem`. - src/services/orders-service.ts: drop the branch's duplicate `getOrder` (same endpoint as main's, different return type) and keep `getPatientOrder`. - src/features/patient-chart/components/PatientChartPanel.tsx: keep main's order columns — `activeOrders` is main's `Order`, which has no `fulfillmentStatus`. - ROADMAP.md: restore the DocForum#54 item line that the earlier merge of main silently dropped.
…fulfilment # Conflicts: # src/mocks/handlers.test.ts
|
kindly review and merge |
|
@Bolajiomo99 The Browser (journeys + accessibility + visual) job fails the visual regression check: the rendered page no longer matches the committed baseline: If the visual change is intentional, regenerate those baselines in the same Linux/Playwright setup CI uses (see the visual-testing notes in |
🔎 Preview build (downloadable artifact)Download the preview artifact · build log
|
afeezorobsco-cyber
left a comment
There was a problem hiding this comment.
Sweep: malware scan clean, CI green.
feat(orders): partial fulfilment — dispense some items and route the rest elsewhere
Close#54
Closes #54
Summary
This PR implements Phase W4 — Partial fulfilment for DocForum Web.
Facility staff can now dispense an order item by item and quantity by quantity, instead of marking a whole order fulfilled or rejected. Anything a facility cannot supply stays outstanding and the patient can route only those remaining items to another eligible facility from the patient orders screen.
The UI is deliberately conservative about money: it renders the payment-release rule supplied by
docforum-coreand explains the implications, but it does not calculate escrow releases, pro-rate payments, or call Stellar/escrow directly. The exact backend release rule remains owned bydocforum-coreand is still pendingdocforum-core#73.The PR also adds the minimum orders foundations needed by #54 because #5/#8 are not fully implemented yet: patient order list/detail, item-level order models, item-level dispensing, remaining-item routing, and MSW coverage so the flow is testable without a backend.
[Phase W4] Partial fulfilment: dispense some items and route the rest elsewhere77d098afeat/partial-fulfilment-dispense-some-items-and-routemainDocForum/docforum-core#73docforum-core#73is still pending, so order/payment shapes are explicitly marked as assumed contracts.Problem
Before this PR:
fulfilled/rejected).quantityPrescribed,quantityDispensed, orquantityOutstanding./patient/orders.This made partial fulfilment unsafe and impossible: a facility with only part of an order could not record what it actually supplied, and a patient could not recover the remaining items elsewhere.
What changed
1. Item-level fulfilment models
Added/mirrored in
src/types/models.ts:FulfillmentItemStatuswith:partially_dispenseddispensed_elsewhereFulfillmentQueueItemwith:quantityPrescribedquantityDispensedquantityOutstandingunitcanDispenseblockedReasondispensedByFacilityIddispensedByFacilityNameorderItemId(links a facility queue row to the patient’s order item)PartialFulfillmentStatusOrderItemFulfillmentStatusOrderItemOrderPaymentSummaryPatientOrderDispenseFulfillmentItemInputRouteRemainingItemsInputOrderwith optionalfulfillmentStatusanditemsso existing patient-chart order tables can display partial status.2. Facility-side partial dispensing
New feature area:
src/features/fulfillment/FacilityFulfillmentQueuedispensed_elsewhereitems and disables any further dispensing.blockedReasonfor routed/blocked items.src/features/fulfillment/status.tsitemFulfillmentStatusderiveOrderFulfillmentStatusITEM_STATUS_LABELSuseDispenseFulfillmentItemFacility dashboard (
/facility) now uses the new per-item queue instead of the whole-order action UI. Existing whole-order attribution behaviour and tests are preserved.3. Patient order list and detail
New feature area additions:
src/features/orders/PatientOrdersListat/patient/ordersUnfulfilled,Partially filled,Fulfilled,Rejected).PatientOrderDetailat/patient/orders/:orderIdRemainingItemsFacilityPicker409conflicts explicitly: if another facility already dispensed or another client already routed an item, it asks the patient to refresh and shows the latest state.4. API service layer
Added:
src/services/fulfillment-service.tsdispenseFulfillmentItem(facilityId, itemId, { quantity }, token)src/services/orders-service.tslistMyOrdersgetOrdergetEligibleFacilitiesForRemainingItemsrouteRemainingItemsAll requests go through
apiFetchand therefore throughdocforum-core. There are no direct calls todocforum-escrowor Stellar in this repo, preserving hard rule 1.5. Mock API coverage (MSW)
Added/updated fixtures and handlers so the entire flow can be exercised locally:
db.ordersseeded with:pending,partially_dispensed,dispensed, anddispensed_elsewherestatessrc/mocks/handlers/orders.tsGET /orders/mineGET /orders/:orderIdGET /orders/:orderId/remaining-items/facilities?itemIds=…POST /orders/:orderId/route-remainingPOST /facilities/:facilityId/fulfillment-queue/:itemId/dispense.409for dispensed-elsewhere, already-routed, or over-quantity requests.dispensed_elsewherewhen the last outstanding quantity is dispensed elsewhere.FACILITY_IDwith the app’s hardcodedfac-mainso the facility dashboard and mock queue are consistent.6. Docs
ROADMAP.mdARCHITECTURE_ESSENTIALS.mddocforum-core#73API shapes.orderItemIdlink.payment.ruleand does not compute escrow releases.Acceptance criteria mapping
FacilityFulfillmentQueue,useDispenseFulfillmentItem, handler testsquantityOutstandingmaintained on queue rows and order itemsrouteRemainingItems+ eligible-facility pickerRemainingItemsFacilityPicker, handler testspartially_fulfilledbadgesFulfillmentStatusBadge,deriveOrderFulfillmentStatus409for dispensed-elsewhere itemspayment.ruleverbatimapiFetchonlyError handling and edge cases
409if forced.409): explicit message asks the patient to refresh; does not silently fail.Partially filled, notFulfilled.aria-modal, Escape close, backdrop close, disabled confirm until a facility is selected.Payment semantics — important for reviewers
This PR intentionally does not implement the release calculation.
OrderPaymentSummary.ruleexactly as supplied bydocforum-core.docforum-coreand is pendingdocforum-core#73.When
docforum-core#73lands, only the response shape/rule text should need confirmation; the screens are designed to render it rather than reinterpret it.Assumed API contracts
These are documented in
ARCHITECTURE_ESSENTIALS.mdand mirrored inmodels.ts:GET /orders/mine→PatientOrder[]GET /orders/:orderId→PatientOrderGET /orders/:orderId/remaining-items/facilities?itemIds=<csv>→FacilityWithDistance[]POST /orders/:orderId/route-remaining→PatientOrderPOST /facilities/:facilityId/fulfillment-queue/:itemId/dispense→FulfillmentQueueItemNotes:
orderItemIdis assumed as the link between a facility queue row and a patient order item.409for dispensed-elsewhere/already-routed items.fulfillmentStatusfrom item rows. The frontend keeps a defensive derivation helper only for resilience.Screenshots
Desktop and mobile captures are included under
screenshots/:patient-orders-desktop.pngpatient-orders-mobile.pngpatient-order-partial-desktop.pngpatient-order-partial-mobile.pngpatient-order-route-picker-desktop.pngpatient-order-route-picker-mobile.pngfacility-partial-fulfilment-desktop.pngfacility-partial-fulfilment-mobile.pngManual QA steps
npm run dev:mock./facilityas the facility persona./patient/ordersas the patient persona.Partially filledand the correct outstanding count.409path (or use an already-dispensed item) and confirm the patient sees an explicit conflict message.Verification
All checks were run locally: