POSTGRESQL REFERENCE · WORKING SOURCE
docs/demo.md
This file ships in the runnable source archive. Synthetic fixtures and demonstration policies are identified in the README.
Download the complete project ↓# Demonstrating svc_warehouse
All identities, warehouses, pallet labels and prices in this script are synthetic. The clock represents October 26–28, 2026 in **America/Denver**, even when the demonstration runs on another date. The invoice is a preview, with no tax, minimum or extra fee in this fixture.
The script describes the intended presentation sequence. Consult the verification report for the exact browser steps and checks actually executed before publishing claims.
## Preparation
Start the database, apply migrations and run the documented isolated reset/seed commands in the project README. Use a fresh fixture with the demo clock at October 26, 08:00 Denver. This reset is an intentional local demonstration action, never a customer-facing API.
Open the application at the local URL printed by the server. The seeded users are:
| Persona | Email | Local demonstration password |
| --- | --- | --- |
| Cedar customer | `shipper@cedar.demo` | `warehouse-demo` |
| Juniper customer | `shipper@juniper.demo` | `warehouse-demo` |
| Warehouse operator | `operator@warehouse.demo` | `warehouse-demo` |
Use the application's actual login action when switching personas. The UI must not treat a client-side role toggle as authentication.
The main booking uses Denver's standard zone, six pallets, October 26 at 09:00 through October 29 at 00:00 Denver. The requested pallet is 1219 × 1016 mm, height 1500 mm, gross weight 800 kg, ambient, sealed dry nonhazardous merchandise. The display should show the accepted maximums and exclusions.
## 90-second customer/operator workflow
| Time | Action | Narration |
| --- | --- | --- |
| 0–12 seconds | Sign in as Cedar. Open Capacity and show eight compatible positions, current physical availability and the future projection. | “This sells a specific kind of pallet position for a specific interval. Current empty space and future promises are shown separately.” |
| 12–27 seconds | Open Booking, request six positions with the default interval, create a quote, create a hold and confirm it before advancing the clock. | “A quote costs no capacity. The ten-minute hold does. Confirmation accepts the quoted rates and keeps the six positions protected.” |
| 27–43 seconds | Sign in as operator, advance to October 26 at 09:00, select the reservation and receive five pallets with `DEMO-*` labels. Show five occupied plus one unreceived, then close receiving and release the unused commitment. | “Six were expected; five arrived. Receiving converts five promises into five custody records. Closing the remaining balance frees the sixth position.” |
| 43–58 seconds | Advance to October 27 at 16:00. Select exactly two pallets and record their release with a reason. | “A partial release frees only these two positions. The other three remain physically present.” |
| 58–70 seconds | Advance to October 28 at 10:00 and release the remaining three pallets. | “The expected departure was only a forecast. Each recorded release is what ends custody.” |
| 70–90 seconds | Open Charges, select the reservation, show USD 61.00 and expand a storage line and movement details. | “Two pallets used two local calendar days each; three used three. Thirteen pallet-days produce 26 dollars of storage, plus 20 receiving and 15 release. Every line points to recorded operations and the accepted tariff.” |
If desired, finish by signing back in as Cedar to show that the customer can inspect the same reservation, inventory history and invoice while operational controls are absent. This extra login may be done after the timed segment.
### Quantities to have visible
| Evidence | Value |
| --- | ---: |
| Quoted quantity | 6 pallets |
| Quoted interval | October 26 09:00 to October 29 00:00 Denver |
| Quoted storage estimate | `6 × 3 × USD 2.00 = USD 36.00` |
| Quoted handling estimate | `6 × (USD 4.00 + USD 3.00) = USD 42.00` |
| Quoted total estimate | **USD 78.00** |
| Actual pallets received/released | 5 / 5 |
| Actual pallet-days | `(2 × 2) + (3 × 3) = 13` |
| Actual preview | **USD 61.00** |
| Fee for the unused sixth commitment | **USD 0.00** |
The estimate and final preview differ for explicit operational reasons: one reserved pallet never arrived, and two of the five departed one date earlier. Do not imply the difference is a discount or rate change.
## Short exception demonstration: an overstay threatens a promise
Use a separate fresh fixture so the main invoice remains easy to reproduce. Pre-stage the following through normal booking and operator actions, or use an explicit scenario helper if one is documented in the README:
1. Cedar reserves one Denver position for October 26 09:00–October 27 09:00. Confirm it at the initial clock.
2. Juniper reserves all eight Denver positions for October 27 09:00–October 28 10:00. Confirm before either quote expires. This future booking is feasible under Cedar's expected departure.
3. Advance to October 26 09:00. Receive Cedar's one pallet and close receiving. Do not release it.
The presentation itself takes roughly 35–45 seconds:
| Step | Action | Point to show |
| --- | --- | --- |
| 1 | As operator, advance the clock to October 27 10:00. | The original pallet remains in custody and occupies its position. |
| 2 | Open Capacity/Operations and show the exception and affected Juniper booking. | The promised future arrival is threatened; the application does not conceal it behind the expired forecast. |
| 3 | Attempt an extension of Cedar's occupied booking over Juniper's interval. | Capacity validation rejects the extension without surrendering Cedar's existing record or deleting its goods. |
| 4 | Record the actual release of Cedar's pallet with a reason. | Only the recorded physical action frees that position and supplies the evidence for resolving the conflict. |
There may be seven physically empty positions while all eight are promised to Juniper. “Physically empty” does not mean “uncommitted.” The operator must resolve the real conflict; the system does not automatically relocate pallets or rewrite customer promises.
## Alternative conflict demonstration: final-position race
The integration suite races two independent PostgreSQL-backed requests for the last compatible positions. Show the test output and resulting commitment counts: one request succeeds and the other receives a capacity conflict. Run the focused command from the verification report; do not label a sequential pair of clicks a concurrency test.
## When presenting a conflict or retry
Leave the relevant conflict message visible long enough to read its reason. Retry the same action with the same key and payload when demonstrating a transport retry; changing the payload under an existing key should produce a conflict. A retry must never create another pallet or another handling charge. The final presentation can cite this behavior only after the verification report records a passing test.
## Posting guardrail
The Thursday post should claim only the persisted workflow, conflict behavior, invoice explanation and browser interactions that were actually exercised. Keep it below 150 words. Deployment, GS1/EPCIS conformance, external WMS integration, real prices, payment handling and production readiness are not claims of this demonstration.