ADR-131: Dynamic BI Pages Cloud Architecture
Status
PROPOSED - 2026-01-28
Context
Building on ADR-130 (BI Dashboard Architecture), we need to extend the local dashboard capability to support:
- On-Demand Cloud Deployment - Launch shareable BI pages on GKE/Cloud Run
- Team Collaboration - Share dashboards across teams with role-based access
- Communication Integration - Push alerts and links to Slack, Teams, Email
- Dynamic Page Generation - Create temporary pages for specific views/reports
- Cost Optimization - Serverless architecture with scale-to-zero
Requirements
| Requirement | Priority | Rationale |
|---|---|---|
| On-demand page generation | P1 | Share specific views without always-on servers |
| Shareable URLs | P1 | Team collaboration across locations |
| Communication channel integration | P1 | Alert teams when reports are ready |
| Role-based access control | P1 | Restrict sensitive data to authorized users |
| Auto-expire pages | P2 | Cost optimization, data freshness |
| Mobile-friendly | P2 | Access from any device |
| Audit logging | P2 | Compliance, usage tracking |
Constraints
- Must integrate with existing multi-tenant architecture (ADR-053)
- Must support offline-first local mode (ADR-130)
- Must comply with HIPAA/SOC2 requirements
- Must minimize cloud costs (scale-to-zero)
Decision
Implement a hybrid local-cloud BI architecture with on-demand page generation.
Architecture Overview
┌─────────────────────────────────────────────────────────────────────────┐
│ BI Dashboard System │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ LOCAL MODE CLOUD MODE │
│ ────────── ────────── │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ /bi │ │ /bi --share │ │
│ │ (Vite Dev) │ │ (Cloud Deploy) │ │
│ └──────┬──────┘ └────────┬────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ localhost │ │ Cloud Run/GKE │ │
│ │ :5174 │ │ Service │ │
│ └─────────────┘ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Dynamic Page │ │
│ │ Generator │ │
│ └────────┬────────┘ │
│ │ │
│ ┌──────────────────────┼──────────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌────────┐ │
│ │ Short-lived │ │ Shareable │ │ Alert │ │
│ │ URL Token │ │ URL │ │ System │ │
│ └─────────────┘ └─────────────┘ └────┬───┘ │
│ │ │
│ ┌───────────────────┤ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐│
│ │ Slack │ │ MS Teams ││
│ │ Integration │ │ Integration││
│ └─────────────┘ └─────────────┘│
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────┐ │
│ │ Email Notification Service │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
Command Structure
# Local mode (existing)
/bi # Launch local dashboard
/bi --view kanban # Open specific view
/bi --export markdown # Export report
# Cloud mode (new)
/bi --share # Deploy to Cloud Run, get shareable URL
/bi --share --view overview # Share specific view
/bi --share --expires 24h # Auto-expire after 24 hours
/bi --share --team dev-team # Notify team channel
/bi --share --slack #reports # Post URL to Slack channel
/bi --share --teams @project # Post to Teams channel
/bi --share --email user@co # Email report link
# Page management
/bi --list-pages # List active shared pages
/bi --revoke <page-id> # Revoke access to shared page
/bi --extend <page-id> 24h # Extend page expiration
Cloud Run Deployment
# bi-dashboard-service.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: bi-dashboard
annotations:
run.googleapis.com/ingress: internal-and-cloud-load-balancing
run.googleapis.com/execution-environment: gen2
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/minScale: '0'
autoscaling.knative.dev/maxScale: '10'
run.googleapis.com/startup-cpu-boost: 'true'
spec:
containerConcurrency: 80
timeoutSeconds: 300
containers:
- image: gcr.io/coditect-prod/bi-dashboard:latest
ports:
- containerPort: 8080
resources:
limits:
cpu: '1'
memory: '512Mi'
env:
- name: NODE_ENV
value: production
- name: BI_MODE
value: cloud
Page Generation Flow
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ /bi │ │ Generate │ │ Store │
│ --share │────▶│ Page ID │────▶│ in Redis │
└──────────────┘ └──────────────┘ └──────────────┘
│
▼
┌──────────────┐ ┌──────────────┐
│ Return │◀────│ Deploy │
│ URL │ │ Container │
└──────────────┘ └──────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Slack Post │ │ Teams Post │ │ Email Send │
└─────────────┘ └─────────────┘ └─────────────┘
URL Structure
# Pattern
https://bi.coditect.ai/p/<page-id>?token=<access-token>
# Examples
https://bi.coditect.ai/p/a1b2c3d4/overview
https://bi.coditect.ai/p/a1b2c3d4/kanban?track=J
https://bi.coditect.ai/p/a1b2c3d4/report?format=pdf
Access Control
| Level | Access | Duration | Revocable |
|---|---|---|---|
| Public | Anyone with URL | Time-limited | Yes |
| Team | Team members only | Session-based | Yes |
| User | Specific users | Permanent | Yes |
| Admin | Full access | Permanent | No |
Communication Integration
Slack Integration:
# Webhook payload
{
"channel": "#bi-reports",
"text": "New BI Dashboard report available",
"attachments": [{
"title": "CODITECT Project Status",
"title_link": "https://bi.coditect.ai/p/a1b2c3d4",
"fields": [
{"title": "Overall Progress", "value": "61%", "short": true},
{"title": "Active Tracks", "value": "14", "short": true}
],
"color": "#6366f1",
"footer": "Expires in 24 hours"
}]
}
Teams Integration:
# Adaptive Card payload
{
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.4",
"body": [
{"type": "TextBlock", "text": "CODITECT BI Report", "size": "Large"},
{"type": "FactSet", "facts": [
{"title": "Progress", "value": "61%"},
{"title": "Tracks", "value": "14"}
]}
],
"actions": [{
"type": "Action.OpenUrl",
"title": "View Dashboard",
"url": "https://bi.coditect.ai/p/a1b2c3d4"
}]
}
Data Flow
LOCAL DATA CLOUD SERVICE CLIENTS
────────── ───────────── ───────
│
sessions.db ─────────────────────▶ │
org.db ──────────────────────────▶ │ ◀───── Browser
platform.db ─────────────────────▶ │ ◀───── Mobile
TRACK files ─────────────────────▶ │ ◀───── API
│
Upload via │ Access via
/bi --share │ shareable URL
Alternatives Considered
1. Always-On GKE Deployment
Pros:
- Instant availability
- No cold start
Cons:
- Higher cost (~$70/month minimum)
- Unnecessary for infrequent access
Decision: Rejected - Cloud Run scale-to-zero is more cost-effective
2. Static Site Generation
Pros:
- Very low cost (GCS hosting)
- No server needed
Cons:
- No real-time data
- No interactive features (Kanban drag-drop)
Decision: Rejected - Need interactivity
3. Embeddable Widgets Only
Pros:
- Easy integration
- Low resource usage
Cons:
- Limited functionality
- Requires parent application
Decision: Partial - Will add as Phase 2 feature
Consequences
Positive
- Cost-Effective Sharing - Pay only for active usage
- Team Collaboration - Share insights across teams easily
- Multi-Channel Alerts - Reach team via preferred communication
- Security - Time-limited, revocable access tokens
- Audit Trail - Full logging of access and actions
Negative
- Cold Start Latency - ~1-2 seconds on first access
- Data Sync Complexity - Need to push local data to cloud
- Dependency - Requires GCP infrastructure
Neutral
- URL Management - Need to track active pages
- Notification Preferences - Users must configure integrations
Implementation Plan
Phase 1: Cloud Deployment (J.17.5)
- J.17.5.1: Create Dockerfile for BI dashboard
- J.17.5.2: Create Cloud Run service configuration
- J.17.5.3: Implement page ID generation
- J.17.5.4: Create shareable URL routing
- J.17.5.5: Add
--shareflag to /bi command
Phase 2: Communication Integration (J.17.6)
- J.17.6.1: Implement Slack webhook integration
- J.17.6.2: Implement MS Teams webhook integration
- J.17.6.3: Implement email notification service
- J.17.6.4: Create notification preferences UI
Phase 3: Access Control (J.17.7)
- J.17.7.1: Implement JWT-based access tokens
- J.17.7.2: Create page management UI
- J.17.7.3: Implement role-based access control
- J.17.7.4: Add audit logging
Phase 4: Advanced Features (J.17.8)
- J.17.8.1: Embeddable widget generation
- J.17.8.2: Scheduled report generation
- J.17.8.3: Custom branding per tenant
- J.17.8.4: PDF generation service
Related ADRs
| ADR | Relationship |
|---|---|
| ADR-130 | Local BI dashboard (foundation) |
| ADR-053 | Multi-tenant cloud sync |
| ADR-118 | Four-tier database architecture |
| ADR-010 | GKE infrastructure |
| ADR-125 | Centralized logging |
References
Author: senior-architect Reviewers: devops-engineer, security-specialist Status: Proposed - Pending Review