Payment Demo Simulator
Triggers real Square sandbox payments — each fires a webhook and appears on the Square Payments page.
Client Demo Runner — Late Fee Automation
Keep this page in the background; present the surfaces below. Each step stages real state on contract CFD-E2E-JANE (Kintone record 170) and fires the same nightly job the midnight cron runs. Full script: docs/flows/late-fee-client-demo.md
scripts/test-late-fee-e2e-record170.ts once (its Phase 0 seeds it), or check the API is up.Default Management Demo Runner
Demoing contract CFD-DEMO-DEFAULT — no Kintone payment history is needed for this module, it only reads/writes the contract's status. Each step back-dates the due date and fires the same nightly job the midnight cron runs. Full flow: docs/flows/default-management-flow.md
Matching Chain Scenario Lab
Each card fires a real Square sandbox payment with specific fields to exercise one path of the 8-level matching chain. After clicking, check the Square Payments page in ~2s to see the result.
Kintone $id=108 (Ilkania Lopez). reference_id = Kintone $id "108" → local DB miss → Kintone API fetch + auto-sync → MATCHED.
Fields sent to Square
No reference_id. note contains "CFD-00108" → regex extracts token → DB lookup by CFD ID.
Fields sent to Square
"rohan.m@godatanova.com" shared by all 10 Kintone records → multi-match → manual queue.
Fields sent to Square
No reference_id, no note, no email, no customer ID → all 8 levels fail → UNMATCHED / ANONYMOUS.
Fields sent to Square
reference_id "99999" not in DB → P1 fails BAD_REFERENCE_ID → falls through chain → UNMATCHED.
Fields sent to Square
note contains BATCH[454,654,232] → worker splits $1,450 across 3 contract IDs → creates PaymentBatch + per-contract Payment rows → BATCH ×3 badge on Payments page.
Fields sent to Square
Step 1: Seed demo contracts first
Creates DEMO-BATCH-454/654/232 in local DB with kintoneRecordId 454/654/232 so the worker can resolve them without hitting Kintone.
Contract Payment Simulator
Pay a real contract amount via Square sandbox — uses reference_id matching (P1).
reference_id on the payment. Square fires a payment.updated webhook → our worker matches by reference_id first (exact lookup, no regex) → logs to DB + writes to Kintone → appears on the Square Payments page.Late Fee Scenario Lab
Seed test contracts, fire the nightly cron on demand, and watch results appear on the Late Fee Automation page. Each scenario exercises a different code path in the state machine.
Has Clause — Pending Review
First overdue offense on a contract with a late fee clause. Cron flags it for operator review — no automatic charge.
Contract seeded with
Appears in table — Waive / Enforce action buttons visible.
Has Clause — Auto-Enforced
Second overdue offense. Cron escalates straight to AUTO_ENFORCED and starts a 15-day grace countdown.
Contract seeded with
Appears in table — Enforce button visible. Grace expires 15 days from now.
No Clause — Reminder Only
Contract has no late fee clause. Cron sends a reminder email but creates no fee record.
Contract seeded with
No row appears in /late-fees. Email sent (no-op with placeholder Resend key).
Special Status — Skipped
Military / hardship flag set. Cron skips this contract entirely — no email, no fee.
Contract seeded with
No row appears in /late-fees.
Grace Period Expired — Invoice
Pre-seeded AUTO_ENFORCED fee whose 15-day grace expired yesterday. Cron tries to send a $50 Square invoice.
Contract seeded with
With placeholder Square creds: squareInvoiceError shown in table. Wire real creds to see ENFORCED.
Gap Fixes Test Lab (LAND-412)
Three end-to-end scenarios for the LAND-412 gap fixes. Each card: seed a contract → trigger the cron → check results. Wait ~3s after triggering before clicking “Check Results”.
10–29 Day Early Warning Email
Contract is 15 days overdue — inside the Pass 1 window. Cron stamps lastReminderEmailSentAt but does NOT create a LateFee record.
Seeded with
Expected
No new row on /late-fees for CFD-LF-S6
Enforcement Level A — 1st Offense Auto-Enforced
With Level A, even a first offense goes straight to AUTO_ENFORCED — skipping the PENDING_REVIEW gate.
Seeded with
Reset to Level C after testing.
Expected
Row on /late-fees shows AUTO_ENFORCED — no Waive button visible
Waive Button Hidden on AUTO_ENFORCED
2nd offense → cron creates AUTO_ENFORCED fee. On /late-fees, the Waive button is absent — only "Apply Fee" is shown.
Seeded with
Expected
On /late-fees the s2 row shows only "Apply Fee" — no Waive button
Live Late Fee E2E Runner
Runs the full Kintone-dynamic late fee + consolidated invoicing flow against a real contract — real Kintone record, real Square sandbox invoices. Unlike the Scenario Labs above, results here reflect actual Kintone and Square API state, not local-only seeds.
Step 1 — Pick a contract
Inspect any Square invoice
Live status + linked Order line-item breakdown for any invoice ID — the same two checks from the manual curl guide (old invoice status, new invoice's Order line items), exposed here instead of the terminal.
Email Test Lab
Exercises all 4 late-fee email types (PRE_DUE_WARNING, EARLY_LATE_WARNING, LATE_FEE_WARNING, CATCH_UP_INVOICE) against a real contract. To see real deliveries instead of just server-log skips, set RESEND_API_KEY, EMAIL_TEST_MODE=true, and EMAIL_TEST_TO=your-inbox@gmail.com in lol-api/.env — every send then redirects to that inbox from Resend's sandbox address instead of the contract's real kintoneEmail. That redirect is hard-disabled outside NODE_ENV=production — it can never fire for a real customer.
Pick a contract