Compare commits
3 Commits
e0332b05ad
...
a2d515992c
| Author | SHA1 | Date | |
|---|---|---|---|
| a2d515992c | |||
| 2a2902d5bc | |||
| ac1cf8fec7 |
@ -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'))
|
INSERT user (name='admin', role='admin', email='admin@ghostgrid.local', password=bcrypt('admin'))
|
||||||
→ log "[Init] Default admin user created"
|
→ log "[Init] Default admin user created"
|
||||||
|
|
||||||
Caddy route import (re-deploy safety net):
|
Caddy route import (re-deploy safety net, Caddy manager only):
|
||||||
if caddy_enabled === 'true' AND caddy table is empty:
|
if CADDY_MANAGER === 'true' AND caddy_enabled === 'true' AND caddy table is empty:
|
||||||
importCaddyfileRoutes() → seed routes from /etc/caddy/Caddyfile
|
importCaddyfileRoutes() → seed routes from /etc/caddy/Caddyfile
|
||||||
(also runs in PUT /api/settings on the disabled → enabled transition)
|
(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`.
|
- 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.
|
- 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`.
|
- 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**.
|
- All user-facing strings are in **English**.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@ -16,7 +16,7 @@ git fetch --prune origin
|
|||||||
git checkout "$BRANCH"
|
git checkout "$BRANCH"
|
||||||
git pull --ff-only origin "$BRANCH"
|
git pull --ff-only origin "$BRANCH"
|
||||||
npm ci
|
npm ci
|
||||||
npm run build
|
VITE_DEPLOY_ENV="$BRANCH" npm run build
|
||||||
sudo systemctl restart "$SVC"
|
sudo systemctl restart "$SVC"
|
||||||
echo "Deployed $BRANCH ($SVC). Status:"
|
echo "Deployed $BRANCH ($SVC). Status:"
|
||||||
systemctl --no-pager status "$SVC" | head -n 5
|
systemctl --no-pager status "$SVC" | head -n 5
|
||||||
|
|||||||
@ -63,8 +63,8 @@ export default function Header({
|
|||||||
|
|
||||||
{/* System Indicator */}
|
{/* 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">
|
<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 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.PROD ? 'Production' : 'Development'}</span>
|
<span>System: {(import.meta.env.VITE_DEPLOY_ENV === 'dev' || import.meta.env.DEV) ? 'Development' : 'Production'}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mail Inbox */}
|
{/* Mail Inbox */}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ interface LogbookProps {
|
|||||||
|
|
||||||
export default function Logbook({ logs, devices, users, currentUser, onAddLog }: LogbookProps) {
|
export default function Logbook({ logs, devices, users, currentUser, onAddLog }: LogbookProps) {
|
||||||
const [searchTerm, setSearchTerm] = useState('');
|
const [searchTerm, setSearchTerm] = useState('');
|
||||||
const [typeFilter, setTypeFilter] = useState<string>('non-system');
|
const [typeFilter, setTypeFilter] = useState<string>('all');
|
||||||
|
|
||||||
// Custom Maintenance Log state
|
// Custom Maintenance Log state
|
||||||
const [showAddLog, setShowAddLog] = useState(false);
|
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 matchesSearch = log.message.toLowerCase().includes(searchTerm.toLowerCase());
|
||||||
const matchesType =
|
const matchesType =
|
||||||
typeFilter === 'all' ? true :
|
typeFilter === 'all' ? true :
|
||||||
typeFilter === 'non-system' ? log.type !== 'system' :
|
|
||||||
log.type === typeFilter;
|
log.type === typeFilter;
|
||||||
return matchesSearch && matchesType;
|
return matchesSearch && matchesType;
|
||||||
});
|
});
|
||||||
@ -126,7 +125,7 @@ export default function Logbook({ logs, devices, users, currentUser, onAddLog }:
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex gap-1 shrink-0 text-xs font-medium flex-wrap">
|
<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: 'booking', label: 'Booking' },
|
||||||
{ key: 'maintenance',label: 'Maintenance' },
|
{ key: 'maintenance',label: 'Maintenance' },
|
||||||
{ key: 'status', label: 'Status' },
|
{ key: 'status', label: 'Status' },
|
||||||
|
|||||||
Reference in New Issue
Block a user