/home/techb158/cosmic-risk.abdallabala.com/docs
Edit: /home/techb158/cosmic-risk.abdallabala.com/docs/development-summary.md (7070B)
# COSMIC AI-Risk Dashboard — Development Summary
## Goal
Transform the academic COSMIC AI-Risk Dashboard prototype into a production-ready SaaS application with multi-tenant authentication, full CRUD APIs, interactive SPA frontend with data entry forms, SSO/OIDC support, and Docker deployment.
---
## Architecture
- **Framework**: Next.js 15 App Router
- **ORM**: Prisma 5.22.0 with PostgreSQL
- **Auth**: Session cookie auth (`cosmic_session`) with bcrypt password hashing
- **RBAC**: 9 roles with permission arrays
- **API**: Next.js API routes (no Express)
- **Deployment**: Docker with `node:20-bookworm-slim`, `output: "standalone"`
- **Database**: PostgreSQL 16 via Docker or Supabase
---
## Progress Summary
### Phase 1 — Core Infrastructure
- Next.js 15 App Router project with TypeScript
- Prisma schema with 24 models, 11 enums
- PostgreSQL database with Docker Compose
- Session-based authentication (login/signup/logout)
- 9 RBAC roles with granular permissions
- Multi-tenant: Organization → Workspace → Project hierarchy
### Phase 2 — API & Services
- All CRUD API routes for risks, mitigations, gates, projects, integrations
- Services layer: auth-service, project-service, risk-service, etc.
- Domain engine: risk scoring with dimension scores
- Rate limiting via Next.js Edge middleware (100 req/min per IP)
- Idempotency via in-memory Map with 24h TTL (risk/mitigation POST)
- Metrics collection endpoint
### Phase 3 — Frontend
- Interactive SPA dashboard with 7 tabs:
1. Overview — Summary cards, risk chart, recent activity
2. Projects — Full project list with Open/Delete
3. Risks — Create, edit, delete, status transitions
4. Mitigations — Create, edit, delete with risk dropdown
5. Gate — Evaluate gate, add decisions (APPROVED/REJECTED/etc.)
6. Integrations — Create Trello/Jira/Asana/MS Planner connections
7. Audit — Project activity history log
- Project selector dropdown in header
- Project settings modal (gear icon) — edit name/description/status
- Quick-access ProjectManagerModal from header
### Phase 4 — SSO/OIDC
- Mock OIDC provider for local development
- Discovery endpoint, token exchange, state CSRF protection
- SSO callback creates org/workspace/project for first-time users
- Enabled in Docker (env vars uncommented)
### Phase 5 — Docker & Deployment
- Multi-stage Dockerfile with `output: "standalone"`
- Non-root user (`cosmic`) for security
- Healthcheck endpoint
- `docker-compose.yml` with local PostgreSQL
- `docker-compose.supabase.yml` override for Supabase
- pgAdmin web UI at port 5050
- Ports: app on 8092, pgAdmin on 5050, PostgreSQL on 5432
### Phase 6 — Seed Data
- 5 seeded users with individual org/workspace/project:
| Email | Password | Role | Risks |
|---|---|---|---|
| owner@cosmic.local | cosmic123 | owner | 5 |
| admin@cosmic.local | admin123 | admin | 4 |
| pm@cosmic.local | pm123 | project_manager | 4 |
| risk-owner@cosmic.local | risk123 | risk_owner | 4 |
| viewer@cosmic.local | view123 | viewer | 4 |
- Each user gets lifecycle phases, gate evaluations, indicators, integrations
- Owner project has 5 detailed risks with mitigations at various stages
### Phase 7 — Supabase Preparation
- `relationMode = "prisma"` added to Prisma schema for PgBouncer compatibility
- `.env` template includes both local Docker and Supabase connection strings
- `docker-compose.supabase.yml` removes local postgres service
- `scripts/setup-supabase.sh` automates schema push + seed + build
---
## Key Technical Decisions
| Decision | Rationale |
|---|---|
| Session cookies over JWT | Server-side revocation support |
| bcrypt for passwords | Industry standard hashing |
| `Secure` flag excluded in dev | HTTP works on localhost |
| Edge middleware rate limiting | 100 req/min sliding window per IP |
| In-memory idempotency Map | 24h TTL, `.unref()` on timeout |
| Debian slim base image | Prisma 5.22.0 needs OpenSSL 1.1 (not Alpine) |
| Query params for tabs (`?tab=Risks`) | Avoids 404s on non-existent sub-routes |
| `useSearchParams` for tab state | Replaces `useState` + `window.location.search` |
| Explicit cascade delete | Deletes all child records by type in project-service.js |
| `relationMode = "prisma"` | Required for Supabase PgBouncer connection pooling |
---
## How to Run
### Local Development (no Docker)
```powershell
# Requires PostgreSQL running locally on port 5432
npm install
npx prisma db push
node prisma/seed.js
npm run dev
# → http://localhost:8090
```
### Docker (local PostgreSQL)
```powershell
docker compose up -d --build
# → http://localhost:8092
# → pgAdmin: http://127.0.0.1:5050 (admin@cosmic.com / cosmic123)
```
### Docker (Supabase)
```powershell
# 1. Update DATABASE_URL in .env with Supabase connection string
# 2. Run:
docker compose -f docker-compose.yml -f docker-compose.supabase.yml up -d
```
### Local Fallback (no DB)
```powershell
npm run local:fallback
# → http://localhost:8090
```
---
## Testing
```powershell
npm test
```
Runs 7 test files:
- `saas-domain.test.js` — Domain logic (risk scoring, gates)
- `tenant-security.test.js` — Multi-tenant data isolation
- `idempotency.test.js` — Idempotency key behavior
- `metrics.test.js` — Metrics collection
- `oidc.test.js` — OIDC/SSO flows
- `rate-limit.test.js` — Rate limiting
- `integration-service.test.js` — Integration sync logic
All tests pass.
---
## Database
- **Tables**: 24
- **Enums**: 11
- **Host**: `localhost:5432` (Docker) / `postgres:5432` (Docker internal)
- **Database**: `cosmic_saas`
- **User**: `cosmic` / Password: `cosmic`
- **Schema reference**: See `docs/database-guide.md`
---
## Files of Note
| File | Purpose |
|---|---|
| `prisma/schema.prisma` | 24 models, 11 enums, `relationMode = "prisma"` |
| `prisma/seed.js` | Seeds 5 users with orgs, projects, risks, sample data |
| `src/app/dashboard/page.jsx` | Main dashboard (1100+ lines, 7 tabs, full CRUD forms) |
| `src/services/project-service.js` | Cascade delete, project CRUD |
| `src/services/auth-service.js` | Login/signup/session/bcrypt |
| `src/services/sso-service.js` | SSO callback, OIDC token exchange |
| `src/lib/api-client.js` | Fetch wrapper with error handling |
| `src/lib/request-context.js` | Actor extraction, permission checks |
| `src/components/ErrorBoundary.jsx` | React error boundary with retry |
| `src/domain/risk-engine.js` | Risk dimension scoring |
| `mock-oidc-provider.js` | Local OIDC provider for SSO testing |
| `docker-compose.yml` | App + PostgreSQL + pgAdmin |
| `docker-compose.supabase.yml` | Override to remove local postgres |
| `scripts/setup-supabase.sh` | Automated Supabase setup |
| `docs/database-guide.md` | Complete database schema reference |
---
## Known Issues
- `docker compose up -d --build` can time out in PowerShell — use separate `docker build` + `docker compose up -d` instead
- When switching from local Docker Postgres to Supabase, update `DATABASE_URL` in `.env` and restart
- pgAdmin uses `postgres` as host (Docker internal network), not `localhost`