Docs.

Admin portal — start here (morning brief)

archive/office-morning-brief-2026-05-30.md

ARCHIVED. The original overnight-build summary (2026-05-30); many claims (read-only inventory, magic-link staff auth) are long superseded. Nothing here is current — see docs/README.md for the live map.

Built overnight 2026-05-29 → 05-30, autonomously, while you slept. This file is the executive summary; the numbered docs hold the detail and the reasoning.

  • 00-architecture.md — the five facts I built around, routing, auth, data model.
  • 01-auth.md — how sign-in works + how to do your first real login.
  • 02-data-model.md — the reservations/finance schema + reservation state machine.
  • 03-roadmap.md — what's built, what's scaffolded, what's deferred + why.

What you have now

An internal admin at /office, same codebase + design system as the site, covering the three areas you asked for:

AreaRouteState
Dashboard/office✅ live stats (rentals today, inventory, exposure, subscribers, health)
Reservations/office/reservations✅ list, month calendar, create, full reservation lifecycle, payments, claims
Inventory (gear)/office/inventory✅ browse items + assets + audit (read-only in Phase 0 — see below)
Customers/office/customers✅ list (auto-created from reservations)
Finances/office/finances✅ deposits held, earned, pipeline, claims, payments ledger
Subscribers/office/subscribers✅ launch list + CSV export
Settings/office/settings✅ editable pricing / deposit / tier / per-class cost-recovery config (+ revision history)
Spaces/office/spaces✅ list, create, edit rentable studio spaces
Blackouts/office/reservations/blackouts✅ create/remove per-unit gear + space blackout windows
Short links/office/links✅ qr.studio.chat code list, create, per-code + scan stats
Data console/office/data✅ archive / restore / purge (soft-delete) reservations, customers, links

Everything is built from the /design tokens (dark, mono .labels, .display headings, CtaButton/FramedLink language) and is gated behind admin auth.

How to get in

Right now there's a dev bypass on in .env.local (ADMIN_DEV_BYPASS=1), so on your machine http://localhost:3026/office opens straight to the dashboard — no login. That's dev-only and ignored in production.

For real (prod) sign-in: grant an office account a role by SQL (brandon@studio.chat, see 01-auth.md "Provisioning"), then sign in with Google at /auth/sign-in. Staff use Google OAuth — it's the only staff path; magic link / passkey are a customer convenience and are declined for any email holding an office role. See 01-auth.md for the one-time setup (enabling the Google provider in Supabase). The first Google sign-in links your auth.users row to the account.

What I verified

  • Auth gate redirects unauthenticated users to /auth/sign-in; office-role check enforced on the callback.
  • Every page renders (200, no errors) at desktop; inventory list/detail, subscribers, settings, finances, reservations all checked in a real browser.
  • Full reservation lifecycle, end to end in the browser: created a reservation (customer auto-created, FX6 line, deposit computed from replacement value → $1,400), transitioned quoted → held, recorded a $1,400 deposit payment, saw it flow into /office/finances. Then I deleted that test data from the production DB so you start clean (0 reservations/customers/payments).
  • tsc --noEmit clean across all admin code.

The one thing to know: inventory is read-only right now

settings.inventory_canonical_source = 'sheet', so the Google Sheet is the source of truth for gear and the DB is a mirror. The admin shows inventory but doesn't edit it, to avoid fighting the sheet sync. Flipping to in-app editing is a deliberate, documented cutover (03-roadmap.md → "Phase-1 inventory cutover"). Reservations/payments/claims are not inventory and are fully editable now.

Decisions I made on your behalf (flag any you'd change)

  1. Supabase Auth + DB office roles (account_roles, no env allowlist) — gives real user identities for the audit trail. Staff sign in with Google OAuth (the only staff path); customers get magic link + an optional passkey. No passwords. (The original build used magic-link/password; that was replaced by Google OAuth — see 01-auth.md.)
  2. Admin at top-level /office, English-only, its own root layout, bypassing the launch gate + i18n. (Not under [locale].)
  3. Reconciled the three conflicting reservation state machines in the docs into one enum (02-data-model.md); used USD cents everywhere (the live convention), not the docs' older *_cop columns.
  4. No payment provider wired yet — payments are recorded manually (cash/transfer/stripe/wompi as a label). Stripe/Wompi integration is a deferred milestone (03-roadmap.md); the payments table already models it.
  5. Forced dark theme for the admin (design-guide-supported via data-theme).
  6. Consolidated the duplicate-SKU inventory rows (migration 0002, §8): the legacy "one items row per physical unit" pattern (e.g. FX6 was 3 rows) is collapsed to one items row + N assets, with a UNIQUE(sku) constraint so it can't recur.

To take it live (when you're ready)

  1. Set prod env on the host: unset ADMIN_DEV_BYPASS, set NEXT_PUBLIC_SITE_URL, enable the Google provider in Supabase, and (for the customer magic-link convenience) ensure email delivery works (01-auth.md).
  2. Grant your office account a role by SQL (01-auth.md "Provisioning"), then first Google sign-in as brandon@studio.chat at /auth/sign-in.
  3. Day rates now auto-derive from replacement value, calibrated to the Colombian market (matched to Cinemarket at 3,600 COP/USD) — see 04-pricing.md. Items with a replacement value are priced; tune the curve in settings or set per-item overrides. The Tier B/C replacement-value thresholds (settings.tier_b_min_replacement_usd_cents, tier_c_min_replacement_usd_cents) are still unset (/office/settings shows them blank) — set those before quoting Tier B/C gear. Confirm the 5 estimated accessory replacement values noted in 04-pricing.md.

All work is committed on develop (see git log); nothing was pushed to a deploy unless you asked. The full operational schema (reservations, finance, customers, etc.) ships in supabase/migrations/0001_baseline.sql; later migrations (00020005) layer on the assets/spaces renames, SKU dedupe, function hardening, soft-delete, and the office RPCs.