Post Phase 8 - Fixes 1

Delivered:

Super Administrator — env-var provisioned, no StaffProfile at all (structural exclusion from Team/barber-picker/appointments/staff-totals, not a filter). hasPermission short-circuit + new getActingBusinessContext() helper retrofitted across 16 owner pages so it can actually manage the business.
Media Manager — one upload/library/external-URL modal + field picker, backing every image field app-wide. Local-disk storage + Docker volume, SVG rejected, size-capped.
Welcome backgrounds — desktop/mobile images with CSS breakpoint swap.
Business Branding settings — logo/cover/welcome/favicon/icon/colours all editable post-install; cover image finally rendered (was dead config).
Service descriptions — now surfaced on Home and in the booking flow.
Loyalty card — live preview, ColorPicker/MediaPicker/IconPicker, flip removed for a static premium-styled card, Loyalty added to bottom nav. Fixed a real pre-existing bug where the card's configured colour/image/icon were stored but never actually rendered.
Home Screen Redesign — hero gallery + sticky Services/Portfolio/Reviews/Details tabs, backed by a new unified gallery model/service (no hero/portfolio duplication). Details tab surfaces social links and a map that were never shown before.
Google Reviews — real sync pipeline (24h cron, CRON_SECRET-gated, mirrors the existing notification cron exactly), DB-only customer reads, owner hide/unhide + policy management page.
Architecture cleanup — SettingsPageShell extracted from 6 duplicated page wrappers; fixed a second pre-existing bug where branding image fields could never actually be cleared once set.
Verification: 418 tests passing (236 unit + 182 integration, all against a real MySQL database), full typecheck/lint clean across src, and a real Docker build+run cycle — which caught and fixed a genuine bug (scripts/ wasn't copied into the production image, so Super Admin sync would have crashed on every real deployment).
This commit is contained in:
Stefan Lazic committed 2026-08-04 17:10:30 +01:00
1 parent 77f25c0489
commit 9e39908ea7
79 files changed
+4121 -450

No files matched your search

+22
View File
@@ -15,6 +15,16 @@ AUTH_GOOGLE_SECRET=""
# Base URL of the app (used for callback URLs, email links, etc.)
NEXT_PUBLIC_APP_URL="http://localhost:3000"
# Media Manager (Phase 9) — max upload size in bytes. Defaults to
# 5,000,000 (5MB) if unset. See src/lib/media/media-storage.ts.
MEDIA_MAX_UPLOAD_BYTES="5000000"
# Google Reviews (Phase 9) — from https://console.cloud.google.com/apis/credentials,
# needs the Places API enabled. Leave unset to keep review sync disabled
# (Home shows clearly-labelled demo reviews instead). See
# src/services/reviews/review-sync.service.ts and /owner/settings/reviews.
GOOGLE_PLACES_API_KEY=""
# Email (Phase 7) — see src/services/notifications/providers.
# "console" logs would-be emails to the server console instead of sending
# (safe default — never send real email from an unconfigured environment).
@@ -52,6 +62,18 @@ CRON_SECRET=""
# openssl rand -hex 32
INSTALLATION_TOKEN=""
# Super Administrator (Phase 9) — platform-level account with every Owner
# permission, provisioned from these env vars rather than the installation
# wizard (see scripts/ensure-super-admin.ts, run on every container start).
# Has no StaffProfile by design: never appears in Team, the customer-facing
# barber picker, or staff totals, and can never receive an appointment. All
# four optional — leave SUPER_ADMIN_EMAIL unset to skip provisioning one
# entirely. Re-run to rotate the password (re-hashed every run).
SUPER_ADMIN_EMAIL=""
SUPER_ADMIN_PASSWORD=""
SUPER_ADMIN_FIRST_NAME=""
SUPER_ADMIN_LAST_NAME=""
# Staff Google Calendar sync (Phase 8) — separate OAuth client from
# AUTH_GOOGLE_ID/SECRET above (different scopes; see
# src/services/calendar/google-calendar.provider.ts). Leave unset to keep