Skip to content

Repository files navigation

War Room

Prisma migrations Node.js Python Next.js FastAPI

War Room is a hackathon MVP for AI-assisted incident operations. It is an engineering operations copilot that turns fragmented operational signals into an auditable incident workflow with visible evidence, Coral SQL, reasoning, timelines, Slack coordination, tickets, and reports.

It is not a generic chatbot, a passive observability dashboard, or an autonomous remediation system.

1. What Problem Do We Solve

Incident response is slow because the truth is scattered:

  • Deployments and pull requests are in GitHub.
  • Errors and alerts are in Sentry, Datadog, Grafana, and PagerDuty.
  • Coordination is in Slack.
  • Follow-up work is in Jira or Linear.
  • Runbooks, postmortems, and operational notes live elsewhere.

During an outage, engineers lose time switching tools, copying context, asking "what changed?", and trying to prove whether a deployment, alert, Slack escalation, or ticket is actually related. AI can help, but only if it shows its work. A black-box summary is not enough for incident response.

War Room solves this by making investigation evidence first-class. It keeps the SQL, source tables, timeline, confidence, reasoning, and actions visible so responders can move from detection to investigation, coordination, remediation planning, and postmortem generation without losing the audit trail.

2. What I Built

War Room combines incident management, connected source querying, AI reasoning, and workflow actions in one project-scoped web app.

  • Authenticated workspaces: Supabase Auth, organizations, current-project selection, project settings, project services, and dependencies.
  • Incident lifecycle: incident history, incident workbench, status transitions, evidence, timeline events, Coral queries, agent steps, action records, reports, postmortems, and ticket actions.
  • Incident intake: manual/API intake, selected Coral query result intake, user-triggered Coral ingestion, verified provider webhooks, and request-driven Coral polling through trigger policies.
  • Investigation workflow: incident RCA can sample available Coral tables, attach SQL/evidence to an incident, call the FastAPI LLM analysis endpoint when available, and use rule-based synthesis when external AI is unavailable.
  • Slack coordination: project Slack OAuth, channel sync, notification preferences, signed interactive actions, app mention handling, owner assignment, incident status updates, ticket creation, timeline responses, and postmortem actions.
  • Ticketing and artifacts: Jira/Linear incident tickets, incident reports, postmortem drafts, runbook helpers, blast-radius utilities, impact simulation, and remediation suggestions.

3. Use Of Coral

Coral is the investigation substrate in War Room. Provider APIs are still used for setup and write workflows, but cross-source evidence retrieval is modeled as Coral catalog discovery and read-only Coral SQL.

The important design choice is that War Room does not hide Coral behind a generic AI answer. The app stores and renders the generated SQL, touched tables, source systems, rows, evidence, confidence, and reasoning context.

Coral Investigation Flow

Project-scoped Coral source lifecycle

Each project can connect Coral-backed sources from the integration settings UI. The implementation:

  • Reads the source catalog and config fields from packages/shared/src/integrations.ts.
  • Encrypts project credentials before storing them in ProjectIntegration.config.
  • Materializes project-local Coral state under CORAL_PROJECT_CONFIG_ROOT or an OS temp fallback.
  • Runs coral source add, coral source test, and verifies provider tables through coral.tables.
  • Rehydrates connected project sources before query execution if local Coral state is missing.

Core code:

Coral catalog and source visibility

War Room exposes source readiness and catalog metadata instead of assuming sources are available.

Read-only Coral SQL execution

War Room treats Coral SQL as an auditable evidence query layer.

This is why the incident workbench can show the exact SQL that supported a conclusion rather than only an AI paragraph.

Natural-language to Coral SQL

When a project has an enabled BYOK AI model, War Room can turn an operator question into Coral SQL:

  • apps/web/app/api/coral/ask/route.ts loads project catalog metadata, applies required filter defaults, calls the configured AI model, validates the generated SQL as read-only, verifies required filters, runs the query, and summarizes the rows.
  • apps/web/lib/coral/ask-sql.ts contains the SQL generation and answer summarization logic.

The output includes the question, answer, generated SQL, returned rows, explanation, and transport used (mcp or cli).

Coral incident ingestion

War Room can promote Coral rows into incident candidates.

Current Coral ingestion providers are GitHub, Sentry, Datadog, Grafana, PagerDuty, and Notion. It handles missing required filters, unsupported catalog entries, source-not-installed states, query failures, duplicate incidents, and persistence failures explicitly.

Incident lifecycle placeholder

Coral in FastAPI investigation orchestration

The FastAPI backend remains independently runnable, but it can run project-scoped Coral investigations above the same source setup:

This keeps orchestration in FastAPI while source retrieval and cross-source context remain Coral-native.

