Physical Scoreboard Hardware Rental
At a glance
Physical scoreboard hardware rental turns Petanque Life into a hardware-as-a-service offer — five kit templates, per-board inventory tracking, public availability calendar with a 7-day buffer, Stripe Checkout, full deposit lifecycle with damage capture and a guided www booking flow let federations and tournaments rent rugged scoreboards by the week without ever owning the kit.
How it works
Tournaments need physical scoreboards but most organisers can't justify owning enough kit for one peak weekend a year. Petanque Life closes the gap by renting fleet hardware and managing the entire lifecycle through the platform. Five kit templates — Trial 8, Silver 32, Gold 64, Platinum 128 and Custom — sit in a slug-indexed catalog with base price, deposit per board and shipping (domestic / EU).
Each physical scoreboard is a ScoreboardKitInstance with a unique serial number and a strict lifecycle status (in_stock → booked → shipping → in_use → returning → maintenance → retired). On petanque.life, the /features/scoreboards page sells the product (hero, SVG mockups, tech specs, use-cases, JSON-LD Product schema), /scoreboards lists the kit catalogue with green/amber/red availability indicators (server-side fetched with a 3-second timeout and static fallback), and /scoreboards/book/[slug] runs the booking flow: date picker → availability check (with a 7-day buffer between rentals, maintenance windows excluded) → contact form → insurance toggle → Turnstile → Stripe Checkout. The rental record (ScoreboardRental) carries a full status machine from quoted to closed with a pricing breakdown (rental, shipping, insurance) and Stripe references.
Deposits run through their own lifecycle (ScoreboardRentalDeposit): a SetupIntent saves the customer's payment method when the kit ships, an off-session charge captures the deposit, and on safe return it is refunded in full — or, if a damage report is filed, the damage cost is captured and the remainder refunded. Tamper auto-arm/disarm dispatches downlinks to the scoreboards on status transitions. A reservation timeout job auto-cancels unpaid bookings after 30 minutes and releases the inventory.
All copy ships in EN/FR/ES/SV and the product is surfaced across five audience pages plus the comparison table.
Key capabilities
- Five kit templates (Trial 8 / Silver 32 / Gold 64 / Platinum 128 / Custom) with structured pricing
- Per-board inventory tracking with strict lifecycle status machine
- Public availability calendar with 7-day rental buffer and maintenance exclusions
- Stripe Checkout for rental payments, Stripe Invoice for NET-30 customers
- Deposit lifecycle with SetupIntent, off-session charge, refund and damage capture
- Reservation timeout job that releases unpaid bookings after 30 minutes
- Full www funnel and EN/FR/ES/SV i18n across catalog, booking and audience pages
In practice
A tournament director planning a 96-team event in three weeks lands on /features/scoreboards from a Google search. The hero, mockups and tech specs convince him; he clicks through to /scoreboards, sees Gold 64 is green-available for his dates, books two Gold kits via /scoreboards/book/gold-64. He picks dates, fills the contact form, toggles insurance on, passes Turnstile and pays via Stripe Checkout.
A confirmation email arrives instantly. The kits ship a week before the event, the deposit is captured off-session when status flips to in_use, and the boards arrive ready to broadcast scores. Post-event he ships them back, the deposit is refunded inside 48 hours of safe arrival.
Features in this subsystem
30| ID | Status | Features |
|---|---|---|
| F19.14.01 | Shipped | ScoreboardKit template model (Trial 8 / Silver 32 / Gold 64 / Platinum 128 / Custom) with pricing (base_price, deposit_per_board, shipping domestic/EU), slug-indexed catalog ✅ PL-T069 |
| F19.14.02 | Shipped | ScoreboardKitInstance inventory model with lifecycle status (in_stock/booked/shipping/in_use/returning/maintenance/retired), serial_no unique, gateway + scoreboard refs, warehouse tracking ✅ PL-T069 |
| F19.14.03 | Shipped | Public kit catalog endpoints (GET /scoreboard-kits, GET /scoreboard-kits/{id}) with active-only filtering ✅ PL-T069 |
| F19.14.04 | Shipped | Admin kit template CRUD (POST/PATCH /scoreboard-kits) with slug uniqueness enforcement ✅ PL-T069 |
| F19.14.05 | Shipped | Admin kit instance inventory (GET/POST /scoreboard-kit-instances) with template/status/warehouse filters ✅ PL-T069 |
| F19.14.06 | Shipped | Availability calendar endpoint (GET /scoreboard-kits/{id}/availability?from=&to=) with 7-day rental buffer, maintenance exclusion, next_available_date ✅ PL-T069 |
| F19.14.07 | Shipped | Seed script for 4 default kit templates (Trial/Silver/Gold/Platinum) with illustrative pricing, idempotent ✅ PL-T069 |
| F19.14.08 | Shipped | ScoreboardRental model with full lifecycle status machine (quoted→payment_pending→paid→shipping→in_use→returning→returned→closed/cancelled/damage_pending), pricing breakdown (rental/shipping/insurance/total), Stripe refs ✅ PL-T070 |
| F19.14.09 | Shipped | Rental booking endpoint (POST /scoreboard-rentals) with atomic kit instance reservation via MongoDB findOneAndUpdate, pricing calculation (base + extension days × boards × 25 SEK + shipping + 10% insurance) ✅ PL-T070 |
| F19.14.10 | Shipped | Stripe Checkout integration for rental payments (mode: payment, line items: rental/shipping/insurance, automatic_tax, success/cancel URLs) + Stripe Invoice for NET-30 customers ✅ PL-T070 |
| F19.14.11 | Shipped | Rental list/detail endpoints (GET /scoreboard-rentals, GET /{id}) with tenant_id and status filters, cursor pagination ✅ PL-T070 |
| F19.14.12 | Shipped | Rental cancellation (POST /{id}/cancel) with status-dependent logic: immediate cancel for quoted/booked/payment_pending, Stripe refund for paid ✅ PL-T070 |
| F19.14.13 | Shipped | Checkout URL regeneration (GET /{id}/checkout-url) for expired Stripe sessions ✅ PL-T070 |
| F19.14.14 | Shipped | Reservation timeout job: auto-cancel payment_pending rentals after 30 min, release kit instances back to in_stock ✅ PL-T070 |
| F19.14.15 | Shipped | Tamper auto-arm/disarm: dispatch tamper_arm downlink on rental.status→in_use, tamper_disarm on →returning ✅ PL-T070 |
| F19.14.16 | Shipped | ScoreboardRentalDeposit model with lifecycle status machine (pending_setup→setup_complete→charged→refunded/partial_refunded/captured_for_damage), Stripe refs (SetupIntent, PaymentMethod, Customer, PaymentIntent), damage_report_id linkage ✅ PL-T071 |
| F19.14.17 | Shipped | Deposit setup endpoint (POST /scoreboard-rentals/{id}/setup-deposit) with Stripe SetupIntent creation, Customer creation, idempotent re-retrieval ✅ PL-T071 |
| F19.14.18 | Shipped | Off-session deposit charge (POST /{id}/charge-deposit) using saved PaymentMethod, admin-larm on card expiry/decline ✅ PL-T071 |
| F19.14.19 | Shipped | Full deposit refund (POST /{id}/refund-deposit) via Stripe Refund API on safe kit return ✅ PL-T071 |
| F19.14.20 | Shipped | Damage capture with partial refund (POST /{id}/capture-deposit-for-damage) — damage_cost deducted, remainder refunded, damage_report_id linkage for PL-T073 ✅ PL-T071 |
| F19.14.21 | Shipped | Deposit status endpoint (GET /{id}/deposit) for rental deposit lookup ✅ PL-T071 |
| F19.14.22 | Shipped | Stripe webhook handlers: setup_intent.succeeded → setup_complete, payment_intent.succeeded (deposit type) → charged, charge.refunded → refunded/partial_refunded ✅ PL-T071 |
| F19.14.23 | Shipped | www feature page /features/scoreboards: hero, SVG mockups, tech specs table, use-cases, referee call, live scoring, kit price cards with API fallback, JSON-LD Product schema ✅ PL-T073 |
| F19.14.24 | Shipped | www kit catalog /scoreboards: server-side fetch with 3 s timeout + static fallback, availability indicators (green/amber/red), 4-col card grid ✅ PL-T073 |
| F19.14.25 | Shipped | www booking flow /scoreboards/book/[slug]: date picker → availability check → contact form → insurance toggle → Turnstile → Stripe Checkout redirect ✅ PL-T073 |
| F19.14.26 | Shipped | www booking status /scoreboards/booking/[id]: server-side fetch with Stripe session token, status badge, deposit lifecycle display ✅ PL-T073 |
| F19.14.27 | Shipped | Scoreboard section added to 5 audience pages (event-organisers, tournament-directors, umpires, federations, venues) via audience-pages.ts section6 ✅ PL-T073 |
| F19.14.28 | Shipped | Comparison table: new "Physical Scoreboards" category with 5 features (live_score, referee_call, kit_rental, custody, ota) ✅ PL-T073 |
| F19.14.29 | Shipped | i18n: all scoreboard copy keys in en, sv, es, fr (4 languages × ~100 keys) ✅ PL-T073 |
| F19.14.30 | Shipped | Navigation: "Scoreboards" link in header nav + footer product column ✅ PL-T073 |