Observa
Multi-tenant incident management with AI-generated dashboards
- Incidents & dashboards
Teams report incidents and move them through statuses and custom fields they define themselves, then ask a question in plain English and get back a dashboard of metric cards, charts, and tables over their own data — savable, re-runnable, and exportable as CSV or PDF.
- Row-level security
Isolated every tenant with row-level security enforced by Postgres, not the query builder: the app connects as a NOBYPASSRLS role, policies cover both document and event tables, and a separate admin role applies schema through a migrate step that aborts if that role could bypass RLS.
- AI dashboards
Kept the model out of the query path: Gemini fills in a declarative dashboard spec instead of writing SQL, a resolver validates every name against the tenant's own schema, and a compiler turns each widget into one parameterized statement run in a read-only, UTC-pinned transaction — so saved dashboards replay with no AI involved.
Guarded model cost with plan caching in HybridCache — the plan is cached, never the numbers — plus per-user and per-company daily allowances and IP-partitioned rate limiting.
- Backend & realtime
Built the API in ASP.NET Core on .NET 10 with clean architecture and CQRS vertical slices — one file per use case carrying its command or query, validator, precondition, and handler — dispatched by Wolverine as mediator, with cookie auth over ASP.NET Core Identity on a Marten-backed user store.
Event-sourced incidents in Marten, document store and event store in one, so the audit trail is the source of truth: commands append to the stream, an inline projection folds it into the document queries read, and changes reach other browsers over per-tenant SignalR groups through Wolverine's outbox.
- Frontend
Shipped the frontend in React 19 and TypeScript on Vite with TanStack Query driven by realtime cache invalidation, Tailwind v4 over Base UI primitives, Recharts widgets, Zod-mirrored API contracts, light/dark theming, and client-side CSV and PDF export captured from the rendered dashboard.
- Deployment
Deployed both apps on Railway with Neon Postgres — the API as a multi-stage Docker image, the SPA behind Caddy proxying /api and /hubs over the private network for a single origin — with schema applied by an idempotent migrate release step, GitHub Actions CI, and 200+ unit tests.
Track every incident. Ask any question.