feat(ui): light-mode sky palette for Caddy card, favicon, doc sync

- index.css: add :root.light overrides for the sky-* accent used only by the
  Caddy settings card (buttons, badges, hovers) + the missing red-950/30 hover
- favicon: add public/favicon.svg (GhostGrid logo) and link it in index.html
- ARCHITECTURE.md: GET /caddy/routes returns a plain array, document the Caddy
  startup import, https:// upstream, favicon/public dir, and the SPA-catch-all-last
  + Cache-Control: no-store invariant
This commit is contained in:
Brückner
2026-06-08 14:51:36 +02:00
parent f6263ad2f3
commit 1dba721a9a
4 changed files with 80 additions and 7 deletions

View File

@ -374,7 +374,7 @@ All `/api/*` routes return JSON. Every route except the public auth/config endpo
|
+-- /caddy
+-- GET /status # Caddy admin API reachable? [auth]
+-- GET /routes # { system, custom } routes [auth]
+-- GET /routes # Custom routes (plain array) [auth]
+-- POST /routes # Add custom route + push config [auth]
+-- PUT /routes/{id} # Update custom route + push config [auth]
+-- DELETE /routes/{id} # Remove custom route + push config [auth]
@ -481,15 +481,19 @@ pushCaddyConfig(): POST <caddy_admin_url>/load (Content-Type: text/caddyfile)
### 6.4 First-start Initialization
Runs in `startServer()` before any routes are registered, every startup — both operations
are idempotent and only fire once on a blank database.
Runs in `startServer()` on every startup — each step is idempotent.
```
Default admin user:
Default admin user (only on a blank database):
if users table is empty:
INSERT user (name='Admin', role='Admin', email='admin@ghostgrid.local', password=bcrypt('admin'))
INSERT user (name='admin', role='admin', email='admin@ghostgrid.local', password=bcrypt('admin'))
→ log "[Init] Default admin user created"
Caddy route import (re-deploy safety net):
if caddy_enabled === 'true' AND caddy table is empty:
importCaddyfileRoutes() → seed routes from /etc/caddy/Caddyfile
(also runs in PUT /api/settings on the disabled → enabled transition)
Default settings:
INSERT OR IGNORE all DEFAULT_SETTINGS keys from server-db.ts
→ existing values in the settings table are never overwritten
@ -577,7 +581,8 @@ Settings
+-- CheckMK (API URL/user/secret, sync interval, "Run sync now")
+-- Ansible Semaphore (API URL/token/project, "Test connection")
+-- Caddy (admin URL, custom route management;
auto-seeded from /etc/caddy/Caddyfile on first enable)
auto-seeded from /etc/caddy/Caddyfile on first enable;
https:// upstream → TLS proxy, certificate not verified)
+-- Secret inputs use the __SET__ sentinel (blank = keep existing)
```
@ -696,7 +701,9 @@ Backup : ghostgrid.db + ghostgrid.db-wal + ghostgrid.db-shm
GhostGrid/
+-- server.ts # Express app: all routes, auth, integrations, background jobs
+-- server-db.ts # SQLite connection, full schema, settings/Caddy helpers
+-- index.html # Vite HTML entry (#root > src/main.tsx)
+-- index.html # Vite HTML entry (#root > src/main.tsx); links /favicon.svg
+-- public/
| +-- favicon.svg # app favicon (GhostGrid logo; served at site root by Vite)
+-- vite.config.ts # Vite + React + Tailwind; '@' alias > repo root
+-- tsconfig.json # noEmit, react-jsx, bundler resolution
+-- package.json # scripts + deps (package name "react-example" is vestigial)
@ -820,6 +827,7 @@ Express (server.ts) ──► better-sqlite3 (ghostgrid.db, WAL)
- Booking boolean flags are 0/1 integers in SQLite, mapped on read.
- A new settings key must be: **seeded** in `server-db.ts`, **allow-listed** in `PUT /api/settings`, and (if secret) added to `SECRET_KEYS`.
- Schema changes go straight into the `CREATE TABLE` block in `server-db.ts` — fresh-install model, no migration helper.
- The SPA catch-all (`app.get('*')`) + static serving are registered **last** in `startServer()`, after every `/api` route — otherwise GET `/api/*` falls through to `index.html`. All `/api` responses carry `Cache-Control: no-store`.
- All user-facing strings are in **English**.
---