@topy-ai/maggie 0.7.38 → 0.7.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-zh-TW.md +55 -4
- package/README.md +65 -7
- package/bin/maggie.js +10 -2
- package/bundled-contracts/maggie-design/css-utility-evidence-v1.schema.json +10 -0
- package/bundled-contracts/maggie-design/dashboard-surface-v1.schema.json +11 -0
- package/bundled-contracts/maggie-design/progressive-enhancement-v1.schema.json +12 -0
- package/bundled-contracts/maggie-design/sample-surface-v1.schema.json +13 -0
- package/bundled-contracts/maggie-seo/privacy-origin-evidence-v1.schema.json +11 -0
- package/bundled-contracts/maggiedash/booking-access-v1.json +5 -4
- package/bundled-contracts/maggiedash/booking-customer-surface-v1.json +12 -1
- package/bundled-contracts/maggiedash/booking-email-templates-v1.json +2 -0
- package/bundled-contracts/maggiedash/booking-host-adapter-v1.json +14 -2
- package/bundled-contracts/maggiedash/booking-runtime.v1.json +41 -0
- package/bundled-contracts/maggiedash/execution-board.json +526 -26
- package/bundled-contracts/maggiedash/host-capabilities-v1.schema.json +10 -0
- package/bundled-contracts/maggiedash/site-structure-v1.schema.json +13 -0
- package/bundled-references/maggiedash-booking/ARCHITECTURE.md +218 -0
- package/bundled-references/maggiedash-booking/CURRENT-STATE.md +92 -0
- package/bundled-references/maggiedash-booking/DATA-FLOW.md +143 -0
- package/bundled-references/maggiedash-booking/DATA-MODEL.md +367 -0
- package/bundled-references/maggiedash-booking/DECISIONS.md +94 -0
- package/bundled-references/maggiedash-booking/EXECUTION-BOARD.json +2387 -0
- package/bundled-references/maggiedash-booking/HOST-ADAPTER.md +314 -0
- package/bundled-references/maggiedash-booking/ORAWELLNESS-INTEGRATION-AUDIT.md +227 -0
- package/bundled-references/maggiedash-booking/PAYMENT-GATEWAY.md +267 -0
- package/bundled-references/maggiedash-booking/PRD.md +228 -0
- package/bundled-references/maggiedash-booking/PROGRESS.md +2434 -0
- package/bundled-references/maggiedash-booking/QA-TEST-PLAN.md +235 -0
- package/bundled-references/maggiedash-booking/README.md +271 -0
- package/bundled-references/maggiedash-booking/RUNTIME-OPERATIONS.md +152 -0
- package/bundled-references/maggiedash-booking/SECURITY-COMPLIANCE.md +158 -0
- package/bundled-references/maggiedash-booking/SKILLS-AND-CLI.md +542 -0
- package/bundled-references/maggiedash-booking/STRIPE-INTEGRATION.md +129 -0
- package/bundled-references/maggiedash-booking/TASK-RUNBOOK.md +107 -0
- package/bundled-references/maggiedash-booking/TASKS.md +137 -0
- package/bundled-references/maggiedash-booking/USER-JOURNEYS.md +224 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-dfd.excalidraw +1 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-dfd.mmd +16 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-dfd.png +0 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-dfd.svg +1 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-state-machine.mmd +19 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-state-machine.png +0 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-state-machine.svg +1 -0
- package/bundled-references/maggiedash-booking/diagrams/manager-journey.excalidraw +1 -0
- package/bundled-references/maggiedash-booking/diagrams/manager-journey.mmd +11 -0
- package/bundled-references/maggiedash-booking/diagrams/manager-journey.png +0 -0
- package/bundled-references/maggiedash-booking/diagrams/manager-journey.svg +1 -0
- package/bundled-references/maggiedash-booking/diagrams/payment-sequence.mmd +20 -0
- package/bundled-references/maggiedash-booking/diagrams/payment-sequence.png +0 -0
- package/bundled-references/maggiedash-booking/diagrams/payment-sequence.svg +1 -0
- package/bundled-references/maggiedash-booking/diagrams/system-context.excalidraw +1 -0
- package/bundled-references/maggiedash-booking/diagrams/system-context.mmd +10 -0
- package/bundled-references/maggiedash-booking/diagrams/system-context.png +0 -0
- package/bundled-references/maggiedash-booking/diagrams/system-context.svg +1 -0
- package/bundled-skills/maggie-blog-bootstrap/SKILL.md +16 -0
- package/bundled-skills/maggie-booking/SKILL.md +97 -18
- package/bundled-skills/maggie-design/SKILL.md +35 -0
- package/bundled-skills/maggie-seo-geo/SKILL.md +12 -0
- package/bundled-skills/maggie-service-booking/SKILL.md +14 -0
- package/bundled-tools/clis/maggie_booking.py +161 -26
- package/bundled-tools/clis/maggie_contracts.py +282 -0
- package/bundled-tools/clis/maggie_dash.py +22 -6
- package/bundled-tools/clis/maggie_design.py +29 -12
- package/bundled-tools/clis/maggie_service_booking.py +50 -1
- package/bundled-tools/clis/site_audit.py +49 -0
- package/package.json +1 -1
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Booking QA and release test plan
|
|
2
|
+
|
|
3
|
+
The booking system is a correctness-sensitive workflow. Visual polish matters,
|
|
4
|
+
but a beautiful calendar that can double-book or misstate payment is a failed
|
|
5
|
+
release.
|
|
6
|
+
|
|
7
|
+
## 1. Test layers
|
|
8
|
+
|
|
9
|
+
| Layer | What it proves | Required fixtures |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| Unit | Money, timezone, policies, transitions, capability mapping | deterministic dates and currencies |
|
|
12
|
+
| Contract | DTO shape, required fields, errors, auth declarations | host adapter JSON fixtures |
|
|
13
|
+
| Database | uniqueness, overlap, foreign keys, transaction behavior | PostgreSQL test database |
|
|
14
|
+
| Integration | booking service plus payment adapter/outbox | fake provider with event replay |
|
|
15
|
+
| Browser | manager journeys, forms, dialogs, responsive states | seeded tenant and fake gateway |
|
|
16
|
+
| Security | tenant isolation, secret scans, webhook verification | hostile IDs and redacted payloads |
|
|
17
|
+
| Runtime | real host routes and server session | sanitized conformance evidence |
|
|
18
|
+
| Load | availability and concurrent hold behavior | fixed dataset and concurrency count |
|
|
19
|
+
|
|
20
|
+
The repository now also has a deterministic runtime layer gate:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm test
|
|
24
|
+
npm run booking:worker -- --job all --now 2026-09-20T10:00:00Z
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
It covers state transitions, half-open interval conflicts, hold expiry,
|
|
28
|
+
newest-first payment event reconciliation, webhook signature/tenant/amount/
|
|
29
|
+
currency boundaries, notification leases/retries, dry-run isolation, and the
|
|
30
|
+
worker cycle. It does not claim PostgreSQL concurrency or provider delivery
|
|
31
|
+
until the host adapter is connected.
|
|
32
|
+
|
|
33
|
+
The migration gate is:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm run booking:schema:validate
|
|
37
|
+
node scripts/validate-booking-schema.mjs \
|
|
38
|
+
--database-url "$DATABASE_URL" --confirm
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The database check is intended for a disposable migration-test database. It
|
|
42
|
+
applies the base schema once, applies the Booking migration twice, verifies the
|
|
43
|
+
table/constraint/index inventory, and checks that an overlapping staff
|
|
44
|
+
allocation is rejected inside a rolled-back transaction. It also verifies the
|
|
45
|
+
normalized payment-event columns, availability snapshot table, and a
|
|
46
|
+
PostgreSQL advisory-lock round trip.
|
|
47
|
+
|
|
48
|
+
The worker repository boundary has a separate source gate:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm run booking:postgres-repository:test
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This uses an injected fake executor to prove parameterized, tenant-scoped SQL,
|
|
55
|
+
transactional writes, payment-event acknowledgement, snapshot persistence, and
|
|
56
|
+
the lock API. It does not replace host connection-pool, backup/restore,
|
|
57
|
+
notification, or alerting evidence.
|
|
58
|
+
|
|
59
|
+
Operational health is checked with:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm run booking:health:test
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The test covers correlation IDs, lock contention, stale worker/availability
|
|
66
|
+
alerts, payment lag, retryable notifications, and dead-letter escalation. The
|
|
67
|
+
host must still prove that critical codes reach its alerting/paging system.
|
|
68
|
+
|
|
69
|
+
The fake-executor and schema checks are supplemented by the optional real
|
|
70
|
+
repository cycle:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm run booking:postgres-repository:integration -- \
|
|
74
|
+
--database-url "$DATABASE_URL" --confirm
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
It requires a host-installed `pg` dependency and an approved disposable/staging
|
|
78
|
+
database; it cleans up its own uniquely-prefixed test tenant.
|
|
79
|
+
|
|
80
|
+
## 2. Required scenario matrix
|
|
81
|
+
|
|
82
|
+
### Availability
|
|
83
|
+
|
|
84
|
+
- location opening hours;
|
|
85
|
+
- staff working hours and service eligibility;
|
|
86
|
+
- staff time off and blocked time;
|
|
87
|
+
- resource conflict;
|
|
88
|
+
- buffer before/after;
|
|
89
|
+
- lead time and maximum advance window;
|
|
90
|
+
- multiple locations with different timezones;
|
|
91
|
+
- DST nonexistent and ambiguous wall-clock times;
|
|
92
|
+
- multi-segment booking;
|
|
93
|
+
- expired hold release;
|
|
94
|
+
- manager override with permission.
|
|
95
|
+
|
|
96
|
+
### Booking lifecycle
|
|
97
|
+
|
|
98
|
+
- customer hold and successful payment;
|
|
99
|
+
- customer hold and failed payment;
|
|
100
|
+
- customer abandon and hold expiry;
|
|
101
|
+
- manager no-payment booking;
|
|
102
|
+
- check-in, in-progress, completed;
|
|
103
|
+
- cancellation inside/outside policy window;
|
|
104
|
+
- reschedule success;
|
|
105
|
+
- reschedule conflict rollback;
|
|
106
|
+
- no-show and no-show fee policy;
|
|
107
|
+
- duplicate submit with same idempotency key;
|
|
108
|
+
- same key with changed request body;
|
|
109
|
+
- cross-tenant and cross-location access.
|
|
110
|
+
|
|
111
|
+
### Payment
|
|
112
|
+
|
|
113
|
+
- gateway configured and unavailable;
|
|
114
|
+
- `action_required` authentication;
|
|
115
|
+
- delayed provider event;
|
|
116
|
+
- duplicate event;
|
|
117
|
+
- out-of-order event;
|
|
118
|
+
- unmatched event;
|
|
119
|
+
- provider object belongs to another tenant/account;
|
|
120
|
+
- full refund;
|
|
121
|
+
- partial refund;
|
|
122
|
+
- refund over captured amount;
|
|
123
|
+
- refund retry after timeout;
|
|
124
|
+
- saved method and off-session flows only when capability is true;
|
|
125
|
+
- Terminal flow only when capability is true.
|
|
126
|
+
|
|
127
|
+
## 3. Concurrency test
|
|
128
|
+
|
|
129
|
+
The minimum regression test starts two requests for the same service, staff,
|
|
130
|
+
resource, and interval at the same time. It expects one of:
|
|
131
|
+
|
|
132
|
+
- one successful hold and one explicit conflict;
|
|
133
|
+
- one successful booking and one explicit conflict;
|
|
134
|
+
- one idempotent replay of the same request.
|
|
135
|
+
|
|
136
|
+
It must never produce two active allocations, two confirmed bookings, or two
|
|
137
|
+
provider payment attempts for one client action.
|
|
138
|
+
|
|
139
|
+
## 4. Browser checklist
|
|
140
|
+
|
|
141
|
+
For desktop and mobile:
|
|
142
|
+
|
|
143
|
+
- login redirect and return path;
|
|
144
|
+
- sidebar/workspace navigation;
|
|
145
|
+
- overview empty/loading/error/provider-outage states;
|
|
146
|
+
- calendar filters and timezone labels;
|
|
147
|
+
- create booking dialog with one scroll owner;
|
|
148
|
+
- booking detail timeline and separate payment status;
|
|
149
|
+
- refund and cancellation confirmation;
|
|
150
|
+
- catalog/staff/resource/schedule forms;
|
|
151
|
+
- disabled unsupported capability action with reason;
|
|
152
|
+
- keyboard focus and Escape behavior;
|
|
153
|
+
- no native browser prompt;
|
|
154
|
+
- no console errors or failed same-origin JSON requests;
|
|
155
|
+
- no horizontal overflow at 320, 768, and desktop widths.
|
|
156
|
+
|
|
157
|
+
## 5. Evidence artifacts
|
|
158
|
+
|
|
159
|
+
Every release candidate should produce sanitized files under `.maggie/booking/`:
|
|
160
|
+
|
|
161
|
+
```text
|
|
162
|
+
host-conformance.json
|
|
163
|
+
runtime-evidence.json
|
|
164
|
+
config-evidence.json
|
|
165
|
+
payment-contract.json
|
|
166
|
+
webhook-evidence.json
|
|
167
|
+
migration-preflight.json
|
|
168
|
+
concurrency.json
|
|
169
|
+
browser-report.json
|
|
170
|
+
release-gate.json
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The protected workflow
|
|
174
|
+
`.github/workflows/booking-browser-evidence.yml` captures the 15 Booking
|
|
175
|
+
routes at 390x844, 768x1024, and 1440x1000, with a host session supplied by an
|
|
176
|
+
environment-scoped secret. `validate-booking-browser-evidence.mjs` fails on a
|
|
177
|
+
missing route, non-2xx response, login redirect, missing screenshot, console
|
|
178
|
+
error, failed network request, or horizontal overflow reported in
|
|
179
|
+
`layoutErrors`. Browser evidence must come from a dedicated test tenant and
|
|
180
|
+
must never include committed cookies or customer exports.
|
|
181
|
+
|
|
182
|
+
The protected workflow
|
|
183
|
+
`.github/workflows/booking-runtime-evidence.yml` captures all 47 host adapter
|
|
184
|
+
endpoints from a host-owned test plan. The plan supplies a dedicated tenant,
|
|
185
|
+
explicit disposable mutation bodies, and the same email/password session
|
|
186
|
+
cookie used by the browser run. `capture-booking-runtime-evidence.mjs` writes
|
|
187
|
+
only sanitized endpoint IDs, canonical routes, status codes, and required-field
|
|
188
|
+
booleans. `validate-booking-runtime-evidence.mjs` fails on a missing endpoint,
|
|
189
|
+
non-2xx response, contract mismatch, or sensitive evidence field. This is the
|
|
190
|
+
real-host gate; `fixtures/booking-runtime-evidence.v1.json` is only a local
|
|
191
|
+
validator fixture.
|
|
192
|
+
|
|
193
|
+
The completed local UI gate also runs the compiled Booking React workspace in
|
|
194
|
+
Chrome against the secret-free reference host. It caught and fixed two classes
|
|
195
|
+
of regression before release: an unselected detail panel requesting a fake
|
|
196
|
+
`none.json` booking, and grid/table intrinsic widths overflowing a 390px
|
|
197
|
+
viewport. The regression check now waits for network idle, verifies
|
|
198
|
+
`document.body.scrollWidth <= window.innerWidth`, and repeats the route sweep
|
|
199
|
+
at all three target widths. This is local fixture evidence, not a substitute
|
|
200
|
+
for the protected real-host run.
|
|
201
|
+
|
|
202
|
+
Artifacts contain schema versions, hashes, counts, statuses, and safe errors.
|
|
203
|
+
They do not contain credentials, cookies, payment payloads, raw provider
|
|
204
|
+
responses, or unredacted customer details.
|
|
205
|
+
|
|
206
|
+
## 6. Release gate
|
|
207
|
+
|
|
208
|
+
`maggie booking release-gate` should fail when any required artifact is missing,
|
|
209
|
+
stale, or failed. It should print:
|
|
210
|
+
|
|
211
|
+
- project and tenant scope;
|
|
212
|
+
- MaggieDash and ai-cmo-skills revisions;
|
|
213
|
+
- schema/migration version;
|
|
214
|
+
- selected payment provider and capabilities;
|
|
215
|
+
- report IDs and generated-at timestamps;
|
|
216
|
+
- failed phase and next action;
|
|
217
|
+
- final `passed` boolean.
|
|
218
|
+
|
|
219
|
+
No “best effort” pass is allowed for auth, tenancy, allocation, payment,
|
|
220
|
+
webhook, migration, or secret-redaction checks.
|
|
221
|
+
|
|
222
|
+
## 7. Regression policy
|
|
223
|
+
|
|
224
|
+
Every production incident adds one of:
|
|
225
|
+
|
|
226
|
+
- a unit test for a pure rule;
|
|
227
|
+
- a database/concurrency test;
|
|
228
|
+
- a provider fixture;
|
|
229
|
+
- a host conformance fixture;
|
|
230
|
+
- a browser journey;
|
|
231
|
+
- a stable CLI validation;
|
|
232
|
+
- a confirmed memory entry only when the rule is general.
|
|
233
|
+
|
|
234
|
+
The feedback draft is evidence and discussion. It is not active memory until the
|
|
235
|
+
maintainer confirms the diagnosis and generality.
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# MaggieDash Booking workspace
|
|
2
|
+
|
|
3
|
+
This folder is the product and engineering documentation for the Booking
|
|
4
|
+
workspace at `/_maggie/booking`. The canonical current snapshot and gap list is
|
|
5
|
+
[`CURRENT-STATE.md`](./CURRENT-STATE.md); this README explains the surface and
|
|
6
|
+
links the deeper contracts.
|
|
7
|
+
|
|
8
|
+
The target is a first-party booking management system for store managers. It
|
|
9
|
+
must own the booking domain while keeping payment providers replaceable. Stripe
|
|
10
|
+
is the first adapter, not the database, booking engine, or public API contract.
|
|
11
|
+
|
|
12
|
+
## What is true today
|
|
13
|
+
|
|
14
|
+
This repository currently provides:
|
|
15
|
+
|
|
16
|
+
- the `maggie-service-booking` skill for provider-backed service catalogues,
|
|
17
|
+
variants, provider URLs, sync, factual validation, and service-page output;
|
|
18
|
+
- a provider-neutral booking adapter reference with Fresha as the first
|
|
19
|
+
catalogue provider and Google Calendar as a limited fallback;
|
|
20
|
+
- MaggieDash installation into `./_maggie/admin`;
|
|
21
|
+
- MaggieDash distribution of a separate `./_maggie/booking` React workspace,
|
|
22
|
+
Booking UI v1 and the provider-neutral Booking host adapter v1;
|
|
23
|
+
- a provider-neutral PostgreSQL Booking starter schema with idempotency, audit,
|
|
24
|
+
outbox, payment, hold, allocation, and database overlap constraints;
|
|
25
|
+
- `maggie booking install` (including explicit `--install-dependencies`, `--bootstrap`, the combined `--ready` path, and reviewed `--schedule systemd|cron` generation), `worker-schedule`, `inspect`, the read-only first-run `setup` checklist,
|
|
26
|
+
`contract`, `runtime-validate`, `ops-validate`, task-board, and fail-closed
|
|
27
|
+
`release-gate` checks in ai-cmo-skills;
|
|
28
|
+
- a non-destructive Astro host bootstrap that installs email/password auth,
|
|
29
|
+
first-owner registration, manager/public routes, PostgreSQL/Stripe wiring,
|
|
30
|
+
the schema command, Resend worker, and middleware rewrite starter;
|
|
31
|
+
- Booking access management for email/password staff, manager, and finance
|
|
32
|
+
accounts is covered by the installable `booking-access-v1` contract, including
|
|
33
|
+
granular permissions, Resend invitations, password reset, revocation,
|
|
34
|
+
disabled-account protection, staff-profile linking, and server-enforced
|
|
35
|
+
granular permissions;
|
|
36
|
+
- tenant-scoped Booking email template management for ten Resend events,
|
|
37
|
+
allowlisted variables, sandboxed preview, audited draft/publish/rollback, and
|
|
38
|
+
worker fallback resolution without exposing provider secrets or recipients;
|
|
39
|
+
- server-side staff assignment scope for bookings, calendar, availability,
|
|
40
|
+
customer summaries, schedule, resources, and lifecycle mutations;
|
|
41
|
+
- a source/install-side runtime plan regression gate for concrete route
|
|
42
|
+
parameters, query parameters, and mutation bodies;
|
|
43
|
+
- a protected operational-evidence workflow that rejects fixture artifacts at
|
|
44
|
+
the host release boundary;
|
|
45
|
+
- a separate public-noindex customer-flow contract and route handler for
|
|
46
|
+
catalogue, availability, holds, checkout start, payment-return recovery,
|
|
47
|
+
cancellation, token-bound customer rescheduling, customer-manage history,
|
|
48
|
+
waitlist joining, safe DTO
|
|
49
|
+
redaction, and notification intents;
|
|
50
|
+
- a tenant-scoped waitlist queue with manager filtering, priority/status
|
|
51
|
+
actions, audit records, a linked booking conversion transaction, and a Resend
|
|
52
|
+
availability-notification intent;
|
|
53
|
+
- a worker-side waitlist matcher that orders eligible entries by priority/FIFO,
|
|
54
|
+
persists the offered slot, and queues one idempotent Resend availability
|
|
55
|
+
notification without auto-reserving the appointment;
|
|
56
|
+
- separate short-lived payment tokens and 30-day sealed customer-manage
|
|
57
|
+
tokens, with Resend worker links for customer self-service follow-up;
|
|
58
|
+
- a public customer-manage history view that lists only redacted appointment
|
|
59
|
+
summaries for the tenant/customer bound to the 30-day token;
|
|
60
|
+
- a manager customer directory with searchable tenant-scoped customer details,
|
|
61
|
+
consent summary, and appointment history;
|
|
62
|
+
- editable schedule-rule management for working hours, staff shifts, time off,
|
|
63
|
+
and location closures without destructive snapshot writes;
|
|
64
|
+
- editable service and treatment catalogue management with stable service and
|
|
65
|
+
variant IDs, payment policy controls, search, and active/inactive status;
|
|
66
|
+
- editable location management with tenant-scoped timezone, locale, address,
|
|
67
|
+
active state, and online-booking controls;
|
|
68
|
+
- editable staff and resource management with assignment, bookable, capacity,
|
|
69
|
+
and active-state controls;
|
|
70
|
+
- editable Booking defaults for venue timezone/currency, accepting new
|
|
71
|
+
bookings, and automatic/manual payment capture policy;
|
|
72
|
+
- editable tenant-scoped treatment package catalogue with included treatment
|
|
73
|
+
quantities, package pricing, currency, expiry, and active state;
|
|
74
|
+
- manager-granted customer package entitlements with tenant/customer-scoped
|
|
75
|
+
balances, expiry checks, and atomic redemption when creating manager
|
|
76
|
+
bookings; public package checkout, provider reconciliation/webhook fulfillment,
|
|
77
|
+
manager purchase listing, and guarded package refund routes are included;
|
|
78
|
+
- Overview bookability readiness that identifies missing active locations,
|
|
79
|
+
catalogue variants, assigned bookable staff, working hours, payment
|
|
80
|
+
capability, and the resulting overall `bookable` state;
|
|
81
|
+
- manager booking creation driven by live catalogue, location, staff, and
|
|
82
|
+
resource selectors with required allocation;
|
|
83
|
+
- install-time configuration forms that read tenant locations and live service
|
|
84
|
+
assignments instead of relying on fixture IDs;
|
|
85
|
+
- an installable public customer booking page source and Astro route starter
|
|
86
|
+
for the same hold/checkout/pending-return journey;
|
|
87
|
+
- public multi-treatment selection with combined-duration availability, summed
|
|
88
|
+
checkout pricing, safe segment DTOs, segment-safe customer rescheduling, and
|
|
89
|
+
tenant location selection with location-scoped availability;
|
|
90
|
+
- a deterministic public customer reference-host journey validator covering
|
|
91
|
+
hold replay, checkout pending state, payment return, token-bound cancel, and
|
|
92
|
+
manager-session isolation;
|
|
93
|
+
- provider-neutral runtime rules and worker runner for availability, hold
|
|
94
|
+
expiry, payment webhook/reconciliation, priority/FIFO waitlist matching, and
|
|
95
|
+
notification outbox delivery;
|
|
96
|
+
- a dated Stripe API/resource/event audit and installable capability contract;
|
|
97
|
+
the host still supplies the concrete official SDK adapter;
|
|
98
|
+
- a manager Reports screen and tenant-scoped `/reports.json` read model for
|
|
99
|
+
period totals plus day, service, staff, and location breakdowns;
|
|
100
|
+
- an idempotent 24-hour reminder worker job that queues confirmed-booking
|
|
101
|
+
reminders into the existing Resend notification outbox;
|
|
102
|
+
- service-level payment policies (`full`, `deposit`, `pay_later`, and
|
|
103
|
+
`no_payment`), purpose-labelled payment attempts, captured/refunded payment
|
|
104
|
+
projection, and manager controls for deposits and outstanding balances;
|
|
105
|
+
- systemd/cron scheduling templates and a protected Playwright browser-evidence
|
|
106
|
+
capture/validation workflow;
|
|
107
|
+
- provider-neutral MaggieDash host, auth, activity, navigation, content, media,
|
|
108
|
+
migration, and runtime-evidence contracts;
|
|
109
|
+
- a PostgreSQL starter schema for MaggieDash content and audit records.
|
|
110
|
+
- a tenant-scoped Notifications screen for delivery-state inspection and
|
|
111
|
+
reasoned dead-letter replay, with recipient redaction and audit evidence.
|
|
112
|
+
- policy-safe cancellation settlement that allocates full/deposit refunds,
|
|
113
|
+
invokes the injected payment provider after the lifecycle write, returns
|
|
114
|
+
`manual_required` on provider failure, and queues accepted/pending refund
|
|
115
|
+
notices through the existing Resend outbox;
|
|
116
|
+
|
|
117
|
+
The manager workspace, distribution contracts, starter schema, provider-neutral
|
|
118
|
+
runtime rules, worker runner, scheduling templates, browser-evidence gate, and
|
|
119
|
+
customer-flow boundary are implemented locally. A secret-free reference host
|
|
120
|
+
and an Astro host scaffold are also available for contract/browser work. A host
|
|
121
|
+
must still apply the schema, prove PostgreSQL transactions, verify a real
|
|
122
|
+
payment account and webhook, enable notification delivery and tenant locking,
|
|
123
|
+
and capture authenticated production browser/runtime/ops evidence before real
|
|
124
|
+
bookings can be enabled.
|
|
125
|
+
Resend is the server-side notification and account-email transport. Staff
|
|
126
|
+
invitation, first-login setup, password reset, one-time token expiry, and
|
|
127
|
+
session revocation are implemented in the Astro host scaffold; real delivery
|
|
128
|
+
and browser evidence remain host deployment gates.
|
|
129
|
+
Stripe setup is likewise server-side: configure the host secret store, then
|
|
130
|
+
verify the account from Booking Overview. For a single-business host, an
|
|
131
|
+
owner/manager can alternatively enter both Stripe values in the secure
|
|
132
|
+
dashboard form; the host verifies them first and stores only encrypted
|
|
133
|
+
ciphertext derived from `BOOKING_TOKEN_SECRET`. Secret presence alone is only
|
|
134
|
+
`pending`; `connected` requires a successful API check, explicit Stripe
|
|
135
|
+
charges/payouts enablement, and a webhook secret. Raw Stripe credentials are
|
|
136
|
+
never returned by the API or stored as plaintext Booking data. Deployment
|
|
137
|
+
secrets take precedence over dashboard-managed credentials.
|
|
138
|
+
|
|
139
|
+
## Current verification snapshot — 2026-09-21
|
|
140
|
+
|
|
141
|
+
| Item | Current evidence |
|
|
142
|
+
|---|---|
|
|
143
|
+
| MaggieDash source | Package `0.2.8`, `HEAD`/`origin/main` [`9d99de7`](https://github.com/TOPY-AI-LTD/MaggieDash/commit/9d99de7); the working tree contains newer uncommitted Booking changes |
|
|
144
|
+
| Delivery board | 84 implementation tasks passed and 3 real-host evidence tasks pending (BK-030, BK-031, BK-032); Reports, reminders, payment-policy projection, cancellation policy snapshots/cutoff/refund settlement, consented Stripe no-show fee charging with explicit manager/finance approval, venue-local calendar day/week ranges, manager/customer history, editable schedule rules, catalogue, treatment package catalogue plus customer entitlement balances/redemption, public package checkout/payment return and public customer package redemption, transactional package-credit restoration on cancellation, Stripe package fulfillment/refunds, package confirmation/refund Resend notifications, locations, staff/resource management, live-config booking creation, manager and public multi-treatment appointments, segment-safe rescheduling, strict first-run setup checks, secure dashboard-managed Stripe connection, tenant-scoped Stripe Customer identity mapping, secret-safe Stripe readiness, installed-workspace validator coverage, explicit schema bootstrap, bootstrap secret provisioning, transactional schema dry-run, compatible Resend sender keys, token-bound rescheduling, customer-manage links/history, transactional waitlist conversion, priority/FIFO waitlist slot matching, synchronized install contracts, npm bundled-contract path resolution, tenant-scoped notification inspection/dead-letter replay, first-owner registration hardening, access defaults, complete server-enforced capability permissions, worker migration preflight, complete browser evidence route coverage, installable administrator-managed Booking access contracts, reference-host Team access CRUD/denial evidence, dependency-complete fresh Astro installation, tenant-scoped Resend email template management, and complete tenant booking defaults are covered by the manager/runtime and public-customer contracts |
|
|
145
|
+
| Local code gates | MaggieDash `npm test`, contract/UI/security/customer/runtime validators, and Python task-board/link checks passed |
|
|
146
|
+
| Installer projection | The default public GitHub source installed 139 source artifacts plus 23 Astro host files in a fresh disposable project; dependency completion added the missing SSR adapter, and the installed host bootstrap validator, `maggie booking inspect`, and `astro build` all passed. Existing host deployment configs are preserved |
|
|
147
|
+
| Published npm parity | Local CLI source is `0.7.39`; npm still serves `@topy-ai/maggie@0.7.38`, which has the older Booking contract and needs a release/published-tarball verification |
|
|
148
|
+
| Access boundary | Standard Booking schema owns `maggiedash_booking_user_roles`; host access API, explicit permissions, linked `staff_id`, and repository data-scope checks passed |
|
|
149
|
+
| Reference host | 47 manager endpoint checks plus public customer-flow checks passed, including explicit no-show fee route coverage, location setup, package catalogue management, customer package grant/balance/redemption, public package redemption from hold to zero-price booking, package checkout/payment-return, Stripe connection verification, notification replay, and multi-treatment hold/checkout/reschedule |
|
|
150
|
+
| Local browser smoke | The browser contract now covers all 15 manager routes (`45` route/viewport screens) across 390/768/1440. A fresh authenticated host capture is still required; the earlier 33/33 result covered only the former 11-route surface and is not reused as production evidence |
|
|
151
|
+
| Production proof | Not yet complete; reference-host and fixture artifacts are explicitly not production evidence |
|
|
152
|
+
|
|
153
|
+
## Current product limits
|
|
154
|
+
|
|
155
|
+
The local Booking release supports both manager-led and public customer package
|
|
156
|
+
redemption. After a confirmed package purchase, the customer can continue to
|
|
157
|
+
the public booking page; the server binds the entitlement to the customer's
|
|
158
|
+
email, locks the balance during checkout, and creates a zero-price confirmed
|
|
159
|
+
booking when all selected treatments are covered. A successful cancellation
|
|
160
|
+
restores each active redemption once and records the reversal; completed and
|
|
161
|
+
no-show visits remain consumed by policy. Memberships, gift cards, and
|
|
162
|
+
recurring appointments are not yet part of the v1 contract. No-show fees are
|
|
163
|
+
supported only through the separate consented, explicitly confirmed
|
|
164
|
+
off-session charge route; there is no automatic charge on status transition.
|
|
165
|
+
|
|
166
|
+
## Evidence inspected
|
|
167
|
+
|
|
168
|
+
| Evidence | What it establishes |
|
|
169
|
+
|---|---|
|
|
170
|
+
| `/home/balalior/Dev/MaggieDash/maggiedash.json` | Distribution targets `_maggie/admin` plus the separate `_maggie/booking` workspace |
|
|
171
|
+
| `/home/balalior/Dev/MaggieDash/backend/booking-adapter-contract.d.ts` | Booking host owns the email/password session, API prefix, manager service surface, and injected provider boundary |
|
|
172
|
+
| `/home/balalior/Dev/MaggieDash/contracts/booking-host-adapter-v1.json` | Current 47-endpoint Booking host contract and response policy, including treatment packages, customer package balances/redemption, package purchase/refund, Stripe verification, consented no-show fee charging, and notification inspection/replay |
|
|
173
|
+
| `/home/balalior/Dev/MaggieDash/contracts/booking-customer-surface-v1.json` | Current eleven-endpoint public customer boundary and noindex/idempotency policy, including package checkout/payment return |
|
|
174
|
+
| `/home/balalior/Dev/MaggieDash/package.json` | Current `0.2.8` package scripts and executable Booking validators |
|
|
175
|
+
| `skills/maggie-service-booking/SKILL.md` | Current provider-backed catalogue and booking-link scope |
|
|
176
|
+
| `references/provider-adapter-contract.md` | Existing provider-neutral booking/payment direction |
|
|
177
|
+
| `tools/clis/maggie_dash.py` | Installer maps both admin and Booking workspaces, plus root contracts/schema |
|
|
178
|
+
| `tools/clis/maggie_booking.py` | Booking installer plus inspect, contract, runtime, and release gates |
|
|
179
|
+
| `/home/balalior/Dev/MaggieDash/adapters/astro/host/` | Generic non-destructive Astro host scaffold for auth, routes, PostgreSQL, Stripe, schema, Resend worker, and middleware |
|
|
180
|
+
| `/home/balalior/Dev/MaggieDash/contracts/booking-email-templates-v1.json` | Ten-event tenant-scoped template contract and server-only Resend/recipient policy |
|
|
181
|
+
| `/home/balalior/Dev/MaggieDash/backend/booking/email-templates.mjs` | Provider-neutral fallback, placeholder allowlist, HTML escaping, and renderer |
|
|
182
|
+
|
|
183
|
+
## Documents
|
|
184
|
+
|
|
185
|
+
| Document | Diataxis role | Use it for |
|
|
186
|
+
|---|---|---|
|
|
187
|
+
| [PRD](./PRD.md) | Reference | Product scope, requirements, personas, and acceptance criteria |
|
|
188
|
+
| [Architecture](./ARCHITECTURE.md) | Explanation | System boundary, modules, state ownership, and runtime topology |
|
|
189
|
+
| [User journeys](./USER-JOURNEYS.md) | Tutorial / explanation | Manager, customer, staff, finance, and failure journeys |
|
|
190
|
+
| [Data flow](./DATA-FLOW.md) | Explanation / reference | DFD, events, consistency, and source-of-truth rules |
|
|
191
|
+
| [Data model](./DATA-MODEL.md) | Reference | Entities, constraints, indexes, and migration order |
|
|
192
|
+
| [Payment gateway](./PAYMENT-GATEWAY.md) | Reference / explanation | Provider port, Stripe adapter, webhooks, refunds, and future providers |
|
|
193
|
+
| [Stripe integration audit](./STRIPE-INTEGRATION.md) | Reference / runbook | Verified API matrix, webhook set, Tax/Billing/Terminal/Connect choices, and gift-card/referral boundary |
|
|
194
|
+
| [Host adapter](./HOST-ADAPTER.md) | Reference | Routes, payloads, auth, errors, and conformance evidence |
|
|
195
|
+
| [Skills and CLI](./SKILLS-AND-CLI.md) | How-to / reference | How ai-cmo-skills supports implementation, checks, and release gates |
|
|
196
|
+
| [Security and compliance](./SECURITY-COMPLIANCE.md) | Explanation / reference | Secrets, tenancy, audit, PCI scope, privacy, and operational controls |
|
|
197
|
+
| [QA plan](./QA-TEST-PLAN.md) | How-to / reference | Contract, state, concurrency, payment, browser, and release tests |
|
|
198
|
+
| [Runtime operations](./RUNTIME-OPERATIONS.md) | How-to / runbook | Worker jobs, webhook flow, notification outbox, cron/systemd, browser evidence, alerts and rollback |
|
|
199
|
+
| [Current state](./CURRENT-STATE.md) | Reference / runbook | Verified surface, release blockers, host sequence, and gaps |
|
|
200
|
+
| [Decision log](./DECISIONS.md) | Explanation | Durable architecture decisions and unresolved choices |
|
|
201
|
+
| [Execution board](./EXECUTION-BOARD.json) | Reference | Leaf tasks with dependencies, implementation files, tests, docs, and acceptance evidence |
|
|
202
|
+
| [Task runbook](./TASK-RUNBOOK.md) | How-to | Task → plan → implement → test → docs → progress operating loop |
|
|
203
|
+
| [ORA integration audit](./ORAWELLNESS-INTEGRATION-AUDIT.md) | Reference | Host-specific Booking, Stripe, Resend, migration, and production-readiness status |
|
|
204
|
+
|
|
205
|
+
## Diagrams
|
|
206
|
+
|
|
207
|
+
The source files live in [`diagrams/`](./diagrams/). Rendered images are linked
|
|
208
|
+
from the data-flow and architecture documents so the documentation does not
|
|
209
|
+
depend on GitHub Mermaid rendering.
|
|
210
|
+
|
|
211
|
+
- [System context](./diagrams/system-context.svg)
|
|
212
|
+
- [Manager journey](./diagrams/manager-journey.svg)
|
|
213
|
+
- [Booking data-flow diagram](./diagrams/booking-dfd.svg)
|
|
214
|
+
- [Payment sequence](./diagrams/payment-sequence.svg)
|
|
215
|
+
- [Booking state machine](./diagrams/booking-state-machine.svg)
|
|
216
|
+
|
|
217
|
+
Each diagram also has an editable `.mmd` source. Flowcharts include an
|
|
218
|
+
`.excalidraw` scene; the sequence and state diagrams intentionally include only
|
|
219
|
+
SVG and PNG because the renderer's editable-scene converter supports flowcharts
|
|
220
|
+
only.
|
|
221
|
+
|
|
222
|
+
## Recommended host rollout
|
|
223
|
+
|
|
224
|
+
1. Read [`CURRENT-STATE.md`](./CURRENT-STATE.md) and run the read-only install,
|
|
225
|
+
schema, contract, and build checks.
|
|
226
|
+
2. Back up the host database and rehearse restore into an empty disposable
|
|
227
|
+
database.
|
|
228
|
+
3. Apply Booking/access migrations only after owner approval, then register the
|
|
229
|
+
first owner and seed a staging location/catalogue/staff schedule.
|
|
230
|
+
4. Configure and verify Stripe test credentials plus the signed webhook secret.
|
|
231
|
+
5. Enable one worker scheduler with lock, alert, retry, and dead-letter proof;
|
|
232
|
+
verify Resend invitation, reset, reminder, waitlist, refund, package, and
|
|
233
|
+
no-show delivery.
|
|
234
|
+
6. Capture the 47-endpoint runtime, 45-screen browser, and ops evidence bundle;
|
|
235
|
+
run the final release gate before a one-location canary.
|
|
236
|
+
|
|
237
|
+
The detailed execution board is maintained by
|
|
238
|
+
[`EXECUTION-BOARD.json`](./EXECUTION-BOARD.json). Use
|
|
239
|
+
`maggie booking tasks validate` before starting a task and record the evidence
|
|
240
|
+
in [`PROGRESS.md`](./PROGRESS.md). A final delivery decision must require
|
|
241
|
+
runtime, browser, ops, and board evidence:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
maggie booking release-gate --project . --require-runtime \
|
|
245
|
+
--evidence .maggie/booking/runtime-evidence.json \
|
|
246
|
+
--require-browser --browser-evidence .maggie/booking/browser/evidence.json \
|
|
247
|
+
--require-ops --ops-evidence .maggie/booking/ops-evidence.json \
|
|
248
|
+
--require-board
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Non-negotiable truths
|
|
252
|
+
|
|
253
|
+
- PostgreSQL is business truth.
|
|
254
|
+
- The availability engine and database constraints are booking truth.
|
|
255
|
+
- The payment gateway is payment truth, but never booking truth.
|
|
256
|
+
- A payment redirect is not proof of payment; a verified webhook or provider
|
|
257
|
+
read is required.
|
|
258
|
+
- A hold is a first-class record with an expiry and an idempotency key.
|
|
259
|
+
- All monetary values use integer minor units plus an ISO currency.
|
|
260
|
+
- All stored instants are UTC; venue-local input carries an IANA timezone.
|
|
261
|
+
- Manager actions are authenticated, authorized, idempotent, and auditable.
|
|
262
|
+
- Provider credentials stay server-side and never enter dashboard props or
|
|
263
|
+
browser bundles.
|
|
264
|
+
|
|
265
|
+
## Evidence boundary
|
|
266
|
+
|
|
267
|
+
The existing MaggieDash source and ai-cmo-skills contracts were inspected on
|
|
268
|
+
2026-09-21. Statements marked **current** describe repository evidence.
|
|
269
|
+
Statements marked **proposed** describe the implementation target and must not
|
|
270
|
+
be presented to a user as an already-supported feature until the relevant
|
|
271
|
+
contract, adapter, tests, and runtime evidence land.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Booking runtime operations
|
|
2
|
+
|
|
3
|
+
This document turns the host-owned runtime boundary into deployable pieces.
|
|
4
|
+
MaggieDash supplies the rules and contracts; the host supplies PostgreSQL,
|
|
5
|
+
provider adapters, email/SMS, secrets, tenant scope, and deployment.
|
|
6
|
+
|
|
7
|
+
## Data model to service map
|
|
8
|
+
|
|
9
|
+
| Runtime concern | Tables | Code/contract | Owner |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| Availability | `maggiedash_booking_working_hours`, `shifts`, `time_off`, `allocations`, `holds`, `bookings` | `backend/booking/domain.mjs` `computeAvailability` | host transaction + Booking worker |
|
|
12
|
+
| Holds | `maggiedash_booking_holds`, `idempotency_keys`, `events`, `audit_events` | `expireHolds` and `booking.holds.*` endpoints | host worker |
|
|
13
|
+
| Payment webhook | `payment_attempts`, `webhook_events`, `events`, `audit_events` | `payment-webhook.mjs`, `booking.provider.webhook` | host server route |
|
|
14
|
+
| Payment reconciliation | `payment_attempts`, `refunds`, `webhook_events` | `reconcilePaymentEvents` and `booking.payment.*` endpoints | host worker/provider adapter |
|
|
15
|
+
| Notifications | `outbox`, `notifications`, `events`, `audit_events` | `notifications.mjs`, `claimNotifications`, `scheduleNotification` | host email/SMS adapter |
|
|
16
|
+
| Browser evidence | no business tables; artifact storage only | `booking-browser-evidence-v1.json` and capture/validate scripts | protected CI environment |
|
|
17
|
+
|
|
18
|
+
## Worker sequence
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
lock tenant
|
|
22
|
+
│
|
|
23
|
+
├─ expire holds
|
|
24
|
+
│ └─ append hold.expired event + audit/outbox in one DB transaction
|
|
25
|
+
├─ reconcile verified payment events
|
|
26
|
+
│ └─ dedupe provider event, reject mismatch, update payment projection
|
|
27
|
+
├─ refresh availability
|
|
28
|
+
│ └─ read UTC schedule and exclusion state, publish labelled read model
|
|
29
|
+
└─ claim notification outbox rows
|
|
30
|
+
└─ dispatch with idempotency key, mark sent or retry/dead-letter
|
|
31
|
+
unlock tenant
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The database exclusion constraints remain the final double-booking guard. A
|
|
35
|
+
distributed lock reduces duplicate work but is not a correctness substitute.
|
|
36
|
+
|
|
37
|
+
Every installed PostgreSQL worker performs a read-only schema preflight before
|
|
38
|
+
acquiring the tenant lock. It checks the core, Booking, and access tables. If a
|
|
39
|
+
migration is missing, it exits with code 1 and emits bounded JSON with
|
|
40
|
+
`status: "needs-migration"`; it does not load worker state, acquire the lock,
|
|
41
|
+
or write business rows. Operators should run the schema command's `--dry-run`
|
|
42
|
+
before an explicitly approved `--apply --confirm` migration.
|
|
43
|
+
|
|
44
|
+
Notification delivery is intentionally after booking/payment truth is committed.
|
|
45
|
+
`notifications.mjs` stores only a recipient hash and allowlisted template
|
|
46
|
+
variables, leases rows before dispatch, retries with exponential backoff, moves
|
|
47
|
+
exhausted rows to `dead_letter`, and requires an operator reason for replay.
|
|
48
|
+
Delivery failure therefore cannot roll back a booking transaction.
|
|
49
|
+
|
|
50
|
+
## Service and cron choices
|
|
51
|
+
|
|
52
|
+
Use one of these, never both for the same tenant:
|
|
53
|
+
|
|
54
|
+
1. `ops/systemd/maggie-booking-worker.service` plus `.timer` on a VPS. The
|
|
55
|
+
timer runs every minute and systemd provides restart/logging boundaries.
|
|
56
|
+
2. `ops/cron/maggie-booking-cron.example` on a host without systemd. `flock`
|
|
57
|
+
makes the single-host job non-overlapping.
|
|
58
|
+
3. A platform scheduler calling the same worker command with a distributed
|
|
59
|
+
lock for a multi-replica deployment.
|
|
60
|
+
|
|
61
|
+
The worker is four logical jobs, not four independent processes. Run them in
|
|
62
|
+
this order so expired holds cannot continue blocking or leaking into
|
|
63
|
+
availability. Webhooks are event-driven and should call the server helper
|
|
64
|
+
immediately; the reconciliation job is a recovery poll, not the primary
|
|
65
|
+
payment signal.
|
|
66
|
+
|
|
67
|
+
## Host adapter module
|
|
68
|
+
|
|
69
|
+
The production command accepts a host module:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
node maggiedash/backend/booking/run-booking-jobs.mjs \
|
|
73
|
+
--adapter /etc/maggie/booking-adapter.mjs \
|
|
74
|
+
--job all --write --output /var/lib/maggie/booking/last-run.json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The module must export:
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
export async function loadState() { /* tenant-scoped PostgreSQL read */ }
|
|
81
|
+
export async function saveState(nextState) { /* transaction + audit/outbox */ }
|
|
82
|
+
export async function dispatchNotification(item) { /* idempotent email/SMS */ }
|
|
83
|
+
export async function acquireLock() { /* PostgreSQL advisory/distributed lock */ }
|
|
84
|
+
export async function releaseLock() { /* release the tenant lock */ }
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The adapter binds tenant IDs and makes the state snapshot/write atomic. The
|
|
88
|
+
runner acquires and releases the adapter lock around the full cycle. The JSON
|
|
89
|
+
fixture mode is for local development and CI only, and is rejected when
|
|
90
|
+
`NODE_ENV=production`.
|
|
91
|
+
|
|
92
|
+
MaggieDash also ships `backend/booking/postgres-worker-repository.mjs`. A host
|
|
93
|
+
can compose it with the adapter seam by injecting a parameterized query
|
|
94
|
+
function, a checked-out-client transaction callback, a tenant scope, and the
|
|
95
|
+
availability window configuration. It persists worker state, acknowledges
|
|
96
|
+
verified payment events, writes availability snapshots, and uses a PostgreSQL
|
|
97
|
+
advisory lock. The query function and transaction callback must use the same
|
|
98
|
+
client; the module does not import `pg` or read secrets. The repository accepts
|
|
99
|
+
the adapter context `{ tenantScope, nextState }` and rejects a mismatched
|
|
100
|
+
tenant scope, so the adapter/repository boundary cannot silently discard a
|
|
101
|
+
state write.
|
|
102
|
+
|
|
103
|
+
## Payment webhook sequence
|
|
104
|
+
|
|
105
|
+
1. Host route receives raw body and provider headers.
|
|
106
|
+
2. `handlePaymentWebhook` calls the provider verifier before parsing trustable
|
|
107
|
+
fields.
|
|
108
|
+
3. Provider adapter normalizes event ID, payment attempt ID, status, amount,
|
|
109
|
+
currency, occurrence time, and account/tenant reference.
|
|
110
|
+
4. Existing `(provider, provider_event_id)` returns idempotent success.
|
|
111
|
+
5. Unknown attempt is quarantined for operator reconciliation, not confirmed.
|
|
112
|
+
6. Tenant, amount, and currency mismatches return a safe 422 error.
|
|
113
|
+
7. Verified event is inserted, then the worker applies ordering and updates
|
|
114
|
+
booking/payment projections.
|
|
115
|
+
|
|
116
|
+
## Browser evidence workflow
|
|
117
|
+
|
|
118
|
+
The protected workflow in
|
|
119
|
+
`.github/workflows/booking-browser-evidence.yml` requires an HTTPS base URL and
|
|
120
|
+
an environment-scoped, short-lived storage state. It captures 15 manager
|
|
121
|
+
screens at mobile/tablet/desktop widths, records console/request failures, uploads
|
|
122
|
+
artifacts for 14 days, and fails validation when any route is missing, not
|
|
123
|
+
ready, non-2xx, or has a browser/network error.
|
|
124
|
+
|
|
125
|
+
Never commit storage state, cookies, screenshots with customer data, or raw
|
|
126
|
+
provider payloads. Use a dedicated test tenant and redact artifacts before
|
|
127
|
+
retention beyond the CI window.
|
|
128
|
+
|
|
129
|
+
The companion `.github/workflows/booking-runtime-evidence.yml` uses the same
|
|
130
|
+
session boundary plus a host-owned runtime plan to exercise every declared
|
|
131
|
+
Booking endpoint. It requires `--confirm` because the plan includes disposable
|
|
132
|
+
test mutations, and it writes only sanitized 2xx/required-field observations.
|
|
133
|
+
Run `maggie booking runtime-validate` on the resulting artifact before the
|
|
134
|
+
release gate. A fixture evidence file can validate the toolchain locally but
|
|
135
|
+
must never be used as production evidence.
|
|
136
|
+
|
|
137
|
+
## Alerts and rollback
|
|
138
|
+
|
|
139
|
+
Alert on:
|
|
140
|
+
|
|
141
|
+
- worker lock contention or two missed minute ticks;
|
|
142
|
+
- availability read model older than five minutes;
|
|
143
|
+
- holds expiring above baseline;
|
|
144
|
+
- payment webhook verification/quarantine spikes or reconciliation lag;
|
|
145
|
+
- notification retries/dead letters;
|
|
146
|
+
- browser evidence console/network errors, route readiness failures, or
|
|
147
|
+
`layoutErrors` horizontal overflow.
|
|
148
|
+
|
|
149
|
+
Rollback disables new booking writes and payment capture through host feature
|
|
150
|
+
flags. It does not delete confirmed bookings, payments, webhooks, events,
|
|
151
|
+
notifications, or audit history. Existing bookings remain readable and
|
|
152
|
+
operable for cancellation/refund recovery.
|