Query generation for operational workflows

War Room includes reusable Coral SQL builders for investigation patterns:

For incident-grade correlation, Coral should join sources when the question is causal: "what changed before the alert?", "which deploy introduced this error?", "which conversation or ticket confirms impact?", or "which follow-up already exists?" Single-source Coral queries are still valid for provider-specific signals, but cross-source RCA is strongest when the SQL ties deploys, errors, alerts, chat, incidents, tickets, and operational knowledge together in one auditable query.

The most relevant join patterns for the connected sources, assuming everything is connected, are:

-- Deployment -> pull request -> Sentry error regression.
SELECT
  d.repo,
  d.sha,
  d.environment,
  d.created_at AS deployed_at,
  pr.title AS pull_request_title,
  pr.state AS pull_request_state,
  s.title AS sentry_issue_title,
  s.level AS sentry_level,
  s.first_seen
FROM github.repo_deployments d
LEFT JOIN github.pulls pr
  ON pr.owner = d.owner
 AND pr.repo = d.repo
 AND (pr.head__sha = d.sha OR pr.merge_commit_sha = d.sha)
LEFT JOIN sentry.issues s
  ON (s.release = d.sha OR s.release = pr.head__sha OR s.project = d.repo)
 AND s.first_seen BETWEEN d.created_at AND d.created_at + INTERVAL '60 minutes';
-- Deployment -> Datadog monitor/event spike.
SELECT
  d.repo,
  d.sha,
  d.created_at AS deployed_at,
  m.name AS monitor_name,
  m.status AS monitor_status,
  m.last_triggered_ts,
  e.title AS event_title,
  e.timestamp AS event_timestamp
FROM github.repo_deployments d
LEFT JOIN datadog.monitors m
  ON (m.service = d.repo OR m.service_name = d.repo)
 AND m.last_triggered_ts BETWEEN d.created_at AND d.created_at + INTERVAL '60 minutes'
LEFT JOIN datadog.events e
  ON (e.service = d.repo OR e.service_name = d.repo)
 AND e.timestamp BETWEEN d.created_at AND d.created_at + INTERVAL '60 minutes';
-- Alert -> PagerDuty incident -> Slack incident conversation.
SELECT
  g.title AS grafana_alert,
  g.state AS grafana_state,
  g.starts_at,
  p.title AS pagerduty_incident,
  p.status AS pagerduty_status,
  sl.channel,
  sl.thread_ts,
  sl.text
FROM grafana.alerts g
LEFT JOIN pagerduty.incidents p
  ON (p.service = g.service OR p.service_name = g.service)
 AND p.created_at BETWEEN g.starts_at - INTERVAL '15 minutes'
                      AND g.starts_at + INTERVAL '90 minutes'
LEFT JOIN slack.messages sl
  ON LOWER(sl.text) LIKE '%' || LOWER(g.service) || '%'
 AND sl.created_at BETWEEN g.starts_at - INTERVAL '15 minutes'
                       AND g.starts_at + INTERVAL '90 minutes';
-- Incident/service context -> Jira and Linear follow-up coverage.
SELECT
  i.service,
  i.title AS incident_title,
  j.key AS jira_key,
  j.summary AS jira_summary,
  j.status AS jira_status,
  li.identifier AS linear_identifier,
  li.title AS linear_title,
  li.state AS linear_state
FROM incident.events i
LEFT JOIN jira.issues j
  ON (LOWER(j.summary) LIKE '%' || LOWER(i.service) || '%'
   OR LOWER(j.description) LIKE '%' || LOWER(i.service) || '%')
LEFT JOIN linear.issues li
  ON (LOWER(li.title) LIKE '%' || LOWER(i.service) || '%'
   OR LOWER(li.description) LIKE '%' || LOWER(i.service) || '%');
-- Feature flag or operational note -> deploy and incident context.
SELECT
  d.repo,
  d.sha,
  d.created_at AS deployed_at,
  ld.name AS flag_name,
  ld.updated_at AS flag_updated_at,
  n.title AS note_title,
  n.updated_at AS note_updated_at
FROM github.repo_deployments d
LEFT JOIN launchdarkly.feature_flags ld
  ON (ld.project = d.repo OR ld.key = d.repo)
 AND ld.updated_at BETWEEN d.created_at - INTERVAL '30 minutes'
                       AND d.created_at + INTERVAL '60 minutes'
LEFT JOIN notion.pages n
  ON LOWER(n.title) LIKE '%' || LOWER(d.repo) || '%'
 AND n.updated_at >= d.created_at - INTERVAL '7 days';

4. Connected Data Sources

