v0.8: auth integration, design persistence (#23), protected sweep (#24)

Server (spans the v0.6→v0.8 arc in one file):
- template-manager mounted with the productsStore catalog, PNG-only
  mockup multer, facet personalization config (§R10, FACET_KEY-gated,
  inert when unset), and the marketing-preview drainer (2s tick, one
  render per tick, .unref()).
- auth-manager bootstrap: DATABASE_URL gates the pg Pool, migrations,
  and mountAuth (magic-link customer + Google SSO admin + facet);
  absent DATABASE_URL logs a warning and the host boots without auth.
- goods-editor design persistence (#23): idempotent 001_designs.sql
  applied at boot, db handle passed to mountEditorApi so /api/designs
  routes mount; without Postgres the client falls back to
  cart-without-design_id.
- reference-protected TTL sweep (#24): before each pass, every
  /uploads/ basename referenced by template-manager JSON or persisted
  designs is collected and protected, and exports/designs (db-driven
  lifecycle, unrecoverable sources) is skipped entirely. Sweep kickoff
  moves below the bootstrap (pgPool TDZ). sweep-worker.mjs is the
  standalone process variant for production.

Client: main.jsx wraps the tree in AuthProvider (single /api/auth/me
fetch shared by useCustomer/useAdmin, degrades on 404) and mounts
AppRouter. eslint bumps server.js to ecmaVersion 2022 (top-level
await); .env.example documents the full v0.8 env surface.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
khalid@traclabs.com
2026-09-01 23:29:16 -05:00
parent dfa1f90a16
commit 840a5dbcb3
5 changed files with 614 additions and 27 deletions

View File

@@ -1,16 +1,24 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { AuthProvider } from '@khalidadil/auth-manager'
import '@khalidadil/auth-manager/styles.css'
import './index.css'
import App from './App'
import App from './AppRouter'
// Service worker registration is handled inside <PWAInstall /> via the
// `useRegisterSW` hook from `virtual:pwa-register/react`. We removed the
// hand-rolled `navigator.serviceWorker.ready` listener that used to live here
// because (a) it didn't actually register the SW — it just listened for updates
// — and (b) it duplicated state the plugin already exposes via the hook.
// v0.8 — <AuthProvider> wraps the whole tree so useCustomer/useAdmin hooks
// share a single /api/auth/me fetch instead of each call site re-fetching.
// AuthProvider degrades gracefully if /api/auth/me returns 404 (host
// running without DATABASE_URL set), so this wrap is safe even when
// auth-manager is disabled server-side.
//
// SW registration lives inside <PWAInstall /> via the `useRegisterSW`
// hook — we removed the hand-rolled `navigator.serviceWorker.ready`
// listener that used to live here.
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
<AuthProvider apiBase="/api">
<App />
</AuthProvider>
</StrictMode>,
)