Dashloom architecture
This document describes the implemented product architecture and the boundaries that new connectors, skills, and commercial features must preserve.
This document describes the implemented product architecture and the boundaries that new connectors, skills, and commercial features must preserve.
Dependency direction
Marketing and product UI
↓
Server routes and actions
↓
Workspace domain services
↓
Evidence builder and deterministic analytics
↓
Agent / workflow orchestration
↓
D1 repositories, provider adapters, and delivery adapters
The browser must not decide workspace authorization, decrypt credentials, accept provider callbacks as trusted, or grant paid entitlements.
Current data ownership
| Data | Owner | Boundary |
|---|---|---|
| Workspace configuration | workspaces | Owner, locale, timezone, and plan |
| Workspace brand | workspace_branding | Runtime brand name, HTTPS assets, accent, support link, and attribution policy |
| Team access | workspace_members | A user role inside one workspace |
| Product catalog | products | Every product belongs to one workspace |
| External connections | connector_accounts | Provider account and encrypted server credential |
| Resource mapping | product_connector_mappings | Maps an external resource to one product |
| Time-series values | metric_points | Workspace and product scoped metric identity |
| Calculated metrics | calculated_metric_definitions | Workspace formula definitions materialized as normalized points |
| Competitor facts | competitors, competitor_metric_points | Approved external entities, metrics, and provenance |
| Collection state | sync_runs | Observable, retryable provider synchronization |
| AI connection | ai_provider_accounts | BYOK or managed provider configuration; secrets remain server-side |
| Dashboard preset | dashboard_views | Workspace views over shared normalized data |
| Agent configuration | agent_profiles | Role, provider, permissions, and structured instructions |
| Agent conversations | agent_conversations | Workspace-scoped thread identity, specialist, lifecycle, and creator |
| Analysis execution | analysis_runs | Evidence, lifecycle, findings, tokens, and errors |
| Model comparisons | agent_comparison_runs, agent_comparison_results | Frozen evidence, prompt version, provider snapshots, validated findings, and deterministic statistics |
| AI usage | ai_usage_events | Append-only, idempotent usage and estimated cost ledger |
| Generated report | reports | Evidence-derived daily, weekly, monthly, or manual output with preserved portfolio/product scope |
| Delivery | delivery_channels, report_deliveries | Encrypted channel configuration and retryable delivery state |
| Client portals | agency_clients, agency_client_products, agency_share_links | Explicit product scope and hashed expiring access tokens |
| Extensions | ingestion_api_keys, agent_skill_manifests | Hashed write-only tokens and versioned analysis guidance |
| Automation | sync_schedules, report_schedules, alert_rules | Claimed jobs, locked product scope, retry state, cooldowns, and plan limits |
| Product feedback | feedback_submissions | Workspace-owned messages and optional strict anonymous diagnostics |
| Billing | billing_customers, billing_subscriptions, billing_webhook_events | Provider-signed subscription truth and idempotent events |
Better Auth owns user, session, verification, password reset, and authentication account records. Dashloom stores stable user identifiers in workspace ownership, membership, invitations, audit events, and administrator-created resources.
Connector contract
Every provider connector must implement:
- Minimal documented permissions.
- Server-side credential storage and encryption.
- Resource discovery without silently granting access.
- Explicit mapping from provider resource to Dashloom product.
- Idempotent collection and metric upserts.
- Retryable errors with stable error codes.
- Connection health, last successful sync, and user-actionable recovery.
- Tests for invalid credentials, revoked access, limits, partial results, and retries.
The normalized ingestion API is the public extension boundary for additional connectors. Its tokens are write-only, hashed at rest, and revocable. Product-scoped tokens are the default for single-product senders; workspace-scoped tokens remain available for trusted multi-product pipelines. Deleting a product cascades its scoped tokens instead of widening their authority.
The Custom REST pull boundary accepts only a fixed versioned metric contract over public HTTPS GET. It validates DNS before each request, blocks private and reserved destinations, rejects redirects and URL credentials, bounds time and response size, and encrypts optional Bearer or custom-header credentials. Remote payloads provide normalized evidence only; they cannot supply code, queries, transformations, or Agent instructions.
Analysis boundary
Dashloom calculates revenue, growth rates, comparisons, anomalies, data-quality facts, product health scores, administrator-defined arithmetic metrics, competitor-period trends, and bounded cross-domain co-movement in deterministic server modules before invoking an LLM. Health combines freshness, runtime errors, commercial or acquisition decline, and source coverage. Metric semantics are explicit: flow metrics are summed, stock metrics such as MRR use the latest period value, and ratios are averaged. Calculated metrics are aligned by product, date, and currency, reject unsafe unit combinations, cannot form dependency cycles, and are materialized through the normalized metric boundary. Co-movement is explicitly non-causal evidence and may only support a labeled hypothesis. The model receives a bounded evidence bundle and returns structured findings; it does not query arbitrary workspace tables or redefine metric truth. Every material finding must reference an evidence identifier present in that frozen bundle. Server-side validation rejects missing or unknown citations before the result is stored, and the tenant-scoped audit route renders the cited snapshot for later review.
Every important finding must retain source, entity, metric, period, freshness, and calculation provenance. Imported provider content is untrusted data and cannot override system instructions or grant tools permission.
Short conversational turns run through a workspace-isolated Agent thread that is locked to either the full portfolio or one real product. Product scope filters first-party metrics, goals, linked competitors, Growth Missions, and report action digests before evidence reaches the model. The same scope is persisted through alert explanations, manual reports, schedules, Executive Briefs, generated reports, and delivery retries. Deleting a product invalidates historical scope labels and cascades future schedules instead of widening either one. A follow-up receives at most four prior question, summary, and action snippets; raw historical evidence and historical citation identifiers are excluded. The server rebuilds current scoped evidence for every turn, and only identifiers from that new frozen bundle can validate the answer. Agent Skill manifests remain subordinate to these evidence and safety rules.
Agent Quality Lab comparisons freeze one evidence bundle, prompt version, and Skill snapshot before calling two to four selected providers in parallel. Only contract-valid and citation-valid results are retained. The comparison layer calculates evidence-reference overlap, finding counts, latency, and token use deterministically; model-reported confidence remains explicitly labeled and is not treated as an objective quality score.
AI provider and entitlement boundary
- Community deployments may configure an OpenAI-compatible endpoint, model, and encrypted API key.
- Custom endpoints must pass server-side HTTPS and outbound-network validation; redirects, DNS resolution, and private address ranges are checked to prevent SSRF.
- Managed Cloud credentials never enter the browser and are separate from BYOK records.
- Plan allowances come from a server-owned catalog.
- Each managed or BYOK call records an append-only usage event.
- A browser-displayed remaining balance is informational, not authorization to spend.
- Failed or duplicate runs must not consume a managed allowance twice.
Multi-tenant invariant
Every query and mutation involving products, connectors, metrics, or sync runs must resolve a trusted server-side workspace membership before accessing data. A workspace ID supplied by the browser is a selector, not proof of authorization.
Operational invariants
- A scheduled job is claimed by conditional update before provider work starts.
- Report, alert, billing, and AI-usage side effects have stable idempotency keys.
- Browser redirects never grant subscription entitlements; verified Stripe events do.
- Data retention never deletes billing, membership, or audit history.
- Production schema changes are complete only after migrations are applied to the intended remote D1 database and the resulting schema is verified.