@topy-ai/maggie 0.7.47 → 0.7.48
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 +2 -2
- package/README.md +49 -15
- package/bin/maggie.js +6 -2
- package/bundled-contracts/maggie-design/palette-roles-v1.schema.json +47 -0
- package/bundled-contracts/maggie-marketplace/template-content-v1.schema.json +103 -0
- package/bundled-contracts/maggiedash/booking-browser-evidence-v1.json +21 -0
- package/bundled-contracts/maggiedash/booking-browser-evidence-v2.json +191 -0
- package/bundled-contracts/maggiedash/booking-email-templates-v1.json +3 -1
- package/bundled-contracts/maggiedash/booking-voucher-lifecycle-v1.json +85 -0
- package/bundled-contracts/maggiedash/execution-board.json +4629 -1553
- package/bundled-contracts/maggiedash/stripe-booking-capabilities-v1.json +1 -0
- package/bundled-marketplace/README.md +17 -0
- package/bundled-marketplace/catalog.json +56 -7
- package/bundled-references/browser-inspection.md +25 -0
- package/bundled-references/maggiedash-booking/CURRENT-STATE.md +128 -10
- package/bundled-references/maggiedash-booking/EXECUTION-BOARD.json +4629 -1553
- package/bundled-references/maggiedash-booking/HOST-ADAPTER.md +5 -0
- package/bundled-references/maggiedash-booking/ORAWELLNESS-INTEGRATION-AUDIT.md +64 -21
- package/bundled-references/maggiedash-booking/PRD.md +9 -1
- package/bundled-references/maggiedash-booking/PROGRESS.md +244 -2399
- package/bundled-references/maggiedash-booking/QA-TEST-PLAN.md +37 -6
- package/bundled-references/maggiedash-booking/README.md +23 -6
- package/bundled-references/maggiedash-booking/RUNTIME-OPERATIONS.md +64 -8
- package/bundled-references/maggiedash-booking/SKILLS-AND-CLI.md +11 -2
- package/bundled-references/maggiedash-booking/STRIPE-INTEGRATION.md +66 -2
- package/bundled-references/maggiedash-booking/TASK-RUNBOOK.md +1 -1
- package/bundled-references/maggiedash-booking/TASKS.md +44 -3
- package/bundled-references/maggiedash-booking/VOUCHERS.md +47 -0
- package/bundled-references/provider-adapter-contract.md +33 -0
- package/bundled-skills/maggie-booking/SKILL.md +8 -0
- package/bundled-skills/maggie-clone-to-template/SKILL.md +26 -0
- package/bundled-skills/maggie-deployment/SKILL.md +53 -1
- package/bundled-skills/maggie-deployment/references/vps.md +41 -0
- package/bundled-skills/maggie-design/SKILL.md +99 -0
- package/bundled-skills/maggie-feedback/SKILL.md +38 -1
- package/bundled-skills/maggie-marketplace/SKILL.md +91 -0
- package/bundled-skills/maggie-qa-workflow/SKILL.md +41 -1
- package/bundled-skills/maggie-service-booking/SKILL.md +23 -0
- package/bundled-skills/maggie-social-share/SKILL.md +37 -5
- package/bundled-skills/maggie-social-share/references/queue-and-connections.md +101 -0
- package/bundled-skills/maggie-template/SKILL.md +57 -3
- package/bundled-skills/maggie-template/references/template-content-v1.example.json +34 -0
- package/bundled-tools/clis/maggie_booking.py +199 -26
- package/bundled-tools/clis/maggie_booking_vouchers.py +185 -0
- package/bundled-tools/clis/maggie_clone_to_template.py +14 -0
- package/bundled-tools/clis/maggie_deployment.py +249 -1
- package/bundled-tools/clis/maggie_design.py +9 -0
- package/bundled-tools/clis/maggie_design_lint.py +277 -0
- package/bundled-tools/clis/maggie_feedback.py +106 -3
- package/bundled-tools/clis/maggie_marketplace.py +199 -5
- package/bundled-tools/clis/maggie_palette.py +280 -0
- package/bundled-tools/clis/maggie_qa_workflow.py +156 -1
- package/bundled-tools/clis/maggie_social_queue.py +338 -0
- package/bundled-tools/clis/maggie_social_share.py +42 -9
- package/bundled-tools/clis/maggie_template_package.py +1141 -0
- package/package.json +1 -1
- package/references/browser-inspection.md +25 -0
- package/references/provider-adapter-contract.md +33 -0
|
@@ -45,6 +45,19 @@ allocation is rejected inside a rolled-back transaction. It also verifies the
|
|
|
45
45
|
normalized payment-event columns, availability snapshot table, and a
|
|
46
46
|
PostgreSQL advisory-lock round trip.
|
|
47
47
|
|
|
48
|
+
Canonical browser evidence capture treats both network-level request failures
|
|
49
|
+
and HTTP responses with status 400 or higher as failed requests. Failure
|
|
50
|
+
records retain viewport, method, status (for HTTP failures), and origin, but
|
|
51
|
+
omit URL paths and query strings so customer identifiers and bearer-like URL
|
|
52
|
+
values are not copied into the evidence artifact. Console and capture errors
|
|
53
|
+
are recorded as route-level codes without raw browser or exception text. The
|
|
54
|
+
GitHub Actions artifact allowlist includes only `evidence.json` and screenshots;
|
|
55
|
+
the protected `storage-state.json` is excluded even when a workflow step fails. Run
|
|
56
|
+
`npm run booking:browser:evidence:test` to check those cases and the 51-screen
|
|
57
|
+
validator contract. Runtime and browser capture commands also avoid printing
|
|
58
|
+
raw plan/exception contents to workflow logs; only allowlisted target error
|
|
59
|
+
codes are emitted, and all other capture errors use a generic code.
|
|
60
|
+
|
|
48
61
|
The worker repository boundary has a separate source gate:
|
|
49
62
|
|
|
50
63
|
```bash
|
|
@@ -140,6 +153,9 @@ provider payment attempts for one client action.
|
|
|
140
153
|
|
|
141
154
|
For desktop and mobile:
|
|
142
155
|
|
|
156
|
+
- On the public customer booking page, select a slot, change the native date,
|
|
157
|
+
verify availability reloads for the new date, and ensure the prior slot is
|
|
158
|
+
cleared before checkout can be submitted.
|
|
143
159
|
- login redirect and return path;
|
|
144
160
|
- sidebar/workspace navigation;
|
|
145
161
|
- overview empty/loading/error/provider-outage states;
|
|
@@ -171,13 +187,28 @@ release-gate.json
|
|
|
171
187
|
```
|
|
172
188
|
|
|
173
189
|
The protected workflow
|
|
174
|
-
`.github/workflows/booking-browser-evidence.yml` captures
|
|
190
|
+
`.github/workflows/booking-browser-evidence.yml` captures all 17 Booking
|
|
175
191
|
routes at 390x844, 768x1024, and 1440x1000, with a host session supplied by an
|
|
176
|
-
environment-scoped secret.
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
192
|
+
environment-scoped secret. The v2 contract maps every route to its expected
|
|
193
|
+
primary heading. Capture records the final pathname and visible `main h1`;
|
|
194
|
+
`validate-booking-browser-evidence.mjs` rejects a route redirect, the wrong
|
|
195
|
+
screen heading, missing routes or screenshots, non-2xx responses, login
|
|
196
|
+
redirects, console errors, failed network requests, and horizontal overflow
|
|
197
|
+
reported in `layoutErrors`. Browser evidence must come from a dedicated test
|
|
198
|
+
tenant and must never include committed cookies or customer exports.
|
|
199
|
+
Existing v1 artifacts do not satisfy the current v2 gate and must be recaptured;
|
|
200
|
+
do not relabel older evidence because it lacks the route-specific observations.
|
|
201
|
+
|
|
202
|
+
The canonical MaggieDash workflows, the ORA repository's root workflows, and
|
|
203
|
+
both capture commands validate `base_url` against the selected GitHub
|
|
204
|
+
environment's exact-host
|
|
205
|
+
`BOOKING_TEST_HOST_ALLOWLIST` variable. The value is a comma- or
|
|
206
|
+
whitespace-separated list of hostnames; wildcards, non-HTTPS URLs, URLs with
|
|
207
|
+
paths/credentials, and unlisted hosts are rejected. The workflows run this
|
|
208
|
+
preflight before writing session-state or runtime-plan material, then pass the
|
|
209
|
+
allowlist into the capture command for an independent second check. Configure
|
|
210
|
+
only dedicated Booking test hosts in this variable; do not add the production
|
|
211
|
+
host.
|
|
181
212
|
|
|
182
213
|
The protected workflow
|
|
183
214
|
`.github/workflows/booking-runtime-evidence.yml` captures all 47 host adapter
|
|
@@ -97,6 +97,8 @@ This repository currently provides:
|
|
|
97
97
|
the host still supplies the concrete official SDK adapter;
|
|
98
98
|
- a manager Reports screen and tenant-scoped `/reports.json` read model for
|
|
99
99
|
period totals plus day, service, staff, and location breakdowns;
|
|
100
|
+
- venue-time manager booking displays and wall-clock inputs, with DST-gap
|
|
101
|
+
rejection and explicit choices for repeated fall-back times;
|
|
100
102
|
- an idempotent 24-hour reminder worker job that queues confirmed-booking
|
|
101
103
|
reminders into the existing Resend notification outbox;
|
|
102
104
|
- service-level payment policies (`full`, `deposit`, `pay_later`, and
|
|
@@ -120,8 +122,10 @@ customer-flow boundary are implemented locally. A secret-free reference host
|
|
|
120
122
|
and an Astro host scaffold are also available for contract/browser work. A host
|
|
121
123
|
must still apply the schema, prove PostgreSQL transactions, verify a real
|
|
122
124
|
payment account and webhook, enable notification delivery and tenant locking,
|
|
123
|
-
and capture authenticated
|
|
124
|
-
bookings can be enabled.
|
|
125
|
+
and capture authenticated browser/runtime/ops evidence against a dedicated
|
|
126
|
+
HTTPS test tenant before real bookings can be enabled. Test evidence workflows
|
|
127
|
+
must not target production; any production observation needs its own approved,
|
|
128
|
+
read-only plan.
|
|
125
129
|
Resend is the server-side notification and account-email transport. Staff
|
|
126
130
|
invitation, first-login setup, password reset, one-time token expiry, and
|
|
127
131
|
session revocation are implemented in the Astro host scaffold; real delivery
|
|
@@ -136,18 +140,31 @@ charges/payouts enablement, and a webhook secret. Raw Stripe credentials are
|
|
|
136
140
|
never returned by the API or stored as plaintext Booking data. Deployment
|
|
137
141
|
secrets take precedence over dashboard-managed credentials.
|
|
138
142
|
|
|
139
|
-
##
|
|
143
|
+
## Verification snapshot — 2026-09-28
|
|
144
|
+
|
|
145
|
+
This dated snapshot records the earlier 0.7.48 candidate review and 15-route
|
|
146
|
+
local browser smoke. It is historical; for the current task count, browser
|
|
147
|
+
contract, and release blockers, use [`CURRENT-STATE.md`](./CURRENT-STATE.md).
|
|
148
|
+
|
|
149
|
+
| Item | Current evidence |
|
|
150
|
+
|---|---|
|
|
151
|
+
| MaggieDash and ai-cmo source | MaggieDash package `0.2.11`; ai-cmo `0.7.48` (published) |
|
|
152
|
+
| Email-template boundary | Ten events, including `payment.no_show_fee`; confirmed bookings allow a host-supplied, escaped `arrivalNote` |
|
|
153
|
+
| ORA source CLI check | Local ai-cmo source `email-templates-contract` and `inspect --project` pass; the installed global package still carries the old nine-event contract and requires a package release/install readback |
|
|
154
|
+
| Regression evidence | MaggieDash `npm test`, 25 targeted ai-cmo Booking Python tests, and ORA email-template/customer validators pass; ORA Astro build passes |
|
|
155
|
+
|
|
156
|
+
## Historical verification snapshot — 2026-09-21
|
|
140
157
|
|
|
141
158
|
| Item | Current evidence |
|
|
142
159
|
|---|---|
|
|
143
160
|
| 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 |
|
|
161
|
+
| Delivery board | 101 implementation tasks passed and 3 real-host evidence tasks pending (BK-030, BK-031, BK-032). The current browser contract requires all 17 manager routes across three viewports (51 screens), including Packages and Email templates; prior 45-screen captures are historical subset evidence. |
|
|
145
162
|
| Local code gates | MaggieDash `npm test`, contract/UI/security/customer/runtime validators, and Python task-board/link checks passed |
|
|
146
163
|
| 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
164
|
| 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
165
|
| 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
166
|
| 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 |
|
|
167
|
+
| Local browser smoke | At this historical snapshot the browser contract covered 15 manager routes (`45` route/viewport screens). The current v2 contract now covers 17 routes and requires route-specific path/heading evidence; the earlier artifact is not reused as complete evidence. |
|
|
151
168
|
| Production proof | Not yet complete; reference-host and fixture artifacts are explicitly not production evidence |
|
|
152
169
|
|
|
153
170
|
## Current product limits
|
|
@@ -231,7 +248,7 @@ only.
|
|
|
231
248
|
5. Enable one worker scheduler with lock, alert, retry, and dead-letter proof;
|
|
232
249
|
verify Resend invitation, reset, reminder, waitlist, refund, package, and
|
|
233
250
|
no-show delivery.
|
|
234
|
-
6. Capture the 47-endpoint runtime,
|
|
251
|
+
6. Capture the 47-endpoint runtime, 51-screen browser, and ops evidence bundle;
|
|
235
252
|
run the final release gate before a one-location canary.
|
|
236
253
|
|
|
237
254
|
The detailed execution board is maintained by
|
|
@@ -13,7 +13,8 @@ provider adapters, email/SMS, secrets, tenant scope, and deployment.
|
|
|
13
13
|
| Payment webhook | `payment_attempts`, `webhook_events`, `events`, `audit_events` | `payment-webhook.mjs`, `booking.provider.webhook` | host server route |
|
|
14
14
|
| Payment reconciliation | `payment_attempts`, `refunds`, `webhook_events` | `reconcilePaymentEvents` and `booking.payment.*` endpoints | host worker/provider adapter |
|
|
15
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-
|
|
16
|
+
| Browser evidence | no business tables; artifact storage only | `booking-browser-evidence-v2.json` and capture/validate scripts | protected CI environment |
|
|
17
|
+
| Worker freshness | `maggiedash_booking_worker_status` | successful write-cycle timestamp, read by the next cycle's `worker.stale` health check | host worker + scheduler |
|
|
17
18
|
|
|
18
19
|
## Worker sequence
|
|
19
20
|
|
|
@@ -31,16 +32,46 @@ lock tenant
|
|
|
31
32
|
unlock tenant
|
|
32
33
|
```
|
|
33
34
|
|
|
35
|
+
Sanitized ops evidence uses UTC timestamps and must preserve the sequence
|
|
36
|
+
`backupVerifiedAt <= restoreVerifiedAt <= generatedAt`. Validators reject a
|
|
37
|
+
restore before its backup, a report generated before restore verification, and
|
|
38
|
+
non-object evidence roots. Direct CLI validation reports a bounded
|
|
39
|
+
`BOOKING_CHECK_FAILED` input error for a non-object JSON file; `release-gate`
|
|
40
|
+
continues and returns a structured `blocked` result with ops status `failed`.
|
|
41
|
+
|
|
34
42
|
The database exclusion constraints remain the final double-booking guard. A
|
|
35
43
|
distributed lock reduces duplicate work but is not a correctness substitute.
|
|
36
44
|
|
|
45
|
+
Each worker acquires its tenant lock before loading worker state. If another
|
|
46
|
+
cycle holds the lock, the runner exits with `status: "skipped"`,
|
|
47
|
+
`worker.lock_contention` at warning severity, and `stateChanged: false`. It
|
|
48
|
+
does not read worker state, write rows, dispatch providers, or mark the cycle
|
|
49
|
+
as a failure. Database/lock acquisition errors still produce a failed worker
|
|
50
|
+
report and must be monitored by the scheduler.
|
|
51
|
+
|
|
37
52
|
Every installed PostgreSQL worker performs a read-only schema preflight before
|
|
38
|
-
acquiring the tenant lock. It checks the core, Booking,
|
|
39
|
-
migration is missing, it exits with code 1 and emits bounded JSON with
|
|
53
|
+
acquiring the tenant lock. It checks the core, Booking, access, and persisted
|
|
54
|
+
worker-status tables. If a migration is missing, it exits with code 1 and emits bounded JSON with
|
|
40
55
|
`status: "needs-migration"`; it does not load worker state, acquire the lock,
|
|
41
56
|
or write business rows. Operators should run the schema command's `--dry-run`
|
|
42
57
|
before an explicitly approved `--apply --confirm` migration.
|
|
43
58
|
|
|
59
|
+
The repository reads `last_success_at` for the selected tenant before the cycle
|
|
60
|
+
and upserts it only when a write-mode cycle passes. That timestamp is persisted
|
|
61
|
+
in the same transaction as the worker state and is supplied to the next
|
|
62
|
+
cycle's `worker.stale` evaluation. A successful write returns the committed
|
|
63
|
+
status timestamp and uses it in that cycle's health report, so the report does
|
|
64
|
+
not retain a stale pre-write value. Preview runs do not advance it and continue
|
|
65
|
+
to evaluate the persisted timestamp. If an adapter write fails after state is
|
|
66
|
+
loaded, the structured error output retains that prior timestamp for stale
|
|
67
|
+
health evaluation. An external scheduler monitor is still required to detect
|
|
68
|
+
a worker that never starts, because no in-process health report can be emitted
|
|
69
|
+
while the process is down.
|
|
70
|
+
The additive status table is now present in ORA staging; the six-job preview
|
|
71
|
+
there passed with `write=false`, zero alerts, and no provider dispatch. The
|
|
72
|
+
preview intentionally left `last_success_at` empty. Production still needs the
|
|
73
|
+
schema migration before the updated worker can run.
|
|
74
|
+
|
|
44
75
|
Notification delivery is intentionally after booking/payment truth is committed.
|
|
45
76
|
`notifications.mjs` stores only a recipient hash and allowlisted template
|
|
46
77
|
variables, leases rows before dispatch, retries with exponential backoff, moves
|
|
@@ -66,6 +97,28 @@ payment signal.
|
|
|
66
97
|
|
|
67
98
|
## Host adapter module
|
|
68
99
|
|
|
100
|
+
The worker supports `--help`, which exits before loading environment values or
|
|
101
|
+
connecting to PostgreSQL. The worker defaults to preview mode. A preview reports eligible outbox rows as
|
|
102
|
+
`previewed` and never invokes `dispatchNotification`; it does not write the
|
|
103
|
+
claim or delivery result. `--write` performs database writes and invokes the
|
|
104
|
+
host provider for each claimed notification. Reconcile staging outbox/provider
|
|
105
|
+
activity before any write-mode run.
|
|
106
|
+
|
|
107
|
+
The generic Astro PostgreSQL worker and ORA host worker include the
|
|
108
|
+
schema-versioned `health` summary in successful cycle output and caught
|
|
109
|
+
schema/lock/runtime failures. It carries stable alert codes, severity, a
|
|
110
|
+
correlation ID, and counts only; the worker does not send an alert itself.
|
|
111
|
+
Route critical reports from the host's structured log pipeline to its chosen
|
|
112
|
+
alert destination. Configuration and database connection failures that occur
|
|
113
|
+
before worker startup remain process-level errors and must also be monitored by
|
|
114
|
+
the scheduler. Structured startup and runtime errors pass through the shared
|
|
115
|
+
redactor, which removes known secret environment values, connection URIs,
|
|
116
|
+
bearer/API tokens, customer email and phone numbers, and sensitive key/value
|
|
117
|
+
fragments before writing JSON.
|
|
118
|
+
When the provider accepts a notification, its opaque `providerRef` is retained
|
|
119
|
+
on the sent outbox row for provider activity reconciliation; it is not exposed
|
|
120
|
+
through customer-facing DTOs.
|
|
121
|
+
|
|
69
122
|
The production command accepts a host module:
|
|
70
123
|
|
|
71
124
|
```bash
|
|
@@ -117,10 +170,12 @@ state write.
|
|
|
117
170
|
|
|
118
171
|
The protected workflow in
|
|
119
172
|
`.github/workflows/booking-browser-evidence.yml` requires an HTTPS base URL and
|
|
120
|
-
an environment-scoped, short-lived storage state.
|
|
121
|
-
screens at mobile/tablet/desktop widths
|
|
122
|
-
|
|
123
|
-
|
|
173
|
+
an environment-scoped, short-lived storage state. The v2 contract captures all
|
|
174
|
+
17 manager screens at mobile/tablet/desktop widths and binds each route to its
|
|
175
|
+
expected primary heading. Evidence records the final pathname and rendered
|
|
176
|
+
heading; validation rejects wrong-route redirects, a wrong screen rendered at
|
|
177
|
+
the requested URL, missing screens, non-2xx responses, and browser/network
|
|
178
|
+
errors. Artifacts are retained for 14 days.
|
|
124
179
|
|
|
125
180
|
Never commit storage state, cookies, screenshots with customer data, or raw
|
|
126
181
|
provider payloads. Use a dedicated test tenant and redact artifacts before
|
|
@@ -138,7 +193,8 @@ must never be used as production evidence.
|
|
|
138
193
|
|
|
139
194
|
Alert on:
|
|
140
195
|
|
|
141
|
-
- worker lock contention or two missed
|
|
196
|
+
- worker lock contention, a stale last successful write cycle, or two missed
|
|
197
|
+
minute ticks;
|
|
142
198
|
- availability read model older than five minutes;
|
|
143
199
|
- holds expiring above baseline;
|
|
144
200
|
- payment webhook verification/quarantine spikes or reconciliation lag;
|
|
@@ -210,6 +210,12 @@ present it reports `dashboard-or-host-secret-pending` and points the signed-in
|
|
|
210
210
|
owner/manager to the secure Booking Overview connection form. A partial
|
|
211
211
|
deployment pair remains `degraded` because the dashboard form is intentionally
|
|
212
212
|
not allowed to override deployment-managed credentials.
|
|
213
|
+
For compatibility with the existing ORA host, `setup` also recognizes
|
|
214
|
+
`ST_SECRECT_KEY` as a legacy alias for `STRIPE_SECRET_KEY`; a complete alias
|
|
215
|
+
plus `STRIPE_WEBHOOK_SECRET` pair is still only
|
|
216
|
+
`online-payments-pending-verification`. New deployments should use the
|
|
217
|
+
canonical name, and only the authenticated Booking connection check can verify
|
|
218
|
+
that the credentials connect to the intended Stripe account.
|
|
213
219
|
`contract` accepts both the source contract JSON Schema and the compact
|
|
214
220
|
ai-cmo-skills contract representation. It never reads secrets or customer data.
|
|
215
221
|
|
|
@@ -445,8 +451,11 @@ maggie booking release-gate --project . --require-runtime \
|
|
|
445
451
|
--require-board
|
|
446
452
|
```
|
|
447
453
|
|
|
448
|
-
The browser gate checks all
|
|
449
|
-
screenshot paths,
|
|
454
|
+
The browser gate checks all 17 screens at mobile/tablet/desktop widths, safe
|
|
455
|
+
screenshot paths, PNG/JPEG content matching the file extension, exact viewport
|
|
456
|
+
width and at least viewport height (host captures use `fullPage`), ready state,
|
|
457
|
+
no console errors, and no failed requests. Screenshot artifacts are capped at
|
|
458
|
+
25 MiB each.
|
|
450
459
|
The board gate additionally fails closed until every task in
|
|
451
460
|
`docs/maggiedash-booking/EXECUTION-BOARD.json` is `passed`; use `--board` to
|
|
452
461
|
inspect a different board.
|
|
@@ -59,7 +59,8 @@ states (`requires_action`, `pending`, `failed`, `succeeded`, `cancelled`, and
|
|
|
59
59
|
The first adapter should subscribe only to events the configured capabilities
|
|
60
60
|
need:
|
|
61
61
|
|
|
62
|
-
- `checkout.session.completed`, `checkout.session.
|
|
62
|
+
- `checkout.session.completed`, `checkout.session.expired`,
|
|
63
|
+
`checkout.session.async_payment_succeeded`,
|
|
63
64
|
and `checkout.session.async_payment_failed`;
|
|
64
65
|
- `payment_intent.processing`, `payment_intent.payment_failed`,
|
|
65
66
|
`payment_intent.succeeded`, `payment_intent.requires_action`, and
|
|
@@ -104,6 +105,47 @@ accounting, CRM, support, analytics, marketing, and workflow automation. It is
|
|
|
104
105
|
an integration surface, not a reason to add third-party credentials to the
|
|
105
106
|
MaggieDash browser bundle.
|
|
106
107
|
|
|
108
|
+
## Live setup runbook (read-only verification)
|
|
109
|
+
|
|
110
|
+
Switching a host to live mode is the step most likely to create real objects
|
|
111
|
+
by accident. A probe that was expected to fail has created a real live object,
|
|
112
|
+
so the live checklist is strictly read-only from the agent side:
|
|
113
|
+
|
|
114
|
+
1. **Verify with GET only.** Use list/retrieve calls (`GET /v1/account`,
|
|
115
|
+
`GET /v1/webhook_endpoints`, `GET /v2/core/event_destinations` or the
|
|
116
|
+
SDK equivalents, `GET /v1/products?limit=…`) to confirm account mode,
|
|
117
|
+
enabled capabilities, endpoint URLs, and subscribed events. Never use a
|
|
118
|
+
`POST`/create call as a probe "to see whether it fails"; in live mode it may
|
|
119
|
+
succeed. If a write is genuinely required, show the exact request to the
|
|
120
|
+
owner and run it only after explicit approval.
|
|
121
|
+
2. **Install signing secrets through a user-run, no-echo command.** The agent
|
|
122
|
+
must not see, print, or paste webhook or Connect event-destination signing
|
|
123
|
+
secrets. Give the owner a command they run themselves, for example:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
read -rs STRIPE_WEBHOOK_SECRET && printf '%s' "$STRIPE_WEBHOOK_SECRET" \
|
|
127
|
+
| wrangler secret put STRIPE_WEBHOOK_SECRET # or the host's secret store
|
|
128
|
+
unset STRIPE_WEBHOOK_SECRET
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Then verify presence only (secret name listed, value never read back).
|
|
132
|
+
3. **Thin-event destination secrets are not retrievable via the API.** A
|
|
133
|
+
Connect/thin-event destination's signing secret is shown once in the
|
|
134
|
+
Dashboard when the destination is created or rolled. If it was not
|
|
135
|
+
captured, roll it in the Dashboard and install the new value with step 2;
|
|
136
|
+
do not try to fetch it programmatically.
|
|
137
|
+
4. **Hand Dashboard steps to the owner.** The Stripe Dashboard can be unusable
|
|
138
|
+
under browser automation (bot challenges, 2FA, session prompts). Treat
|
|
139
|
+
Dashboard-only steps — activating live mode, creating or rolling event
|
|
140
|
+
destinations, revealing secrets, Connect onboarding — as owner tasks with a
|
|
141
|
+
written checklist, then confirm the result with the read-only calls above.
|
|
142
|
+
5. **Record evidence, not values.** Capture account mode, endpoint IDs, event
|
|
143
|
+
lists, and secret *presence* in the release evidence; never key material.
|
|
144
|
+
|
|
145
|
+
`maggie booking setup` and `maggie booking stripe-audit` do not call Stripe:
|
|
146
|
+
they read local configuration and the versioned capability contract only.
|
|
147
|
+
Any host-side live readiness check must likewise issue `GET` requests only.
|
|
148
|
+
|
|
107
149
|
## Recommended rollout order
|
|
108
150
|
|
|
109
151
|
1. Stripe Customers + Checkout Sessions or PaymentIntents.
|
|
@@ -114,7 +156,8 @@ MaggieDash browser bundle.
|
|
|
114
156
|
6. Billing/Portal for memberships; Terminal for in-person operations; Connect
|
|
115
157
|
only for a true platform model.
|
|
116
158
|
7. Gift-card partner or local ledger after accounting and redemption rules are
|
|
117
|
-
approved.
|
|
159
|
+
approved. The local-ledger option is fixed by the
|
|
160
|
+
[voucher lifecycle contract](./VOUCHERS.md).
|
|
118
161
|
|
|
119
162
|
Run the local contract gate with:
|
|
120
163
|
|
|
@@ -127,3 +170,24 @@ maggie booking stripe-audit --contract /path/to/MaggieDash/contracts/stripe-book
|
|
|
127
170
|
No production payment, refund, gift-card issue, or referral reward is enabled
|
|
128
171
|
by this document. The host must add its adapter, integration tests, secret
|
|
129
172
|
configuration, and runtime evidence first.
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
Public customer booking payments explicitly request the hosted Checkout flow.
|
|
176
|
+
The PostgreSQL payment adapter preserves `hosted` in the normalized request,
|
|
177
|
+
its idempotency hash, and provider call; the Stripe adapter then creates one
|
|
178
|
+
Checkout Session for that payment attempt. Package purchases already use the
|
|
179
|
+
same hosted flow.
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
Hosted Checkout Sessions request a 31-minute expiry, above Stripe's 30-minute
|
|
183
|
+
minimum. Reconciliation recognizes `cs_` references and retrieves the Checkout
|
|
184
|
+
Session; open sessions remain pending, paid sessions succeed and adopt the
|
|
185
|
+
PaymentIntent reference when Stripe provides one, and expired sessions map to
|
|
186
|
+
the provider-neutral cancelled state.
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
For Checkout's asynchronous payment methods, supported `checkout.session.*`
|
|
190
|
+
webhooks retain the Session's PaymentIntent reference when Stripe provides one.
|
|
191
|
+
The Session ID is the fallback for events without a PaymentIntent, such as an
|
|
192
|
+
expired unpaid Checkout. This keeps later reconciliation and refund requests
|
|
193
|
+
on the provider object they expect.
|
|
@@ -79,7 +79,7 @@ maggie booking release-gate --project . --require-runtime \
|
|
|
79
79
|
--require-ops --ops-evidence .maggie/booking/ops-evidence.json
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
`--require-browser` applies the same
|
|
82
|
+
`--require-browser` applies the same 17-screen × 3-viewport checks (51 screens) as the
|
|
83
83
|
browser evidence validator, including safe screenshot paths, ready state,
|
|
84
84
|
empty console errors, and empty failed-request reports.
|
|
85
85
|
|
|
@@ -40,8 +40,8 @@ or evidence gate. The detailed leaf-task board is
|
|
|
40
40
|
| BK-027 | Finish Booking UI data loading, navigation, forms, and action feedback | MaggieDash | BK-018, BK-022, BK-023 | typed route loading, pagination, dialogs, forms, feedback | UI source gate + esbuild + reference-host Chrome smoke | passed |
|
|
41
41
|
| BK-028 | Finish manager daily operations journeys | MaggieDash | BK-021, BK-023, BK-027 | calendar modes, lifecycle/reschedule, payment operations, audit views | UI source gate + reference-host Chrome interaction smoke | passed |
|
|
42
42
|
| BK-029 | Verify authentication, tenancy, roles, and privacy boundaries | both | BK-019, BK-022, BK-027 | session/role/project checks, staff lifecycle-only mutations, payment/customer denial, and redaction scan | security validator + contract gate | passed |
|
|
43
|
-
| BK-030 | Wire the production worker and operational controls | both | BK-020, BK-021, BK-024, BK-026 | injected PostgreSQL worker
|
|
44
|
-
| BK-031 | Capture real host conformance and browser evidence | both | BK-019, BK-022, BK-028, BK-029, BK-030 |
|
|
43
|
+
| BK-030 | Wire the production worker and operational controls | both | BK-020, BK-021, BK-024, BK-026 | injected PostgreSQL worker adapter, serialized tenant-scoped reads, no-provider dry-run, credential-free `--help`, tenant lock, correlation/health report with a persisted tenant-scoped last-success timestamp, dead-letter policy, ops evidence contract, production fixture guard, executable backup/restore rehearsal, and reviewed systemd/cron schedule generation | adapter/repository/health/ops evidence tests + safe installed `--help` checks + `maggie booking worker-schedule` + real disposable worker cycle/schema/lock + staging no-dispatch preview + backup/restore integration; lock contention skips before state load and provider dispatch; `worker.stale` reads the persisted prior success and the status table is preflighted; ORA staging migration, six-job preview, and real PostgreSQL integration passed; redaction covers customer email and phone numbers; ORA staging tools now enforce normalized production/staging database separation and provide a read-only cleanup audit; local backup/restore rehearsal passed; ORA production timer observed active and write-capable; provider activity review, alert routing, and host recovery evidence pending | needs-evidence |
|
|
44
|
+
| BK-031 | Capture real host conformance and browser evidence | both | BK-019, BK-022, BK-028, BK-029, BK-030 | ORA local Chrome v2 QA now checks all 17 manager routes at 3 viewports (51/51 normalized route/heading/layout passes, zero captured console errors, no horizontal overflow). A post-BK-141 localhost smoke also confirms Calendar venue-zone rendering and the Bookings direct route/New booking dialog after fixing a missing dirty-state hook and SSR hydration mismatch. Failed network requests were not observable and screenshot bitmap dimensions vary, so local artifacts remain supplemental only. The ORA repo `.env` has no dedicated HTTPS staging base URL; protected workflow secrets were not inspected. Canonical MaggieDash and ORA root workflows now run the exact environment host-allowlist preflight before protected state writes and pass the allowlist to capture for a second check; regression and contract checks cover workflow ordering. Authenticated HTTPS-host evidence for all 47 endpoints and the canonical 51-screen browser artifact remain open | `npm run booking:runtime:plan:test` + MaggieDash `npm test` + ORA `booking:evidence-target:test`, `contract:check`, Astro check/build + protected-workflow order/allowlist regression + canonical/ORA helper byte parity + ORA local Chrome QA (supplemental only) | needs-evidence |
|
|
45
45
|
| BK-032 | Run release gate, canary, documentation, and feedback closure | both | BK-025, BK-030, BK-031, BK-033, BK-034, BK-035, BK-036, BK-037, BK-038 | final release report, browser artifact parity/layout rejection, and docs | `maggie booking release-gate --require-runtime --require-browser --require-ops --require-board` | needs-evidence |
|
|
46
46
|
| BK-033 | Freeze and validate the public customer booking boundary | both | BK-021, BK-024, BK-026 | public-noindex catalog/availability/hold/checkout/payment-return/cancel contract, redacted DTOs, notification intents, and host safety boundary | `npm run booking:customer-flow:test` + `npm test` | passed |
|
|
47
47
|
| BK-034 | Ship the public customer booking page and pending-payment recovery UI | MaggieDash | BK-033 | installable customer page source, Astro route starter, catalog/availability/hold/checkout/pending-return UI, and noindex/public request checks | `npm run booking:customer-ui:test` + manifest/install validation | passed |
|
|
@@ -94,7 +94,7 @@ or evidence gate. The detailed leaf-task board is
|
|
|
94
94
|
| BK-081 | Harden first-owner registration | both | BK-058, BK-071 | Serialize first-owner registration, verify existing passwords, and prevent password overwrite or disabled-account reactivation | MaggieDash bootstrap validator + `npm test` + ORA `contract:check`/build + `git diff --check` | passed |
|
|
95
95
|
| BK-082 | Harden Booking access defaults and disabled-account boundary | both | BK-026, BK-081 | Give invited staff/finance accounts safe role defaults, preserve granular permissions, and reject disabled accounts instead of re-enabling them | MaggieDash bootstrap validator + `npm test` + ORA `contract:check`/build + `git diff --check` | passed |
|
|
96
96
|
| BK-083 | Add worker migration preflight | both | BK-030, BK-070 | Check core, Booking, and access tables before worker lock/repository reads and return bounded `needs-migration` JSON without writes or stack traces | worker `node --check` + Astro bootstrap validator + unmigrated ORA worker run + `git diff --check` | passed |
|
|
97
|
-
| BK-084 | Synchronize browser evidence with the complete manager workspace | both | BK-080, BK-083 |
|
|
97
|
+
| BK-084 | Synchronize browser evidence with the complete manager workspace | both | BK-080, BK-083 | Covered the then-current 15 manager routes across mobile, tablet, and desktop; BK-120 extends the evidence set to all 17 current routes | MaggieDash `npm test` + ORA contract/build + ai-cmo Booking tests + packaged task validation + `git diff --check` | passed |
|
|
98
98
|
| BK-085 | Make cancellation and refund policy tenant-configurable and booking-scoped | both | BK-064, BK-084 | Configure cutoff/refund/no-show policy, snapshot it on every booking creation path, and enforce customer cancellation cutoff without pretending provider refunds are automatic | MaggieDash `npm test` + ORA contract/build + policy validators + `git diff --check` | passed |
|
|
99
99
|
| BK-086 | Make calendar day and week views honor their requested venue-local range | both | BK-084, BK-085 | Filter Day/Week queries by the correct venue-local range, keep staff scope, and align reference host/UI behavior with the PostgreSQL contract | MaggieDash `npm test` + calendar/repository validators + ORA contract/build + `git diff --check` | passed |
|
|
100
100
|
| BK-087 | Execute cancellation refunds through the provider boundary and Resend outbox | both | BK-080, BK-085, BK-086 | Allocate policy-safe refunds across captured attempts, call the injected provider after cancellation, expose bounded settlement status, queue payment.refunded only for accepted/pending refunds, and keep generic/ORA Resend workers behaviorally aligned | MaggieDash `npm test` + cancellation/customer settlement validators + Astro bootstrap validator + ORA contract/build + `git diff --check` | passed |
|
|
@@ -115,9 +115,20 @@ or evidence gate. The detailed leaf-task board is
|
|
|
115
115
|
| BK-101 | Complete server-enforced Booking capability permissions | both | BK-089, BK-100 | Reconcile every route capability with the administrator registry, enforce safe role defaults for legacy rows, honor explicitly granted staff reads, and synchronize generic/ORA/reference-host/CLI contracts | MaggieDash npm/access/route-handler gates, ORA contract/build, ai-cmo Booking tests, and `git diff --check` | passed |
|
|
116
116
|
| BK-102 | Persist provider customer identity for real Stripe payments | both | BK-025, BK-100 | Resolve local tenant customer UUIDs to idempotent Stripe Customer objects, persist only the provider reference, and use it for Checkout/PaymentIntent/SetupIntent without leaking credentials or cross-tenant data | Stripe adapter conformance with customer resolver, central/ORA schema validators, ORA contract/build, MaggieDash `npm test`, and `git diff --check` | passed |
|
|
117
117
|
| BK-103 | Add consented Stripe no-show fee charging | both | BK-088, BK-102 | Add an explicit manager/finance action that charges only a policy-derived no-show fee when the customer consented, a saved payment method is available, and Stripe off-session capability is verified; persist adjustment payment/audit state and queue the Resend payment notification | Stripe adapter, payment adapter, route/reference-host, email, UI, central `npm test`, ORA contract/build, and `git diff --check` | passed |
|
|
118
|
+
| BK-104 | Gate public booking exposure on host readiness | both | BK-033, BK-034 | Shared fail-closed readiness gate and test override; gate Astro customer page and new customer creation routes while preserving customer continuations; install the source manifest and reuse route policy in ORA | MaggieDash `npm test` + Astro host-bootstrap gate + direct route guard tests + ORA public-gate/build + source CLI install parity | passed |
|
|
119
|
+
| BK-105 | Synchronize ORA Booking CLI gates with current contracts | both | BK-097, BK-100 | Sync ORA-local inspect/setup validator and source contract with the canonical ten-event template contract, `arrivalNote`, and Stripe key alias behavior while preserving pending-verification semantics | ORA-local inspect/setup/email-template contract + canonical Booking CLI unit tests + byte-parity + whitespace checks | passed |
|
|
120
|
+
| BK-106 | Explain Stripe connection checks in the Booking setup checklist | MaggieDash | BK-100, BK-105 | Show API, webhook, charge and payout check results, with a clear action when the account cannot accept payments | Booking UI validator + MaggieDash `npm test` + task-board validation + `git diff --check` | passed |
|
|
121
|
+
| BK-107 | Derive online-payment capability from verified Stripe charge availability | both | BK-100, BK-104, BK-106 | Keep online/off-session payment disabled until the credential is verified and Stripe reports charges enabled; mirror the rule into ORA | Stripe readiness regression + host-bootstrap + MaggieDash `npm test` + ORA contract/build + byte parity | passed |
|
|
122
|
+
| BK-108 | Fail closed when online-payment capability is missing | both | BK-107 | Missing payment capability in stored settings must not make manager Overview or payment-health report payments ready | PostgreSQL core repository regression + MaggieDash `npm test` + ORA contract/build + source parity | passed |
|
|
118
123
|
|
|
119
124
|
## Execution rule
|
|
120
125
|
|
|
126
|
+
| BK-109 | Require explicit online-payment capability in shared payment flows | both | BK-108 | Shared payment starts and reference-host readiness must fail closed unless onlinePayment is an explicit boolean true | focused gateway/reference-host regressions + MaggieDash `npm test` + ORA contract/build + task board | passed |
|
|
127
|
+
|
|
128
|
+
| BK-110 | Verify current Booking install parity in a disposable Astro host | both | BK-109 | Exercise the current manifest through canonical CLI install; compare every projected file and run installed inspect/bootstrap validators without DB or dependency writes | disposable Astro install + exact parity + inspect + installed validators + source host-bootstrap + board | passed |
|
|
129
|
+
|
|
130
|
+
| BK-111 | Bind Stripe gateway capabilities to verified account state | both | BK-107, BK-109, BK-110 | Runtime Stripe gateway must use account-verification state, not credential presence or hardcoded true values | readiness matrix + adapter regressions + MaggieDash tests + ORA contract/build + 207-file install parity | passed |
|
|
131
|
+
|
|
121
132
|
For each leaf task: select it with `maggie booking tasks`, write the plan and
|
|
122
133
|
acceptance checks, implement the smallest complete slice, run its gate, update
|
|
123
134
|
the relevant docs, then append a dated entry to [`PROGRESS.md`](./PROGRESS.md).
|
|
@@ -135,3 +146,33 @@ invent a production provider integration, notification transport, or live
|
|
|
135
146
|
database migration runner. Those remain explicit Phase 2–6 host work in
|
|
136
147
|
[`CURRENT-STATE.md`](./CURRENT-STATE.md) and are represented by contracts and
|
|
137
148
|
readiness states where the host must own the runtime behavior.
|
|
149
|
+
| BK-112 | Require verified online-payment capability for public exposure | both | BK-104, BK-107, BK-111 | Keep the natural public entry closed unless Stripe is connected in live mode with an explicit onlinePayment capability and verified secret fingerprint; preserve parity with generic Astro | ORA exposure/contract/readiness validators + Astro build + generic host-bootstrap parity + task-board validation | passed |
|
|
150
|
+
| BK-113 | Restrict public force-open override to non-production hosts | both | BK-104, BK-112 | Deny force-open by default; generic Astro and ORA may opt in only outside production, while production force-off remains available and force-on falls back to natural readiness | shared and ORA gate regressions + host-bootstrap parity + ORA contract/build + staging-backed production preview + fresh install parity + task-board validation | passed |
|
|
151
|
+
| BK-114 | Show verified Stripe account reference in Booking setup | both | BK-100, BK-102, BK-111 | Return the tenant-scoped persisted Stripe account ID and show it in the manager checklist to support intended-account confirmation, with no secret/provider payload exposure | PostgreSQL/reference-host/UI validators + MaggieDash npm test + ORA validators/build + fresh install checks + task-board validation | passed |
|
|
152
|
+
| BK-115 | Complete customer payment-return handoff and guest details | both | BK-107, BK-114 | Use the long-lived manage token after verified payment, expose safe guest/pricing details to the customer DTO, and preserve only the suitability-cleared marker in ORA holds | MaggieDash/ORA customer-flow and UI validators + staging PostgreSQL integration + build + install parity + board validation | passed |
|
|
153
|
+
| BK-116 | Fail fast before staging checkout writes when Stripe test charges are disabled | ORA host harness | BK-114, BK-115 | Run a read-only Stripe test-account capability preflight before staging writes; reject disabled charges and live keys without exposing credentials | ORA preflight unit tests + checkout suite fail-fast check + task-board validation | passed |
|
|
154
|
+
| BK-117 | Validate browser screenshot image contents and viewport dimensions | both | BK-031 | Require PNG/JPEG bytes to match the extension and named viewport width, allow full-page height, and reject malformed or oversized artifacts across the canonical gate and ORA mirrors | Python browser-evidence unit tests + MaggieDash npm test + canonical/ORA JS valid and invalid fixture parity + mirror parity + task-board validation | passed |
|
|
155
|
+
| BK-118 | Keep packaged Booking status references link-safe | ai-cmo-skills | BK-091 | Replace a workspace-only relative link in canonical Booking status docs and rebuild the standalone CLI reference bundle | bundled-reference markdown-link test + full AI-CMO Python suite + task-board validation | passed |
|
|
156
|
+
| BK-119 | Verify customer date changes refresh availability and clear stale slots | ORA host harness | BK-115 | Change the date after selecting a public customer slot; prove the new-date availability request and response render, the old selection clears, and the browser submits no hold/checkout | ORA local-staging Playwright UI journey + contract/build + task-board validation + `git diff --check` | passed |
|
|
157
|
+
| BK-120 | Cover every current manager screen in browser evidence | both | BK-117 | Align the evidence contract/capture/validator and ORA mirrors with all 17 current screens, including Packages and Email templates, across three viewports (51 screens) | canonical/ORA accept and missing-route regressions + MaggieDash `npm test` + ORA contract/build + mirror parity + packaged-contract test + task-board validation | passed |
|
|
158
|
+
| BK-121 | Reject browser evidence captured from the wrong manager screen | both | BK-120 | Version the evidence contract to v2 and require each screen’s final pathname and primary heading to match its manager route | canonical/ORA path-heading regressions + MaggieDash `npm test` + AI-CMO browser-evidence tests + ORA contract/build + mirror parity + task-board validation | passed |
|
|
159
|
+
| BK-122 | Test browser capture readiness without requiring a live host | both | BK-121 | Extract and package the pure pathname/readiness helper; cover successful and rejected capture states deterministically | helper condition regressions + MaggieDash `npm test`/manifest + AI-CMO Booking tests + ORA contract/build + mirror parity + task-board validation | passed |
|
|
160
|
+
| BK-123 | Keep Booking inventory and release status docs aligned with contracts | ai-cmo-skills | BK-122 | Align public inventory/current-state docs with v2 routes and latest Stripe/staging evidence; test task counts against the board | docs inventory/status regression + AI-CMO Booking tests + task-board validation + ORA doc checks | passed |
|
|
161
|
+
| BK-124 | Honor scheduled location closures in customer availability | both | BK-052, BK-123 | Load location closure intervals into the shared planner and reject overlapping public slots and holds while preserving exact boundaries | pure planner + PostgreSQL customer-adapter closure regressions + ORA contract/build + task-board validation | passed |
|
|
162
|
+
| BK-125 | Apply dated staff shifts to customer availability | both | BK-052, BK-124 | Load date-scoped shifts and constrain assigned staff to shifts plus recurring venue/staff hours, preserving fallback on dates without shifts | pure planner + PostgreSQL customer-adapter shift regressions + ORA contract/build + task-board validation | passed |
|
|
163
|
+
| BK-126 | Enforce configured availability on manager-created bookings | both | BK-042, BK-052, BK-125 | Apply the shared venue/staff/resource planner to direct manager creation and waitlist conversion; keep active manager-only services bookable; reject schedule-ineligible explicit assignments before booking/queue writes | Canonical and ORA repository regressions + fresh local-source install projection + customer/availability validators + ORA contract/build + docs/board validation | passed |
|
|
164
|
+
| BK-127 | Enforce configured availability on booking reschedules | both | BK-052, BK-125, BK-126 | Apply the shared planner to proposed manager/customer reschedules while excluding the current booking's old allocations | Canonical and ORA repository regressions + fresh local-source install projection + customer/availability validators + ORA contract/build + docs/board validation | passed |
|
|
165
|
+
| BK-128 | Synchronize expired Stripe Checkout reconciliation across hosts | both | BK-025, BK-030 | Normalize `checkout.session.expired` as a cancelled attempt, cancel its pending booking and release its reserved allocation; sync contract/CLI/host mirrors | Runtime regression + PostgreSQL 16 disposable worker integration + MaggieDash npm test + ORA validators/contract + AI-CMO contract/task validation | passed |
|
|
166
|
+
| BK-129 | Route package purchase reads through the payment repository seam | both | BK-096, BK-097 | Keep the payment-owned manager read on the composed payment repository, outside the core-only transaction callback | service regression + MaggieDash npm test + board validation + `git diff --check` | passed |
|
|
167
|
+
| BK-130 | Persist provider references returned by payment reconciliation | both | BK-025, BK-030 | Save a refreshed provider payment reference during payment-attempt or package-purchase reconciliation, preserving the prior reference when omitted | PostgreSQL payment-adapter regression + MaggieDash npm test + board validation + `git diff --check` | passed |
|
|
168
|
+
| BK-131 | Carry hosted Checkout intent through public booking payments | both | BK-107, BK-130 | Preserve hosted intent from customer checkout through payment adapter and include it in request identity so Stripe creates a Checkout Session | customer/payment adapter regressions + Stripe adapter validator + MaggieDash npm test + board validation + `git diff --check` | passed |
|
|
169
|
+
| BK-132 | Reconcile Stripe Checkout Sessions through the generic adapter | both | BK-128, BK-130, BK-131 | Create bounded-lifetime Checkout Sessions and retrieve `cs_` references through Stripe Checkout, mapping open/paid/expired states and provider references | Stripe adapter regressions + MaggieDash npm test + board validation + Booking Python tests + `git diff --check` | passed |
|
|
170
|
+
| BK-133 | Preserve PaymentIntent references from asynchronous Checkout webhooks | both | BK-130, BK-132 | Normalize `checkout.session.async_payment_succeeded/failed` with the PaymentIntent reference when available, retaining the Session ID only as fallback | canonical/ORA runtime projection regression + disposable PostgreSQL 16 worker persistence integration + MaggieDash npm test + ORA contract check + board validation + Booking Python tests + `git diff --check` | passed |
|
|
171
|
+
| BK-134 | Fulfill captured package purchases after sales are disabled | both | BK-096, BK-097 | Do not gate paid package webhook fulfillment on current sale availability; preserve active checks when starting new purchases | canonical Astro bootstrap + ORA contract regression + builds + board validation + Booking Python tests + `git diff --check` | passed |
|
|
172
|
+
| BK-135 | Retry incomplete package fulfillment on duplicate webhooks | both | BK-134 | Re-run idempotent package settlement when a verified provider event is redelivered; only mark package events processed after fulfillment, and propagate failure so the provider retries | canonical/ORA duplicate retry runtime regression + host contract checks + MaggieDash `npm test` + ORA runtime/contract + board/Python validation + `git diff --check` | passed |
|
|
173
|
+
| BK-136 | Require a validated manage token for closed-gate reschedule availability | both | BK-033, BK-113 | Remove raw query-token gate exemptions; permit closed-gate availability only after host validation of a bearer manage token for a reschedulable booking; keep the token out of the URL | canonical/ORA gate, customer-adapter and UI regressions + MaggieDash `npm test` + ORA `contract:check`, Astro check/build + task-board validation + `git diff --check` | passed |
|
|
174
|
+
| BK-137 | Require validated tokens to render the closed-gate customer page | both | BK-104, BK-136 | Remove the raw query-token page exception; when the public gate is closed, render customer continuations only after validating one unexpired, unrevoked booking payment/manage token or package purchase token | canonical/ORA customer-adapter and route checks + MaggieDash `npm test` and host bootstrap + ORA `contract:check`, Astro check/build + task-board validation + `git diff --check` | passed |
|
|
175
|
+
| BK-138 | Require manage-purpose tokens for customer cancellation and rescheduling | both | BK-060, BK-137 | Require an unexpired, unrevoked manage token scoped to the requested booking before cancel/reschedule mutations and before returning an idempotent replay | canonical/ORA customer-adapter regressions for payment, expired, revoked, wrong-booking and revoked replay denial + MaggieDash `npm test` + ORA `contract:check`, Astro check/build + task-board validation + `git diff --check` | passed |
|
|
176
|
+
| BK-139 | Align the reference customer host with payment/manage token boundaries | MaggieDash | BK-035, BK-138 | Issue separate short-lived payment and 30-day manage tokens; expose manage access only after a valid payment return; validate manage purpose, expiry, revocation, and booking scope before mutation replay | reference-host journey covers token purpose/lifetimes, payment-token and wrong-booking denial, revoked replay denial + MaggieDash `npm test` + task-board validation + `git diff --check` | passed |
|
|
177
|
+
| BK-140 | Fail closed on expired package return tokens in reference hosts | both | BK-035, BK-137 | Reject missing, expired, or malformed-expiry package return tokens before purchase reads/reconciliation, and synchronize canonical/ORA manifest-projected fixture host and validator | canonical and ORA customer-reference-host revoked/expiry regressions + byte parity + MaggieDash `npm test` + ORA `contract:check` + AI-CMO Booking tests + task-board validation + `git diff --check` | passed |
|
|
178
|
+
| BK-141 | Use venue-local time throughout manager booking workflows | both | BK-021, BK-028 | Render appointment instants and interpret manager create, waitlist conversion, reschedule, and dated shift/time-off/closure datetime-local fields in each selected location timezone; reject DST gaps, expose fold choices, disable nonexistent calendar slots, and order dated schedule intervals by UTC instant | Venue-time conversion and schedule UI regressions + MaggieDash `npm test` + ORA Booking UI/contract/build + Booking Python tests + board validation + source parity + `git diff --check` | passed |
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Gift voucher lifecycle
|
|
2
|
+
|
|
3
|
+
**Status:** contract only — MaggieDash ships no voucher runtime in this release.
|
|
4
|
+
**Contract:** `contracts/maggiedash/booking-voucher-lifecycle-v1.json`
|
|
5
|
+
**Validator:** `maggie booking voucher-contract [--ledger FIXTURE]`
|
|
6
|
+
|
|
7
|
+
Stripe has no native gift-card resource (see
|
|
8
|
+
[Stripe integration](./STRIPE-INTEGRATION.md#gift-cards-credits-and-referrals)).
|
|
9
|
+
A host that sells vouchers therefore owns a local, append-only ledger, and a
|
|
10
|
+
Stripe payment only *funds* an online voucher. This contract fixes the
|
|
11
|
+
provider-neutral lifecycle so every host implements the same rules instead of
|
|
12
|
+
designing them from scratch.
|
|
13
|
+
|
|
14
|
+
## Lifecycle
|
|
15
|
+
|
|
16
|
+
| Concern | Rule |
|
|
17
|
+
|---|---|
|
|
18
|
+
| Sale online | Checkout/PaymentIntent funds the voucher; it stays `pending_payment` until the verified payment webhook, then the `issue` entry records `paymentRef`. |
|
|
19
|
+
| Sale in shop (till) | Staff with `vouchers.sell` record the in-shop payment method (`cash`, `card-terminal`, `external`); the voucher is active immediately. |
|
|
20
|
+
| Code format | Online: `PREFIX-XXXX-XXXX-XXXX` from an unambiguous alphabet, last segment a truncated HMAC under a server-only secret, checked in constant time before any lookup. Till: prefix + digits with a Luhn check digit. Store only `codeHash` and `codeLast4`; the full code appears only in the delivery email. |
|
|
21
|
+
| Partial redemption | Any positive amount up to the remaining balance; the remainder stays redeemable. |
|
|
22
|
+
| Undo | `undo_redeem` reverses one earlier `redeem` by id, same amount, at most once, never after void. |
|
|
23
|
+
| Void | Requires a reason; blocks every later redemption, undo, and refund. |
|
|
24
|
+
| Expiry | No redemption at or after `expiresAt`; an `expire` entry records the unused balance. The expiry policy is declared by the host for its jurisdiction. |
|
|
25
|
+
| Refund | Capped by the remaining balance and by the funded amount minus earlier refunds. Online refunds reference the original provider payment (a Stripe Refund); till refunds record `refundMethod`. A full refund before any redemption moves the voucher to `refunded`. |
|
|
26
|
+
| Emails | `voucher.purchase.confirmed` (buyer), `voucher.delivered` (recipient), `voucher.redeemed`, `voucher.refunded`, `voucher.expiry_reminder`, delivered through the host outbox. |
|
|
27
|
+
| Merchant ledger | Append-only `issue`, `redeem`, `undo_redeem`, `void`, `expire`, `refund` entries with actor, timestamp, and idempotency key; every mutation is audited and tenant-scoped. |
|
|
28
|
+
|
|
29
|
+
States: `pending_payment`, `active`, `exhausted`, `expired`, `voided`,
|
|
30
|
+
`refunded`. Money is integer minor units, one currency per voucher.
|
|
31
|
+
|
|
32
|
+
## Proving a host implementation
|
|
33
|
+
|
|
34
|
+
Export a sanitized `maggiedash-booking-voucher-ledger.v1` fixture (no full
|
|
35
|
+
codes, secrets, or customer PII) and replay it:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
maggie booking voucher-contract
|
|
39
|
+
maggie booking voucher-contract --ledger path/to/voucher-ledger.json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The replay rejects a negative balance, over-redemption, redemption after void
|
|
43
|
+
or expiry or before payment, a second undo of the same redemption, refunds
|
|
44
|
+
above the balance or funded amount, online refunds without a payment
|
|
45
|
+
reference, and declared `status`/`balance` values that disagree with the
|
|
46
|
+
ledger. `fixtures/maggiedash/booking-voucher-ledger.v1.json` in the source
|
|
47
|
+
repository is a passing example.
|
|
@@ -150,6 +150,39 @@ image-processing contract: optimisation may use Cloudflare Images
|
|
|
150
150
|
transformations, Astro build tooling or a provider-specific implementation
|
|
151
151
|
behind the same interface.
|
|
152
152
|
|
|
153
|
+
## OAuth connections
|
|
154
|
+
|
|
155
|
+
A provider connection is only as reliable as its weakest connect path:
|
|
156
|
+
|
|
157
|
+
- Each adapter declares one canonical OAuth scope set. Every client that
|
|
158
|
+
starts the flow (dashboard, mobile app, CLI) requests exactly that set.
|
|
159
|
+
LinkedIn invalidates a member's earlier tokens when a later sign-in asks for
|
|
160
|
+
a different scope set, so a mobile app that omits `email` silently revokes
|
|
161
|
+
the dashboard's token while the database still says `active`.
|
|
162
|
+
- Prefer one OAuth client per product. When a client ID is shared with other
|
|
163
|
+
products or callbacks, record it as `client_shared_with`; their sign-ins can
|
|
164
|
+
revoke this product's tokens unless they use the identical scope set.
|
|
165
|
+
- Treat stored connection status as a cache. A token that the provider has
|
|
166
|
+
revoked, or that the serving host cannot decrypt, is `needs_reconnect`
|
|
167
|
+
before anything is scheduled on it — not when a post fails.
|
|
168
|
+
- Provider media URLs (for example `media.licdn.com` with an `e=` expiry) are
|
|
169
|
+
signed and expire. Cache the bytes in owned storage or refresh on readback.
|
|
170
|
+
|
|
171
|
+
`maggie tool maggie_social_share.py adapters` and `connections` check these
|
|
172
|
+
rules from a redacted JSON manifest; see the Social Share skill for shapes.
|
|
173
|
+
|
|
174
|
+
## Structured model output
|
|
175
|
+
|
|
176
|
+
Keep structured-output schemas small. Gemini rejected a JSON schema whose enum
|
|
177
|
+
had 125 values with `400 INVALID_ARGUMENT`, and the caller silently fell back
|
|
178
|
+
for every request. For a large vocabulary (styles, categories, catalogue IDs):
|
|
179
|
+
|
|
180
|
+
1. ask for a free string (optionally with a short list of examples in the
|
|
181
|
+
prompt) instead of a large `enum`;
|
|
182
|
+
2. validate the returned value server-side against the authoritative list;
|
|
183
|
+
3. treat a schema rejection or an unknown value as a visible, counted failure —
|
|
184
|
+
never a silent fallback to a default.
|
|
185
|
+
|
|
153
186
|
## Adding a provider
|
|
154
187
|
|
|
155
188
|
1. Implement the relevant interface in `src/lib/providers/`.
|
|
@@ -373,6 +373,14 @@ node scripts/maggie-booking-schema.mjs --apply --confirm
|
|
|
373
373
|
node scripts/maggie-booking-worker.mjs --write --confirm
|
|
374
374
|
```
|
|
375
375
|
|
|
376
|
+
Before switching Stripe to live mode, follow the read-only live setup runbook
|
|
377
|
+
in `docs/maggiedash-booking/STRIPE-INTEGRATION.md`: verify with list/retrieve
|
|
378
|
+
calls only, never use a create call as a probe, have the owner install
|
|
379
|
+
webhook and event-destination signing secrets with a no-echo command, and hand
|
|
380
|
+
Dashboard-only steps to the owner. Gift vouchers follow the host-owned
|
|
381
|
+
`booking-voucher-lifecycle-v1.json` contract; validate a host ledger with
|
|
382
|
+
`maggie booking voucher-contract --ledger FIXTURE`.
|
|
383
|
+
|
|
376
384
|
The dry-run executes the complete additive migration in a transaction and
|
|
377
385
|
rolls it back, which verifies PostgreSQL permissions without changing data.
|
|
378
386
|
The apply command commits the migration as one transaction.
|