Adds lib/grammars/caddyfile.json with scopes for directives, named-matchers
(@prefix), placeholders, strings, and comments. Updates /caddy page to use
createHighlighter with the local grammar instead of the nginx fallback.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- relativeTime(date: Date) helper toegevoegd aan lib/utils.ts
- AuditWidget gebruikt nu gedeelde relativeTime in plaats van inline functie
- CaddyWidget toont rode badge als soonest cert-expiry <30 dagen
- app/page.tsx berekent expiringWarning voor CaddyInitial
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Parallel server-side fetches via Promise.allSettled voor Docker, Caddy,
systemd, Git en Audit. Iedere widget toont geaggregeerde status en
refresht elke 30s client-side onafhankelijk van de andere widgets.
- lib/agent-fetch.ts: gedeelde client-side streaming helper
- app/api/audit/latest/route.ts: GET endpoint voor AuditWidget refresh
- app/_components/DockerWidget.tsx: running/total containers
- app/_components/CaddyWidget.tsx: soonest cert expiry in dagen
- app/_components/SystemdWidget.tsx: healthy/total units (of niet geconfigureerd)
- app/_components/GitWidget.tsx: dirty repo count (of niet geconfigureerd)
- app/_components/AuditWidget.tsx: laatste FlowRun status + relatief tijdstip
- app/page.tsx: vervangt SECTIONS-grid, doet parallel fetches, rendert widgets
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rate-limit /api/flows/start to 10 req/min per user (in-memory, matches login pattern)
- Add middleware.ts: validates x-csrf-token header against csrf_token cookie on all
API POST requests; issues the cookie on GET if missing; sets CSP, X-Frame-Options,
X-Content-Type-Options, and Referrer-Policy on all responses
- Add lib/csrf.ts: client-side apiFetch() wrapper that injects the CSRF header
- Update all client components (login, useFlowRun, docker, caddy, git, systemd)
to use apiFetch() for POST requests
- Cookie config in login route already correct (NODE_ENV check, httpOnly, sameSite=strict)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add journalctl_recent command and scrum4me-web to whitelist in commands.yml.example
- Add SYSTEMD_UNITS env var to .env.example
- lib/parse-systemd.ts: parse activeState, subState, uptime, description
- /app/systemd: server page reading SYSTEMD_UNITS, client list with 10s polling and status badges
- /app/systemd/[unit]: server detail page, client component showing systemctl status + last 100 journal lines (polling 10s)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- lib/agent-client.ts: server-side execAgent() that calls the ops-agent
directly via OPS_AGENT_URL/OPS_AGENT_SECRET and streams SSE output
- lib/parse-docker.ts: pure parser for fixed-width docker ps table output
- app/docker/page.tsx: server component that fetches initial container list
and passes it to the client component
- app/docker/_components/docker-table.tsx: client component with 5s
auto-refresh via useEffect, status badge, and Link to /docker/[name]
- app/docker/[name]/page.tsx: placeholder detail page (logs in Story 3)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Models: User, Session, FlowRun, FlowStep met FlowStatus enum
- prisma.config.ts met DATABASE_URL via @prisma/adapter-pg (Prisma 7 API)
- Initiële migratie applied op ops_dashboard database
- Seed-script voor 1 user via SEED_USER_EMAIL/SEED_USER_PASSWORD env-vars
- lib/prisma.ts als gedeelde singleton client voor Next.js
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>