FluxLens is an engineering delivery operating system that forecasts coordination risk using a deterministic heuristic scoring model on top of your existing toolchain (Jira, Slack, GitHub).
FluxLens uses a leakage-safe, calibrated coordination-risk scorer built under strict temporal contracts (Phases 5-7).
- Active scoring path: deterministic heuristic (
baseline-heuristic.v1) — a learned model will be promoted only once real connector history passes the Phase 7 acceptance gate. - Methodology: 20 engineered coordination features (blocked ticket rates, handoff latency, cross-team dependency age, Slack escalation density, and coverage/freshness signals) computed with
observedAt <= snapshot_tto prevent leakage. - Evaluation: walk-forward validation, PR-AUC primary metric, Platt/isotonic calibration, full slice analysis, and a versioned promotion gate (
promotion-gate.v1). Seedata/model_eval/coordination_risk_v1/report.mdandmodel_card.mdfor the full evaluation record. - Model specs:
data/model_specs/— frozen label spec, feature catalog, and scoring contract.
- Health gauge with live score needle
- Header navigation with search, notifications, and command palette
- Overview layout with forecast, signals, and team heatmaps
- NextAuth.js v5 integration with credentials and Google OAuth
- Sign-in page at
/auth/signin - Demo credentials:
demo@fluxlens.ai/demo123 - Protected routes with middleware
- Session management with JWT
- Zustand store with localStorage persistence
- Saves filters, theme, dashboard layout, and notification settings
- API endpoints at
/api/preferencesfor backend sync
- RESTful endpoint:
GET /api/flux/data - Toggle between mock and real data
- Query parameters:
department,startDate,endDate,mock
- React Error Boundary with graceful fallbacks
- Skeleton loaders for all major components
- Toast notifications via Sonner
- Development error details, production-friendly messages
/about- Company mission and technology/pricing- Three-tier pricing model
- In-app action chips in the assistant to send weekly reports, trigger syncs, export snapshots, and run full integration syncs
- Actions: rebuild snapshots from events (Supabase service role required), export CSV/PDF with download links
- Backend endpoint
/api/agent/executewith rate limits, audit logging (agent_runstable), and dry-run support - Enable via
AGENT_ENABLED=true; setAGENT_DEFAULT_DRY_RUN=falseto execute actions (set totruefor simulation-only mode)
For detailed setup instructions, see SETUP.md.
npm install
cp .env.example .env.local
npx tsx scripts/checkSupabaseReady.ts # optional sanity check
npm run dx:doctor # env and connectivity check
npm run dev- Node.js 18+
- npm or yarn
- OpenSSL (for generating secrets)
npm install
cp .env.example .env.local
# Generate a secure NextAuth secret
openssl rand -base64 32
# Copy the output to NEXTAUTH_SECRET in .env.local
npm run devOpen http://localhost:3000 to view the app.
- Email: demo@fluxlens.ai
- Password: demo123
These are demo credentials for development only.
fluxlens-ai/
├── src/
│ ├── app/ # Next.js App Router routes
│ │ ├── (app)/ # Authenticated product surfaces
│ │ ├── (marketing)/ # Marketing, legal, and docs pages
│ │ ├── api/ # API routes
│ │ ├── auth/ # NextAuth and registration endpoints
│ │ ├── flux/data/ # Flux data API
│ │ └── integrations/ # OAuth and sync routes
│ ├── components/ # Product, marketing, and shared UI
│ ├── lib/ # Domain logic, integrations, billing, AI
│ ├── store/ # Zustand state management
│ └── auth.ts # NextAuth configuration
├── docs/
│ ├── design/ # Brand, design system, font pack
│ ├── product/ # Product guides and reliability/SLA
│ ├── prototypes/ # Preserved design handoff prototypes
│ ├── strategy/ # Active goals and readiness notes
│ └── archive/ # Historical implementation reports
├── scripts/ # Ingest, rebuild, report, and utility scripts
├── tests/ # Vitest and Playwright coverage
└── WARP.md # AI assistant context
# AI Provider (defaults to OpenRouter + Llama 3.3)
NEXT_PUBLIC_AI_PROVIDER=openrouter
OPENROUTER_API_KEY=your_openrouter_key
OPENROUTER_DEFAULT_MODEL=meta-llama/llama-3.3-8b-instruct:free
AI_SIMPLE_MODEL=meta-llama/llama-3.3-8b-instruct:free
AI_COMPLEX_MODEL=meta-llama/llama-3.3-70b-instruct:free
NEXT_DISABLE_FONT_DOWNLOADS=1
NEXT_BINARY_CACHE_DIR=.next/cache/swc
NEXT_FORCE_WASM=1
PLAYWRIGHT_TEST_BASE_URL=http://127.0.0.1:3100
# Supabase (optional until live data pipeline is ready)
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=public-anon-key
SUPABASE_SERVICE_ROLE_KEY=service-role-key
# Optional OpenAI fallback
OPENAI_API_KEY=
OPENAI_DEFAULT_MODEL=gpt-4o-mini
# NextAuth
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-secret-key
# Google OAuth (optional)
GOOGLE_CLIENT_ID=your_client_id
GOOGLE_CLIENT_SECRET=your_client_secret
# Integration OAuth (Slack, Jira, Linear)
SLACK_CLIENT_ID=your_slack_client_id
SLACK_CLIENT_SECRET=your_slack_client_secret
JIRA_CLIENT_ID=your_jira_client_id
JIRA_CLIENT_SECRET=your_jira_client_secret
LINEAR_CLIENT_ID=your_linear_client_id
LINEAR_CLIENT_SECRET=your_linear_client_secret
# Feature Flags
NEXT_PUBLIC_ENABLE_AI_FEATURES=true
NEXT_PUBLIC_ENABLE_EXPORT=true
NEXT_PUBLIC_USE_REAL_DATA=false-
Install and authenticate the Supabase CLI.
-
Configure
SUPABASE_URL,SUPABASE_ANON_KEY, andSUPABASE_SERVICE_ROLE_KEYin.env.local. -
Apply the migrations (remote
db seed --fileis not supported in Supabase CLI v2.58):SUPABASE_DB_PASSWORD=your_db_password \ supabase db push --db-url "postgresql://postgres.<project_ref>:${SUPABASE_DB_PASSWORD}@aws-1-us-east-1.pooler.supabase.com:5432/postgres" -
Populate Supabase with a fresh mock snapshot (safe to rerun):
FLUXLENS_ORG_ID=demo-org FLUXLENS_RESET=true npx tsx scripts/ingestSupabaseSnapshots.ts
- Set
FLUXLENS_ORG_IDto target a different tenant. - Omit
FLUXLENS_RESETor set it tofalseto append without clearing prior rows.
- Set
-
Validate connectivity before switching to real-data mode:
npx tsx scripts/checkSupabaseReady.ts
- Confirms env variables are present and PostgREST responds.
- Exits non-zero if
NEXT_PUBLIC_USE_REAL_DATAis true but Supabase env is missing.
-
When ready for real integrations, schedule the ingestion script via cron, Supabase Edge Functions, or your job runner. Example cron entry:
0 2 * * * cd /path/to/fluxlens-ai && \ FLUXLENS_ORG_ID=demo-org FLUXLENS_RESET=true \ npx tsx scripts/ingestSupabaseSnapshots.ts >> logs/ingest.log 2>&1
The workflow at
.github/workflows/nightly-supabase-ingest.ymlruns the same command nightly at 02:00 UTC. DefineSUPABASE_URL,SUPABASE_ANON_KEY, andSUPABASE_SERVICE_ROLE_KEYas repository secrets.
- Seed Supabase with
scripts/ingestSupabaseSnapshots.tsso/api/flux/datahas a snapshot to read. - Set
NEXT_PUBLIC_USE_REAL_DATA=truein.env.localand restart the dev server. - Provide
SUPABASE_URL,SUPABASE_ANON_KEY, andSUPABASE_SERVICE_ROLE_KEY. - Verify with
?mock=false(e.g./api/flux/data?mock=false) or runSESSION_COOKIE="next-auth.session-token=..." ./scripts/smokeRealData.sh.
- Workflow:
.github/workflows/nightly-supabase-ingest.yml - Schedule:
0 2 * * *(daily, plus manualworkflow_dispatch) - Secrets required:
SUPABASE_URL,SUPABASE_ANON_KEY,SUPABASE_SERVICE_ROLE_KEY - Runs
npx tsx scripts/ingestSupabaseSnapshots.tswithFLUXLENS_ORG_ID=demo-organdFLUXLENS_RESET=true.
FLUXLENS_ORG_ID=demo-org \
SUPABASE_URL=... \
SUPABASE_SERVICE_ROLE_KEY=... \
npx tsx scripts/ingestSlackSnapshot.ts data/slackSnapshot.json- Input format:
data/slackSnapshot.json - Each message is persisted as an
eventsrow withtype="slack_signal"plus severity metadata derived fromurgency - Audit logging via
/audit_logis best-effort; failures do not block ingestion
FLUXLENS_ORG_ID=demo-org \
SUPABASE_URL=... \
SUPABASE_SERVICE_ROLE_KEY=... \
npx tsx scripts/ingestJiraSnapshot.ts data/jiraSnapshot.json- Defaults to
data/jiraSnapshot.jsonif no path is provided - Rebuilds the snapshot after ingest so UI freshness indicators update
- Requires Supabase env keys and
NEXT_PUBLIC_USE_REAL_DATA=true
FLUXLENS_ORG_ID=demo-org \
SUPABASE_URL=... \
SUPABASE_SERVICE_ROLE_KEY=... \
JIRA_ACCESS_TOKEN=... \
JIRA_CLOUD_ID=... \
JIRA_PROJECT_KEY=OPS \
npx tsx scripts/ingestJiraApi.ts- Set
JIRA_INGEST_LIMIT(default 50) to cap results. - Rebuilds the snapshot after ingest so dashboard freshness indicators stay current.
chmod +x scripts/smokeRealData.sh
SESSION_COOKIE="next-auth.session-token=..." ./scripts/smokeRealData.sh- Requires a valid
SESSION_COOKIE(from browser DevTools) and optionallyBASE_URL(defaults tohttp://localhost:3000). - Prints the first ~400 bytes of each response for inspection.
- The
Real Data Smokeworkflow (.github/workflows/real-data-smoke.yml) runs daily in CI whenSESSION_COOKIEis set as a GitHub secret.
- Supabase targets: extend or reuse tables such as
event_record,event_comment,diagnosis, andaudit_log. Add new columns in a migration alongside mock fallbacks to keep the API contract backward compatible. - Ingestion worker: create a script under
scripts/that normalizes provider payloads and callsrepo.addEvents,repo.addComments, or new repository helpers. Keep provider adapters pure for testability. - API endpoints: expose
/api/integrations/slackor/api/integrations/jirato trigger re-syncs, surface health, or accept signed webhooks. Validate provider signatures, enqueue work, and respond quickly. - Testing: add unit tests that feed recorded Slack/Jira JSON into the worker and assert Supabase insert batches. For end-to-end coverage, add a Playwright spec that mocks the provider endpoint and verifies the dashboard reflects the ingested data.
-
All OpenRouter calls attach
OPENROUTER_SITE_URLandOPENROUTER_APP_TITLEheaders, parse rate-limit headers, and emit structured quota logs. Configure:OPENROUTER_SITE_URL=https://your-domain OPENROUTER_APP_TITLE="FluxLens" AI_QUOTA_ALERT_THRESHOLD=10 # optional, defaults to 10 remaining calls AI_ALERT_WEBHOOK_URL=https://hooks.slack.com/services/...
-
When remaining quota falls below the threshold (or reaches
0),quotaMonitorlogs a warning and optionally POSTs toAI_ALERT_WEBHOOK_URL. -
Backend endpoints return structured fallback payloads instead of silent 429 errors:
{ "error": "AI features are temporarily unavailable due to free quota exhaustion.", "fallback": true, "provider": "simulated", "quotaDetails": { "remaining": 0, "limit": 50, "reset": "2025-10-31T00:00:00Z" } } -
The frontend surfaces failures with a quota banner, labels simulated responses, and shows actionable guidance.
-
Offline fallbacks include canned insights so demos continue when the free plan is exhausted.
-
Recent quota events are persisted client-side via
useQuotaStore.
# Run unit tests
npm run test
# Type check
npm run buildnpm run dx:doctor— validates env keys and Supabase connectivity.- Husky pre-push runs
lintand targetedvitest --run(setSKIP_PREPUSH=1to bypass).
Calculates organizational health based on:
- Response latency patterns
- Handoff failure rates
- Meeting density load
- Cross-team collaboration index
- 30/60/90-day forecast windows
- Linear regression on metric slopes
- Anomaly detection with 2-sigma deviation
- Confidence scoring
- OpenAI GPT-4 integration
- Root cause analysis
- Intervention recommendations
- Natural language explanations
- Event diagnosis on predicted risks with cached AI analysis
For production deployment, see DEPLOYMENT.md.
npm i -g vercel
vercel login
vercel --prodConfigure the following in the Vercel dashboard:
NEXTAUTH_SECRET— generate withopenssl rand -base64 32NEXTAUTH_URL— your production domain (e.g.https://fluxlens.ai)OPENAI_API_KEY— optional, for AI featuresGOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRET— optional, for Google OAuth
- Frontend: Next.js 16 (App Router), React 19, TypeScript
- Styling: Tailwind CSS, Radix UI
- State: Zustand (global), localStorage (persistence)
- Auth: NextAuth.js v5
- Charts: Recharts, D3.js
- AI: OpenAI GPT-4
- Deployment: Vercel
- JWT-based session management
- Protected API routes with auth middleware
- HTTPS-only cookies in production
- CSP in
src/middleware/security.tsremoves'unsafe-inline'/'unsafe-eval'in production and restrictsconnect-srcto known domains - AI routes include basic rate limiting
FluxLens supports OAuth integrations with Slack, Jira, and Linear. See docs/INTEGRATIONS.md for setup instructions.
- Configure OAuth apps and add credentials to
.env.local - Run
npx prisma migrate devto create the IntegrationToken table - Connect integrations via Settings → Integrations
# Manual sync via API
curl -X POST http://localhost:3000/api/integrations/sync \
-H "Cookie: next-auth.session-token=..."
# Background job
npx tsx scripts/sync-integrations.tsAutomated sync via cron:
0 * * * * cd /path/to/fluxlens-ai && npx tsx scripts/sync-integrations.tsKeep priorities in sync with docs/strategy/CURRENT_GOALS.md (single source of truth).
This is a private project. For questions or support:
- General: hello@fluxlens.ai
- Sales: sales@fluxlens.ai
- Support: support@fluxlens.ai
Proprietary — All rights reserved
- Server-only:
OPENROUTER_API_KEY,OPENAI_API_KEY, optional default model vars - Public flags:
NEXT_PUBLIC_AI_PROVIDER,NEXT_PUBLIC_APP_URL - OAuth:
GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET
See .env.example for the authoritative list.
src/lib/db/repository.ts prefers Supabase for preferences, audit logs, events, comments, health deltas, and AI diagnoses when the required environment variables are present. It falls back to the JSON files under data/ for local demo mode.
- Monitor
GET /api/healthand the root page via UptimeRobot or equivalent. ALERT_WEBHOOK_URLreceives failure notifications fromscripts/refreshSupabaseSnapshots.tsand other ingest jobs.- Observability runbook:
docs/MONITORING.md.
npx tsx scripts/generate_proof_points.ts
npx tsx scripts/export_proof_points_pdf.tsOutputs land in docs/out/ and are referenced by docs/DATA_ROOM.md.
- Observability smoke:
pnpm vitest run tests/observability.spec.ts— verifies Sentry/PostHog keys before deploys. - Weekly report delivery:
npm run report:weeklyorPOST /api/cron/send-weekly-report(requiresCRON_SECRET,REPORT_EMAIL_TO,WEEKLY_REPORT_WEBHOOK_URL/DIGEST_SLACK_WEBHOOK_URL). - Weekly automations:
.github/workflows/weekly-report-cron.ymlposts to/api/cron/send-weekly-reportand emits a funnel health Slack ping via/api/funnel/weekly. - Nightly Supabase refresh:
.github/workflows/nightly-rebuild.ymlrunsnpm run supabase:refresh; keepALERT_WEBHOOK_URLset so ingest failures trigger notifications.