War Room supports project-scoped integrations with different roles:

  • Coral read sources: GitHub, Slack, Sentry, Datadog, Jira, Linear, Notion, PagerDuty, Grafana, and LaunchDarkly.
  • Incident trigger webhooks: GitHub, Sentry, Datadog, Grafana, and PagerDuty.
  • Request-driven Coral polling triggers: GitHub, Sentry, Datadog, Grafana, and PagerDuty.
  • Slack workflow integration: Slack OAuth, channel sync, notifications, interactions, app mentions, and action routing.
  • Ticket write integrations: Jira and Linear ticket creation.
  • Repository correlation helpers: GitHub REST/GraphQL utilities under services/github.
  • Provider helper services: Sentry, tickets, Slack workflow service, and Coral query-builder packages under services.

Integration configuration is project-scoped. Secrets are encrypted before storage, redacted before returning to the browser, and used to materialize Coral source state only when needed.

5. Local Dev Environment Setup + Env Setup

Prerequisites

  • Node.js 20+
  • npm 11+
  • Python 3.12+
  • Supabase project with Auth and Postgres
  • Coral CLI installed and available as coral, or set CORAL_CLI_PATH

Install dependencies

npm install

Environment files

Start from the example file:

cp .env.example .env.local
cp .env.example apps/web/.env.local

PowerShell:

Copy-Item .env.example .env.local
Copy-Item .env.example apps/web/.env.local

The web app reads apps/web/.env.local. The database scripts also load .env.local from the repo root or apps/web/.env.local.

Required local variables

NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=
DATABASE_URL=
DIRECT_URL=
WAR_ROOM_PUBLIC_URL=http://localhost:3000
WAR_ROOM_API_URL=http://localhost:3000
WAR_ROOM_FASTAPI_URL=http://localhost:8000
WAR_ROOM_API_TOKEN=
CREDENTIAL_ENCRYPTION_KEY=

Use the pooled Supabase connection string for DATABASE_URL and the direct connection string for DIRECT_URL when running migrations. CREDENTIAL_ENCRYPTION_KEY is required before War Room can store encrypted project credentials such as Coral source tokens, Slack tokens, and BYOK model keys.

AI model configuration

CREDENTIAL_ENCRYPTION_KEY=
WAR_ROOM_API_TOKEN=
WAR_ROOM_API_URL=http://localhost:3000
WAR_ROOM_FASTAPI_URL=http://localhost:8000

AI is optional for core incident workflows, but required for natural-language Coral questions and model-backed report generation.

Provider API keys are normally configured in the product under Settings -> AI Models. War Room stores those BYOK model records in Postgres as encrypted AiModelConfiguration rows, then decrypts them only at runtime for Coral ask, report generation, postmortems, and FastAPI validation. CREDENTIAL_ENCRYPTION_KEY must be present before those encrypted model credentials can be saved or read.

The variables below are optional fallback/runtime variables for standalone agent package execution or FastAPI analysis when no project-scoped active model is available:

LITELLM_BASE_URL=http://localhost:4000/v1
LITELLM_API_KEY=
LITELLM_MODEL=gemini/gemini-2.5-flash
GEMINI_API_KEY=
GOOGLE_API_KEY=
OPENAI_API_KEY=
ANTHROPIC_API_KEY=
VERCEL_AI_GATEWAY_API_KEY=

Optional Slack variables

SLACK_CLIENT_ID=
SLACK_CLIENT_SECRET=
SLACK_OAUTH_STATE_SECRET=
SLACK_SIGNING_SECRET=
WAR_ROOM_PUBLIC_URL=http://localhost:3000

Slack notification OAuth is separate from Slack as a Coral read source. Coral Slack read access is configured per project with a SLACK_TOKEN in the settings UI.

Optional source and Coral variables

GITHUB_TOKEN=
SENTRY_ORG=
SENTRY_TOKEN=
DD_SITE=datadoghq.com
DD_API_KEY=
DD_APPLICATION_KEY=
LINEAR_API_KEY=
PAGERDUTY_API_TOKEN=
GRAFANA_URL=
GRAFANA_TOKEN=
LAUNCHDARKLY_TOKEN=
CORAL_CLI_PATH=coral
CORAL_PROJECT_CONFIG_ROOT=
CORAL_QUERY_TIMEOUT_MS=15000
CORAL_MCP_TIMEOUT_MS=15000
CORAL_SOURCE_TIMEOUT_MS=30000
WAR_ROOM_GITHUB_OWNER=
WAR_ROOM_GITHUB_REPO=

See .env.example for the full list, including Jira, Linear workflow fields, report timeouts, and standalone Slack service settings.

Database setup

npm --workspace @workspace/db run migrate:deploy

