Skip to main content

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:

  1. On-Demand Cloud Deployment - Launch shareable BI pages on GKE/Cloud Run
  2. Team Collaboration - Share dashboards across teams with role-based access
  3. Communication Integration - Push alerts and links to Slack, Teams, Email
  4. Dynamic Page Generation - Create temporary pages for specific views/reports
  5. Cost Optimization - Serverless architecture with scale-to-zero

Requirements

RequirementPriorityRationale
On-demand page generationP1Share specific views without always-on servers
Shareable URLsP1Team collaboration across locations
Communication channel integrationP1Alert teams when reports are ready
Role-based access controlP1Restrict sensitive data to authorized users
Auto-expire pagesP2Cost optimization, data freshness
Mobile-friendlyP2Access from any device
Audit loggingP2Compliance, usage tracking

Constraints

  1. Must integrate with existing multi-tenant architecture (ADR-053)
  2. Must support offline-first local mode (ADR-130)
  3. Must comply with HIPAA/SOC2 requirements
  4. 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

LevelAccessDurationRevocable
PublicAnyone with URLTime-limitedYes
TeamTeam members onlySession-basedYes
UserSpecific usersPermanentYes
AdminFull accessPermanentNo

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

  1. Cost-Effective Sharing - Pay only for active usage
  2. Team Collaboration - Share insights across teams easily
  3. Multi-Channel Alerts - Reach team via preferred communication
  4. Security - Time-limited, revocable access tokens
  5. Audit Trail - Full logging of access and actions

Negative

  1. Cold Start Latency - ~1-2 seconds on first access
  2. Data Sync Complexity - Need to push local data to cloud
  3. Dependency - Requires GCP infrastructure

Neutral

  1. URL Management - Need to track active pages
  2. 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 --share flag 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
ADRRelationship
ADR-130Local BI dashboard (foundation)
ADR-053Multi-tenant cloud sync
ADR-118Four-tier database architecture
ADR-010GKE infrastructure
ADR-125Centralized logging

References


Author: senior-architect Reviewers: devops-engineer, security-specialist Status: Proposed - Pending Review