The guest cannot subscribe to the operator's wallet and the existing
booking read needs a wallet invoice key, so a client had no way to wait
for awaiting_payment -> confirmed over HTTP short of polling the invoice
on LNbits core. Add the HTTP twin of the RPC door's chatelet_booking_get:
the 10-char booking id from the quote is the capability, and the response
is public_booking_dict — lifecycle, dates and money only, with the guest's
pubkey/contact and the Lightning/Nostr plumbing stripped.
Closes#18
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Asserts public_room_dict drops wallet + checkin_instructions, public list
shows active-only + stripped, and public get 404s on inactive. 32 pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019VUQCfdqiLSsFS2jcGnaFD
Runs the full m0NN migration chain against a fresh temp SQLite via the
lnbits Database, then round-trips a room + booking through crud (exercising
the m002 checkin_instructions column, big_int amounts, and is_available on
real rows). Closes the gap that let the #13 SQLite-index bug ship: the rest
of the suite monkeypatches crud, so migrations were never executed.
Isolation is import-order-independent: monkeypatch settings.lnbits_data_folder
to tmp_path, build a fresh ext_chatelet Database, swap it into crud for the
test. Verified it fails (sqlite3 OperationalError) if the #13 bad-index syntax
is reintroduced.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019VUQCfdqiLSsFS2jcGnaFD
Assert the wrap is kind 1059, p-tagged to the guest, authored by an
ephemeral key (not the operator), and that plaintext doesn't leak. Round-
trip: decrypt the wrap with the guest key via core nip44_decrypt to recover
the operator-authored seal (kind 13) — proves the ephemeral NIP-44 v2 layer
is real + interoperable, not just structural. Soft-fail case returns None.
24 pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019VUQCfdqiLSsFS2jcGnaFD
16 tests, run under the LNbits pytest env (spirekeeper pattern: monkeypatch
crud/invoice, drive async via asyncio.run — no live DB/wallet):
- test_availability: half-open overlap semantics (back-to-back stays OK),
and is_available blocking on held/confirmed bookings + manual blocks.
- test_booking_flow: canonical amount_sat, awaiting_payment transition,
min-nights guard, and hold-release (declined) on InvoiceError.
- test_atomic_hold: the #4 regression — two concurrent same-date requests
yield exactly one hold + one conflict; non-overlapping both succeed. The
fakes yield mid-check to open the race window, so the test fails without
the per-room lock (verified by neutering it) and passes with it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019VUQCfdqiLSsFS2jcGnaFD