Run the web app

npm run dev:web

Open:

http://localhost:3000

Run the FastAPI backend

In a second terminal:

cd apps/api
python -m venv .venv
.venv\Scripts\activate
pip install -e .
uvicorn main:app --reload

Open:

http://localhost:8000/docs

Extra Project Context

Architecture

flowchart LR
  Web[Next.js web app] --> DB[Supabase Postgres + Prisma]
  Web --> Shared[Shared TypeScript contracts]
  Web --> Coral[Coral source/query layer]
  Web --> FastAPI[FastAPI orchestration API]
  FastAPI --> Agents[LangChain/LangGraph analysis]
  Web --> Slack[Slack OAuth, events, interactions]
  Web --> Tickets[Jira and Linear ticket services]
  Coral --> Sources[GitHub, Slack, Sentry, Datadog, Grafana, PagerDuty, Jira, Linear, Notion, LaunchDarkly]
Loading

Repository Layout

apps/web          Next.js app, UI, auth, settings, incidents, Slack routes, Coral routes, API handlers
apps/api          independently runnable FastAPI orchestration and LLM-analysis backend
packages/db       Prisma schema, migrations, and database helpers
packages/shared   shared incident, trigger, integration, workspace, and AI-model contracts
packages/ui       shared shadcn/ui primitives and Tailwind global styles
packages/coral    Coral metadata and SQL execution helpers
packages/agents   reports, postmortems, runbooks, risk, remediation, and analysis helpers
services/coral    Coral query-builder service package
services/github   GitHub REST/GraphQL correlation helpers
services/sentry   Sentry signal helpers
services/tickets  Jira and Linear ticket clients
services/slack    optional standalone Slack development service
docs              architecture notes, MVP boundaries, setup docs, and planning material

Useful Commands

npm run dev
npm run lint
npm run typecheck
npm run test
npm run build
npm --workspace web run build
npm --workspace @workspace/db run generate
npm --workspace @workspace/db run migrate:dev
npm --workspace @workspace/db run migrate:deploy

FastAPI syntax check:

cd apps/api
python -m py_compile main.py

Product Flow

  1. Open /dashboard for project overview, incidents, source status, and action-center context.
  2. Open /incidents to inspect project incident history.
  3. Open an incident workbench to review evidence, timeline, Coral SQL, agents, actions, tickets, reports, and postmortems.
  4. Open /coral for the source query console and AI-assisted Coral query path.
  5. Open /settings to configure project integrations, Slack, AI models, services, dependencies, and trigger policies.

Boundaries

  • There is no in-repo background worker or distributed queue. Scheduled trigger polling is exposed as a token-protected HTTP endpoint and must be called by an external scheduler.
  • Remediation actions are approval-oriented. War Room does not autonomously change production infrastructure.
  • The standalone services/slack package is an optional development service; the primary Slack product path is implemented in the Next.js app routes.

Reference Docs

GitHub Actions

The repository includes a Prisma migration workflow at .github/workflows/prisma-migrations.yml. It runs on pushes to master only when files under packages/db/prisma/migrations/** change, then applies migrations with:

npm --workspace @workspace/db run migrate:deploy

Required repository secrets:

DATABASE_URL
DIRECT_URL

6. Future Improvements

  • Replace the Coral Investigation Flow and Incident Lifecycle placeholder assets with final product diagrams or screenshots.
  • Add richer provider-specific Coral query plans for each connected source so every integration becomes incident-grade, not just connectable.
  • Expand trigger coverage with more verified webhook providers and scheduler integrations while keeping polling request-driven unless a worker is explicitly introduced.
  • Add stronger project-level permission controls without turning the MVP into enterprise RBAC.
  • Improve deployment and trace correlation with more OpenTelemetry-backed Coral tables.
  • Add more post-incident learning loops that write durable operational memory from completed postmortems.
  • Package a shorter hackathon operator guide with screenshots and a fixed narrative path.

Deployment Notes

  • Deploy apps/web as the Next.js frontend.
  • Deploy apps/api as an independently runnable FastAPI service.
  • Configure Supabase Auth redirect URLs for the deployed web origin.
  • Set WAR_ROOM_PUBLIC_URL, WAR_ROOM_API_URL, and WAR_ROOM_FASTAPI_URL to public deployment URLs.
  • Configure Slack redirect URLs and request signing if Slack workflows are enabled.
  • Keep provider credentials in deployment secrets or project-scoped encrypted records, not in committed files.

Made as part of Pirates of the CoralBean hackathon!

About

AI incident operations copilot that connects Coral-powered evidence, timelines, Slack, tickets, and reports into one auditable workflow.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages