* feat(filters): dynamic filter framework — typed schema, URL state, FilterBar
Port of dflow's filter.utils pattern, adapted to Containr:
- lib/dynamic-filter.ts: FilterConfig schema (search/select/multiselect/
boolean/date-range/status), FilterEngine with client-side apply,
derived options with counts, active-filter tracking, removal.
- lib/use-dynamic-filter.ts: filter state lives in ?f.<key> search
params — filtered views are shareable links. useFilterState exposes
URL state before data loads (server-backed filters); useDynamicFilter
adds the engine over fetched data.
- shared/components/FilterBar.tsx: renders a schema as compact controls
+ active-filter chips, matching design tokens.
- Applied: audit logs (server-backed — state in URL, params to API),
builds (server-backed + client date-range), activity (severity to the
server query, category/search on the fetched page).
- 8 unit tests for the engine.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(filters): erasableSyntaxOnly compat + BuildStatus cast
- Constructor parameter properties are banned under erasableSyntaxOnly —
declare fields explicitly.
- listBuilds status param needs the BuildStatus type, not raw string.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---------
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Central demo-mode helper (lib/demo-mode.ts): ?demo=1 query flag plus
VITE_PUBLIC_DEMO build flag that makes every route demo for the
public Vercel showcase.
- Single demo fixture source (lib/demo-data.ts): projects, services,
builds, databases, cron, HA, security, host monitoring, templates.
Fixes cross-page ID drift that broke project navigation.
- Demo support on Projects, HA, Security, Usage, Templates, Landing,
Service detail; DemoRestricted gate on People/Settings/Audit/Admin.
- Demo-aware PlatformShell: nav filtering, env:demo, demo account menu,
?demo=1 preserved through internal links.
- TemplatesPage: selection moved into ?template= URL param for deep
links; template fixtures shared via demo-data.
- requestJson returns {} for unparseable 200 bodies (SPA fallback) so
envelope unwraps degrade instead of dereferencing null.
- Recharts ResponsiveContainer initialDimension kills -1 warnings.
- vercel.json: vite framework + SPA rewrites for direct deep links.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Backend:
- GET /services/:id/metrics with real Docker container stats
- DELETE /git/providers/:id and GET repo branches endpoint
Frontend:
- Service detail shows real telemetry or honest empty states
- Live status distinguishes idle/polling/reconnecting
- Git providers section in Settings; repo+branch pickers in Add Service
- Real logo, compact Projects header, canvas fitView fix
- index.css deduplicated (1725 -> 1384 lines)
- Fixed smoke tests, lint errors, ToastProvider/context unification
Repo hygiene:
- Added LICENSE (MIT), CONTRIBUTING.md, SECURITY.md; rewrote README
- Untracked .env.prod and data/letsencrypt secrets; fixed .gitignore
- Removed legacy root src/internal/cmd and stale configs/docs/artifacts
- Moved guides and design references under docs/
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>