Compare commits

..

3 Commits

Author SHA1 Message Date
a2d515992c fix(logbook): 'All' filter shows every log including system entries
Drop the 'non-system' default filter; 'All' now means all log types.
2026-06-09 13:09:04 +02:00
2a2902d5bc feat(ui): distinguish dev/prod via VITE_DEPLOY_ENV
Both instances run with NODE_ENV=production, so import.meta.env.PROD was
always true and the header always showed 'Production'. deploy.sh now passes
VITE_DEPLOY_ENV=<branch> into the build and Header reads it to label the
system indicator dev vs prod correctly.
2026-06-09 13:09:03 +02:00
ac1cf8fec7 docs(architecture): sync Caddy manager gate in first-start + ownership invariant 2026-06-09 13:09:01 +02:00
4 changed files with 8 additions and 8 deletions

View File

@ -501,8 +501,8 @@ Default admin user (only on a blank database):
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:
Caddy route import (re-deploy safety net, Caddy manager only):
if CADDY_MANAGER === 'true' AND 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)
@ -841,6 +841,7 @@ Express (server.ts) ──► better-sqlite3 (ghostgrid.db, WAL)
- 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`.
- One Caddy per container; `POST /load` replaces the whole config. Only the `CADDY_MANAGER=true` instance may push/seed/edit routes — never let the non-manager push.
- All user-facing strings are in **English**.
---

View File

@ -16,7 +16,7 @@ git fetch --prune origin
git checkout "$BRANCH"
git pull --ff-only origin "$BRANCH"
npm ci
npm run build
VITE_DEPLOY_ENV="$BRANCH" npm run build
sudo systemctl restart "$SVC"
echo "Deployed $BRANCH ($SVC). Status:"
systemctl --no-pager status "$SVC" | head -n 5

View File

@ -63,8 +63,8 @@ export default function Header({
{/* System Indicator */}
<div className="hidden md:flex items-center gap-2 px-3 py-1 bg-slate-800/60 rounded-full border border-slate-700/50 text-xs font-mono text-slate-300">
<span className={`w-2 h-2 rounded-full animate-pulse ${import.meta.env.PROD ? 'bg-emerald-500' : 'bg-amber-400'}`} />
<span>System: {import.meta.env.PROD ? 'Production' : 'Development'}</span>
<span className={`w-2 h-2 rounded-full animate-pulse ${(import.meta.env.VITE_DEPLOY_ENV === 'dev' || import.meta.env.DEV) ? 'bg-amber-400' : 'bg-emerald-500'}`} />
<span>System: {(import.meta.env.VITE_DEPLOY_ENV === 'dev' || import.meta.env.DEV) ? 'Development' : 'Production'}</span>
</div>
{/* Mail Inbox */}

View File

@ -20,7 +20,7 @@ interface LogbookProps {
export default function Logbook({ logs, devices, users, currentUser, onAddLog }: LogbookProps) {
const [searchTerm, setSearchTerm] = useState('');
const [typeFilter, setTypeFilter] = useState<string>('non-system');
const [typeFilter, setTypeFilter] = useState<string>('all');
// Custom Maintenance Log state
const [showAddLog, setShowAddLog] = useState(false);
@ -35,7 +35,6 @@ export default function Logbook({ logs, devices, users, currentUser, onAddLog }:
const matchesSearch = log.message.toLowerCase().includes(searchTerm.toLowerCase());
const matchesType =
typeFilter === 'all' ? true :
typeFilter === 'non-system' ? log.type !== 'system' :
log.type === typeFilter;
return matchesSearch && matchesType;
});
@ -126,7 +125,7 @@ export default function Logbook({ logs, devices, users, currentUser, onAddLog }:
</div>
<div className="flex gap-1 shrink-0 text-xs font-medium flex-wrap">
{[
{ key: 'non-system', label: 'All' },
{ key: 'all', label: 'All' },
{ key: 'booking', label: 'Booking' },
{ key: 'maintenance',label: 'Maintenance' },
{ key: 'status', label: 'Status' },