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:
134
.env.example
134
.env.example
@@ -34,6 +34,140 @@ NODE_ENV=development
|
||||
# FILE_TTL_MS=86400000 # 24 hours
|
||||
# CLEANUP_INTERVAL_MS=3600000 # 1 hour
|
||||
|
||||
# ==================================================================
|
||||
# auth-manager (v0.8) -- runtime
|
||||
# ==================================================================
|
||||
#
|
||||
# auth-manager mounts customer magic-link + admin Google SSO + the
|
||||
# account shell. If DATABASE_URL is NOT set, auth-manager is disabled
|
||||
# gracefully and the rest of the host still boots -- useful when
|
||||
# working on goods-editor / template-manager features without
|
||||
# provisioning Postgres locally.
|
||||
|
||||
# Postgres connection string. Required to enable auth-manager.
|
||||
# Examples:
|
||||
# Local Docker: postgres://postgres:postgres@localhost:5432/apparel
|
||||
# Dokploy: postgres://<user>:<pass>@<service>:5432/<db>
|
||||
# DATABASE_URL=postgres://postgres:postgres@localhost:5432/apparel
|
||||
|
||||
# Fully-qualified base used to build:
|
||||
# - the magic-link URL we email to customers (and print to console)
|
||||
# - the Google OAuth redirect URI for admin SSO
|
||||
# Must match the redirect URI registered in Google Cloud Console.
|
||||
# In dev, set to http://localhost:3001. In prod, your storefront URL.
|
||||
# Falls back to http://localhost:${PORT} if unset (dev only -- won't
|
||||
# work behind a reverse proxy).
|
||||
# PUBLIC_BASE_URL=http://localhost:3001
|
||||
|
||||
# Comma-separated allowlist of Google accounts that can sign in via
|
||||
# admin SSO. Two or more entries strongly recommended for break-glass
|
||||
# recovery (locked decision #4 in v08_Auth_v1.md).
|
||||
# ADMIN_EMAILS=you@gmail.com,backup@gmail.com
|
||||
|
||||
# Google OAuth 2.0 Web client credentials. Required for admin SSO.
|
||||
# Create in Google Cloud Console -> APIs & Services -> Credentials ->
|
||||
# Create credentials -> OAuth client ID -> Web application. Authorized
|
||||
# redirect URI must be ${PUBLIC_BASE_URL}/auth/admin/google/callback.
|
||||
# GOOGLE_CLIENT_ID=...apps.googleusercontent.com
|
||||
# GOOGLE_CLIENT_SECRET=...
|
||||
|
||||
# Optional: SMTP relay for magic-link emails. If unset, magic links
|
||||
# ONLY print to the server's stdout (still fully functional for dev
|
||||
# -- just copy/paste the link from your terminal).
|
||||
#
|
||||
# Recommended dev setup: Mailpit (https://mailpit.axllent.org).
|
||||
# docker run -d -p 1025:1025 -p 8025:8025 axllent/mailpit
|
||||
# then visit http://localhost:8025 to read sent mail.
|
||||
#
|
||||
# Resend integration is deferred to v2 -- see v08_Auth_v1.md
|
||||
# "Email delivery in v1" section for rationale.
|
||||
# SMTP_HOST=localhost
|
||||
# SMTP_PORT=1025
|
||||
# SMTP_USER=
|
||||
# SMTP_PASS=
|
||||
# SMTP_FROM=no-reply@localhost
|
||||
|
||||
# Optional: cookie domain for cross-subdomain session sharing
|
||||
# (e.g. '.yourdomain.com' so checkout.yourdomain.com sees the same
|
||||
# session as yourdomain.com). Usually leave unset -- SureCart's WP
|
||||
# sidecar uses its own customer identity (passed via metadata at
|
||||
# checkout creation), not auth-manager's session.
|
||||
# COOKIE_DOMAIN=
|
||||
|
||||
# ==================================================================
|
||||
# Personalization facet (Project doc §R10) -- runtime
|
||||
# ==================================================================
|
||||
#
|
||||
# Generic "customers filter the shop by a facet" feature. For THIS
|
||||
# deployment the facet is "Pet Type" (dog/cat/reptile/…); other shops
|
||||
# configure a different facet, or none. The facet VALUES are managed by
|
||||
# an admin inside template-manager; only the DEFINITION is set here.
|
||||
#
|
||||
# FACET_KEY is the master switch. Leave it UNSET to run a plain,
|
||||
# unfiltered shop: no sign-in prompt, no template filtering, the editor
|
||||
# shows all stickers, and the account/admin facet UIs stay hidden.
|
||||
|
||||
# The facet's stable key. Setting it turns the feature ON. Becomes the
|
||||
# facet_key on customer_facet_values rows + the audienceTags scope.
|
||||
# FACET_KEY=pet_type
|
||||
|
||||
# Display label shown in the UI ("Choose your {LABEL}", account heading,
|
||||
# admin section title).
|
||||
# FACET_LABEL=Pet Type
|
||||
|
||||
# Selection mode: `multi` (default) lets a customer pick several values
|
||||
# (e.g. dog + cat); `single` restricts to one.
|
||||
# FACET_SELECTION_MODE=multi
|
||||
|
||||
# Require an admin to categorize every template before saving it
|
||||
# (>=1 facet value, or marked General/universal). Default false. Turn
|
||||
# this ON whenever the shop filters strictly, so an untagged template
|
||||
# is never hidden silently. THIS shop: true.
|
||||
# REQUIRE_TEMPLATE_CATEGORY=true
|
||||
|
||||
# Require a signed-in customer to choose at least one value before
|
||||
# browsing. Default false. THIS shop: false (the prompt nudges but is
|
||||
# skippable; choosing nothing shows everything).
|
||||
# REQUIRE_FACET_SELECTION=false
|
||||
|
||||
# ==================================================================
|
||||
# Image upscale service (goods-editor, 2026-06-10) -- runtime
|
||||
# ==================================================================
|
||||
#
|
||||
# Optional REST service that upscales low-resolution customer photos
|
||||
# before they hit the print render (goods-editor's /api/export
|
||||
# pipeline). goods-editor reads these variables itself
|
||||
# (imageUpscalerFromEnv inside mountEditorApi) -- no server.js wiring
|
||||
# needed; setting UPSCALE_SERVICE_URL is the master switch. Unset =
|
||||
# feature fully dormant, renders byte-identical to before.
|
||||
#
|
||||
# The editor independently FLAGS low-res images to customers/admins
|
||||
# in the UI regardless of this setting -- the service only improves
|
||||
# what actually prints. Upscaling is best-effort: if the service is
|
||||
# down or slow, the render proceeds with the original pixels.
|
||||
#
|
||||
# Expected contract (adapt goods-editor's src/server/lib/
|
||||
# imageUpscaler.js if your service differs -- it's the single point
|
||||
# of adaptation):
|
||||
# POST $UPSCALE_SERVICE_URL with JSON
|
||||
# { "image": "<base64>", "mime": "image/png", "scale": 2 }
|
||||
# -> 200 with an image/* binary body, OR JSON { "image": "<base64>" }
|
||||
|
||||
# Master switch. e.g. a Real-ESRGAN container in the same Dokploy
|
||||
# project: http://upscaler:5000/upscale
|
||||
# UPSCALE_SERVICE_URL=
|
||||
|
||||
# Optional credential. Sent as 'Authorization: Bearer <key>' unless
|
||||
# UPSCALE_SERVICE_AUTH_HEADER names a custom header (e.g. X-Api-Key),
|
||||
# in which case the bare key is sent in that header.
|
||||
# UPSCALE_SERVICE_API_KEY=
|
||||
# UPSCALE_SERVICE_AUTH_HEADER=Authorization
|
||||
|
||||
# Per-request abort + the service's integer scale ceiling.
|
||||
# UPSCALE_SERVICE_TIMEOUT_MS=30000
|
||||
# UPSCALE_SERVICE_MAX_SCALE=4
|
||||
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
# Build-time — values the `docker compose build` step uses
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user