@useatlas/create 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -18
- package/index.ts +191 -31
- package/package.json +1 -1
- package/templates/docker/.env.example +3 -3
- package/templates/docker/Dockerfile.sidecar +28 -0
- package/templates/docker/bin/__tests__/plugin-cli.test.ts +9 -9
- package/templates/docker/bin/atlas.ts +108 -44
- package/templates/docker/data/demo-semantic/catalog.yml +51 -27
- package/templates/docker/data/demo-semantic/entities/accounts.yml +95 -103
- package/templates/docker/data/demo-semantic/entities/companies.yml +88 -152
- package/templates/docker/data/demo-semantic/entities/people.yml +82 -95
- package/templates/docker/data/demo-semantic/glossary.yml +104 -8
- package/templates/docker/data/demo-semantic/metrics/accounts.yml +62 -23
- package/templates/docker/data/demo-semantic/metrics/companies.yml +52 -78
- package/templates/docker/docker-compose.yml +1 -1
- package/templates/docker/docs/deploy.md +2 -39
- package/templates/docker/package.json +17 -1
- package/templates/docker/semantic/catalog.yml +62 -3
- package/templates/docker/semantic/entities/accounts.yml +162 -0
- package/templates/docker/semantic/entities/companies.yml +143 -0
- package/templates/docker/semantic/entities/people.yml +132 -0
- package/templates/docker/semantic/glossary.yml +116 -4
- package/templates/docker/semantic/metrics/accounts.yml +77 -0
- package/templates/docker/semantic/metrics/companies.yml +63 -0
- package/templates/docker/sidecar/Dockerfile +5 -6
- package/templates/docker/sidecar/railway.json +1 -2
- package/templates/docker/src/api/__tests__/admin.test.ts +7 -7
- package/templates/docker/src/api/__tests__/health-plugin.test.ts +7 -0
- package/templates/docker/src/api/__tests__/health.test.ts +30 -8
- package/templates/docker/src/api/routes/admin.ts +549 -8
- package/templates/docker/src/api/routes/chat.ts +5 -20
- package/templates/docker/src/api/routes/health.ts +39 -27
- package/templates/docker/src/api/routes/openapi.ts +1329 -74
- package/templates/docker/src/api/routes/query.ts +2 -1
- package/templates/docker/src/api/server.ts +27 -0
- package/templates/docker/src/app/api/[...route]/route.ts +2 -2
- package/templates/docker/src/app/globals.css +13 -12
- package/templates/docker/src/app/layout.tsx +9 -2
- package/templates/docker/src/components/ui/alert-dialog.tsx +196 -0
- package/templates/docker/src/components/ui/badge.tsx +48 -0
- package/templates/docker/src/components/ui/button.tsx +64 -0
- package/templates/docker/src/components/ui/card.tsx +92 -0
- package/templates/docker/src/components/ui/collapsible.tsx +33 -0
- package/templates/docker/src/components/ui/command.tsx +184 -0
- package/templates/docker/src/components/ui/dialog.tsx +158 -0
- package/templates/docker/src/components/ui/dropdown-menu.tsx +257 -0
- package/templates/docker/src/components/ui/input.tsx +21 -0
- package/templates/docker/src/components/ui/scroll-area.tsx +58 -0
- package/templates/docker/src/components/ui/select.tsx +190 -0
- package/templates/docker/src/components/ui/separator.tsx +28 -0
- package/templates/docker/src/components/ui/sheet.tsx +143 -0
- package/templates/docker/src/components/ui/sidebar.tsx +726 -0
- package/templates/docker/src/components/ui/skeleton.tsx +13 -0
- package/templates/docker/src/components/ui/table.tsx +116 -0
- package/templates/docker/src/components/ui/tabs.tsx +91 -0
- package/templates/docker/src/components/ui/toggle-group.tsx +83 -0
- package/templates/docker/src/components/ui/toggle.tsx +47 -0
- package/templates/docker/src/components/ui/tooltip.tsx +57 -0
- package/templates/docker/src/hooks/use-mobile.ts +19 -0
- package/templates/docker/src/lib/__tests__/agent-cache.test.ts +2 -0
- package/templates/docker/src/lib/__tests__/agent-dialect.test.ts +17 -0
- package/templates/docker/src/lib/__tests__/agent-health-annotations.test.ts +2 -0
- package/templates/docker/src/lib/__tests__/agent-integration.test.ts +2 -0
- package/templates/docker/src/lib/__tests__/config.test.ts +69 -19
- package/templates/docker/src/lib/__tests__/plugin-aware-validation.test.ts +321 -0
- package/templates/docker/src/lib/__tests__/providers.test.ts +32 -1
- package/templates/docker/src/lib/__tests__/startup-actions.test.ts +9 -0
- package/templates/docker/src/lib/__tests__/startup-first-run.test.ts +429 -0
- package/templates/docker/src/lib/__tests__/startup.test.ts +5 -0
- package/templates/docker/src/lib/agent-query.ts +5 -23
- package/templates/docker/src/lib/agent.ts +32 -112
- package/templates/docker/src/lib/auth/__tests__/migrate.test.ts +5 -3
- package/templates/docker/src/lib/auth/middleware.ts +30 -4
- package/templates/docker/src/lib/auth/migrate.ts +97 -0
- package/templates/docker/src/lib/auth/server.ts +12 -1
- package/templates/docker/src/lib/config.ts +37 -39
- package/templates/docker/src/lib/db/__tests__/connection.test.ts +89 -14
- package/templates/docker/src/lib/db/__tests__/registry-health.test.ts +1 -18
- package/templates/docker/src/lib/db/__tests__/registry-pool-limits.test.ts +0 -19
- package/templates/docker/src/lib/db/__tests__/registry.test.ts +11 -208
- package/templates/docker/src/lib/db/connection.ts +87 -265
- package/templates/docker/src/lib/db/internal.ts +6 -1
- package/templates/docker/src/lib/plugins/__tests__/hooks-integration.test.ts +3 -1
- package/templates/docker/src/lib/plugins/__tests__/hooks.test.ts +2 -2
- package/templates/docker/src/lib/plugins/__tests__/migrate.test.ts +355 -1
- package/templates/docker/src/lib/plugins/__tests__/registry.test.ts +32 -5
- package/templates/docker/src/lib/plugins/__tests__/wiring.test.ts +228 -14
- package/templates/docker/src/lib/plugins/index.ts +4 -1
- package/templates/docker/src/lib/plugins/migrate.ts +103 -0
- package/templates/docker/src/lib/plugins/registry.ts +12 -6
- package/templates/docker/src/lib/plugins/wiring.ts +113 -4
- package/templates/docker/src/lib/providers.ts +6 -1
- package/templates/docker/src/lib/security.ts +24 -0
- package/templates/docker/src/lib/semantic.ts +2 -0
- package/templates/docker/src/lib/sidecar-types.ts +12 -1
- package/templates/docker/src/lib/startup.ts +71 -101
- package/templates/docker/src/lib/tools/__tests__/custom-validation.test.ts +2 -0
- package/templates/docker/src/lib/tools/__tests__/explore-nsjail.test.ts +32 -18
- package/templates/docker/src/lib/tools/__tests__/explore-plugin.test.ts +14 -14
- package/templates/docker/src/lib/tools/__tests__/explore-sidecar.test.ts +5 -3
- package/templates/docker/src/lib/tools/__tests__/python-nsjail.test.ts +515 -0
- package/templates/docker/src/lib/tools/__tests__/python-sandbox.test.ts +397 -0
- package/templates/docker/src/lib/tools/__tests__/python-sidecar.test.ts +365 -0
- package/templates/docker/src/lib/tools/__tests__/python.test.ts +331 -0
- package/templates/docker/src/lib/tools/__tests__/registry-actions.test.ts +1 -13
- package/templates/docker/src/lib/tools/__tests__/registry.test.ts +38 -31
- package/templates/docker/src/lib/tools/__tests__/sql-audit.test.ts +2 -0
- package/templates/docker/src/lib/tools/__tests__/sql-connection-whitelist.test.ts +2 -0
- package/templates/docker/src/lib/tools/__tests__/sql-ratelimit.test.ts +2 -0
- package/templates/docker/src/lib/tools/__tests__/sql.test.ts +5 -308
- package/templates/docker/src/lib/tools/explore-nsjail.ts +17 -12
- package/templates/docker/src/lib/tools/explore-sidecar.ts +25 -0
- package/templates/docker/src/lib/tools/explore.ts +28 -32
- package/templates/docker/src/lib/tools/python-nsjail.ts +396 -0
- package/templates/docker/src/lib/tools/python-sandbox.ts +476 -0
- package/templates/docker/src/lib/tools/python-sidecar.ts +150 -0
- package/templates/docker/src/lib/tools/python.ts +367 -0
- package/templates/docker/src/lib/tools/registry.ts +49 -22
- package/templates/docker/src/lib/tools/sql.ts +88 -88
- package/templates/docker/src/types/vercel-sandbox.d.ts +7 -0
- package/templates/docker/src/ui/components/admin/admin-layout.tsx +77 -8
- package/templates/docker/src/ui/components/admin/admin-sidebar.tsx +25 -17
- package/templates/docker/src/ui/components/admin/change-password-dialog.tsx +128 -0
- package/templates/docker/src/ui/components/admin/entity-detail.tsx +3 -3
- package/templates/docker/src/ui/components/admin/semantic-file-tree.tsx +159 -0
- package/templates/docker/src/ui/components/atlas-chat.tsx +64 -12
- package/templates/docker/src/ui/components/chart/result-chart.tsx +25 -15
- package/templates/docker/src/ui/components/chat/markdown.tsx +88 -42
- package/templates/docker/src/ui/components/chat/python-result-card.tsx +244 -0
- package/templates/docker/src/ui/components/chat/sql-block.tsx +39 -15
- package/templates/docker/src/ui/components/chat/sql-result-card.tsx +6 -1
- package/templates/docker/src/ui/components/chat/tool-part.tsx +12 -3
- package/templates/docker/src/ui/components/chat/typing-indicator.tsx +5 -2
- package/templates/docker/src/ui/components/conversations/conversation-item.tsx +25 -20
- package/templates/docker/src/ui/context.tsx +1 -1
- package/templates/docker/src/ui/hooks/use-conversations.ts +3 -3
- package/templates/docker/src/ui/hooks/use-dark-mode.ts +17 -10
- package/templates/docker/tsconfig.json +2 -2
- package/templates/nextjs-standalone/.env.example +1 -1
- package/templates/nextjs-standalone/bin/__tests__/plugin-cli.test.ts +9 -9
- package/templates/nextjs-standalone/bin/atlas.ts +108 -44
- package/templates/nextjs-standalone/data/demo-semantic/catalog.yml +51 -27
- package/templates/nextjs-standalone/data/demo-semantic/entities/accounts.yml +95 -103
- package/templates/nextjs-standalone/data/demo-semantic/entities/companies.yml +88 -152
- package/templates/nextjs-standalone/data/demo-semantic/entities/people.yml +82 -95
- package/templates/nextjs-standalone/data/demo-semantic/glossary.yml +104 -8
- package/templates/nextjs-standalone/data/demo-semantic/metrics/accounts.yml +62 -23
- package/templates/nextjs-standalone/data/demo-semantic/metrics/companies.yml +52 -78
- package/templates/nextjs-standalone/docs/deploy.md +2 -39
- package/templates/nextjs-standalone/package.json +11 -2
- package/templates/nextjs-standalone/scripts/migrate-auth.ts +25 -0
- package/templates/nextjs-standalone/scripts/seed-demo.ts +94 -0
- package/templates/nextjs-standalone/semantic/catalog.yml +62 -3
- package/templates/nextjs-standalone/semantic/entities/accounts.yml +162 -0
- package/templates/nextjs-standalone/semantic/entities/companies.yml +143 -0
- package/templates/nextjs-standalone/semantic/entities/people.yml +132 -0
- package/templates/nextjs-standalone/semantic/glossary.yml +116 -4
- package/templates/nextjs-standalone/semantic/metrics/accounts.yml +77 -0
- package/templates/nextjs-standalone/semantic/metrics/companies.yml +63 -0
- package/templates/nextjs-standalone/src/api/__tests__/admin.test.ts +7 -7
- package/templates/nextjs-standalone/src/api/__tests__/health-plugin.test.ts +7 -0
- package/templates/nextjs-standalone/src/api/__tests__/health.test.ts +30 -8
- package/templates/nextjs-standalone/src/api/routes/admin.ts +549 -8
- package/templates/nextjs-standalone/src/api/routes/chat.ts +5 -20
- package/templates/nextjs-standalone/src/api/routes/health.ts +39 -27
- package/templates/nextjs-standalone/src/api/routes/openapi.ts +1329 -74
- package/templates/nextjs-standalone/src/api/routes/query.ts +2 -1
- package/templates/nextjs-standalone/src/api/server.ts +27 -0
- package/templates/nextjs-standalone/src/app/api/[...route]/route.ts +2 -2
- package/templates/nextjs-standalone/src/app/globals.css +13 -12
- package/templates/nextjs-standalone/src/app/layout.tsx +9 -2
- package/templates/nextjs-standalone/src/components/ui/alert-dialog.tsx +196 -0
- package/templates/nextjs-standalone/src/components/ui/badge.tsx +48 -0
- package/templates/nextjs-standalone/src/components/ui/button.tsx +64 -0
- package/templates/nextjs-standalone/src/components/ui/card.tsx +92 -0
- package/templates/nextjs-standalone/src/components/ui/collapsible.tsx +33 -0
- package/templates/nextjs-standalone/src/components/ui/command.tsx +184 -0
- package/templates/nextjs-standalone/src/components/ui/dialog.tsx +158 -0
- package/templates/nextjs-standalone/src/components/ui/dropdown-menu.tsx +257 -0
- package/templates/nextjs-standalone/src/components/ui/input.tsx +21 -0
- package/templates/nextjs-standalone/src/components/ui/scroll-area.tsx +58 -0
- package/templates/nextjs-standalone/src/components/ui/select.tsx +190 -0
- package/templates/nextjs-standalone/src/components/ui/separator.tsx +28 -0
- package/templates/nextjs-standalone/src/components/ui/sheet.tsx +143 -0
- package/templates/nextjs-standalone/src/components/ui/sidebar.tsx +726 -0
- package/templates/nextjs-standalone/src/components/ui/skeleton.tsx +13 -0
- package/templates/nextjs-standalone/src/components/ui/table.tsx +116 -0
- package/templates/nextjs-standalone/src/components/ui/tabs.tsx +91 -0
- package/templates/nextjs-standalone/src/components/ui/toggle-group.tsx +83 -0
- package/templates/nextjs-standalone/src/components/ui/toggle.tsx +47 -0
- package/templates/nextjs-standalone/src/components/ui/tooltip.tsx +57 -0
- package/templates/nextjs-standalone/src/hooks/use-mobile.ts +19 -0
- package/templates/nextjs-standalone/src/lib/__tests__/agent-cache.test.ts +2 -0
- package/templates/nextjs-standalone/src/lib/__tests__/agent-dialect.test.ts +17 -0
- package/templates/nextjs-standalone/src/lib/__tests__/agent-health-annotations.test.ts +2 -0
- package/templates/nextjs-standalone/src/lib/__tests__/agent-integration.test.ts +2 -0
- package/templates/nextjs-standalone/src/lib/__tests__/config.test.ts +69 -19
- package/templates/nextjs-standalone/src/lib/__tests__/plugin-aware-validation.test.ts +321 -0
- package/templates/nextjs-standalone/src/lib/__tests__/providers.test.ts +32 -1
- package/templates/nextjs-standalone/src/lib/__tests__/startup-actions.test.ts +9 -0
- package/templates/nextjs-standalone/src/lib/__tests__/startup-first-run.test.ts +429 -0
- package/templates/nextjs-standalone/src/lib/__tests__/startup.test.ts +5 -0
- package/templates/nextjs-standalone/src/lib/agent-query.ts +5 -23
- package/templates/nextjs-standalone/src/lib/agent.ts +32 -112
- package/templates/nextjs-standalone/src/lib/auth/__tests__/migrate.test.ts +5 -3
- package/templates/nextjs-standalone/src/lib/auth/middleware.ts +30 -4
- package/templates/nextjs-standalone/src/lib/auth/migrate.ts +97 -0
- package/templates/nextjs-standalone/src/lib/auth/server.ts +12 -1
- package/templates/nextjs-standalone/src/lib/config.ts +37 -39
- package/templates/nextjs-standalone/src/lib/db/__tests__/connection.test.ts +89 -14
- package/templates/nextjs-standalone/src/lib/db/__tests__/registry-health.test.ts +1 -18
- package/templates/nextjs-standalone/src/lib/db/__tests__/registry-pool-limits.test.ts +0 -19
- package/templates/nextjs-standalone/src/lib/db/__tests__/registry.test.ts +11 -208
- package/templates/nextjs-standalone/src/lib/db/connection.ts +87 -265
- package/templates/nextjs-standalone/src/lib/db/internal.ts +6 -1
- package/templates/nextjs-standalone/src/lib/plugins/__tests__/hooks-integration.test.ts +3 -1
- package/templates/nextjs-standalone/src/lib/plugins/__tests__/hooks.test.ts +2 -2
- package/templates/nextjs-standalone/src/lib/plugins/__tests__/migrate.test.ts +355 -1
- package/templates/nextjs-standalone/src/lib/plugins/__tests__/registry.test.ts +32 -5
- package/templates/nextjs-standalone/src/lib/plugins/__tests__/wiring.test.ts +228 -14
- package/templates/nextjs-standalone/src/lib/plugins/index.ts +4 -1
- package/templates/nextjs-standalone/src/lib/plugins/migrate.ts +103 -0
- package/templates/nextjs-standalone/src/lib/plugins/registry.ts +12 -6
- package/templates/nextjs-standalone/src/lib/plugins/wiring.ts +113 -4
- package/templates/nextjs-standalone/src/lib/providers.ts +6 -1
- package/templates/nextjs-standalone/src/lib/security.ts +24 -0
- package/templates/nextjs-standalone/src/lib/semantic.ts +2 -0
- package/templates/nextjs-standalone/src/lib/sidecar-types.ts +12 -1
- package/templates/nextjs-standalone/src/lib/startup.ts +71 -101
- package/templates/nextjs-standalone/src/lib/tools/__tests__/custom-validation.test.ts +2 -0
- package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-nsjail.test.ts +32 -18
- package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-plugin.test.ts +14 -14
- package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-sidecar.test.ts +5 -3
- package/templates/nextjs-standalone/src/lib/tools/__tests__/python-nsjail.test.ts +515 -0
- package/templates/nextjs-standalone/src/lib/tools/__tests__/python-sandbox.test.ts +397 -0
- package/templates/nextjs-standalone/src/lib/tools/__tests__/python-sidecar.test.ts +365 -0
- package/templates/nextjs-standalone/src/lib/tools/__tests__/python.test.ts +331 -0
- package/templates/nextjs-standalone/src/lib/tools/__tests__/registry-actions.test.ts +1 -13
- package/templates/nextjs-standalone/src/lib/tools/__tests__/registry.test.ts +38 -31
- package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-audit.test.ts +2 -0
- package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-connection-whitelist.test.ts +2 -0
- package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-ratelimit.test.ts +2 -0
- package/templates/nextjs-standalone/src/lib/tools/__tests__/sql.test.ts +5 -308
- package/templates/nextjs-standalone/src/lib/tools/explore-nsjail.ts +17 -12
- package/templates/nextjs-standalone/src/lib/tools/explore-sidecar.ts +25 -0
- package/templates/nextjs-standalone/src/lib/tools/explore.ts +28 -32
- package/templates/nextjs-standalone/src/lib/tools/python-nsjail.ts +396 -0
- package/templates/nextjs-standalone/src/lib/tools/python-sandbox.ts +476 -0
- package/templates/nextjs-standalone/src/lib/tools/python-sidecar.ts +150 -0
- package/templates/nextjs-standalone/src/lib/tools/python.ts +367 -0
- package/templates/nextjs-standalone/src/lib/tools/registry.ts +49 -22
- package/templates/nextjs-standalone/src/lib/tools/sql.ts +88 -88
- package/templates/nextjs-standalone/src/ui/components/admin/admin-layout.tsx +77 -8
- package/templates/nextjs-standalone/src/ui/components/admin/admin-sidebar.tsx +25 -17
- package/templates/nextjs-standalone/src/ui/components/admin/change-password-dialog.tsx +128 -0
- package/templates/nextjs-standalone/src/ui/components/admin/entity-detail.tsx +3 -3
- package/templates/nextjs-standalone/src/ui/components/admin/semantic-file-tree.tsx +159 -0
- package/templates/nextjs-standalone/src/ui/components/atlas-chat.tsx +64 -12
- package/templates/nextjs-standalone/src/ui/components/chart/result-chart.tsx +25 -15
- package/templates/nextjs-standalone/src/ui/components/chat/markdown.tsx +88 -42
- package/templates/nextjs-standalone/src/ui/components/chat/python-result-card.tsx +244 -0
- package/templates/nextjs-standalone/src/ui/components/chat/sql-block.tsx +39 -15
- package/templates/nextjs-standalone/src/ui/components/chat/sql-result-card.tsx +6 -1
- package/templates/nextjs-standalone/src/ui/components/chat/tool-part.tsx +12 -3
- package/templates/nextjs-standalone/src/ui/components/chat/typing-indicator.tsx +5 -2
- package/templates/nextjs-standalone/src/ui/components/conversations/conversation-item.tsx +25 -20
- package/templates/nextjs-standalone/src/ui/context.tsx +1 -1
- package/templates/nextjs-standalone/src/ui/hooks/use-conversations.ts +3 -3
- package/templates/nextjs-standalone/src/ui/hooks/use-dark-mode.ts +17 -10
- package/templates/nextjs-standalone/tsconfig.json +0 -1
- package/templates/nextjs-standalone/vercel.json +4 -1
- package/templates/docker/render.yaml +0 -34
- package/templates/docker/semantic/entities/.gitkeep +0 -0
- package/templates/docker/semantic/metrics/.gitkeep +0 -0
- package/templates/docker/src/lib/db/__tests__/duckdb.test.ts +0 -141
- package/templates/docker/src/lib/db/__tests__/salesforce.test.ts +0 -339
- package/templates/docker/src/lib/db/__tests__/snowflake.test.ts +0 -217
- package/templates/docker/src/lib/db/duckdb.ts +0 -122
- package/templates/docker/src/lib/db/salesforce.ts +0 -342
- package/templates/docker/src/lib/tools/__tests__/salesforce-tool.test.ts +0 -154
- package/templates/docker/src/lib/tools/__tests__/soql-validation.test.ts +0 -303
- package/templates/docker/src/lib/tools/__tests__/sql-duckdb.test.ts +0 -233
- package/templates/docker/src/lib/tools/salesforce.ts +0 -138
- package/templates/docker/src/lib/tools/soql-validation.ts +0 -172
- package/templates/nextjs-standalone/semantic/entities/.gitkeep +0 -0
- package/templates/nextjs-standalone/semantic/metrics/.gitkeep +0 -0
- package/templates/nextjs-standalone/src/lib/db/__tests__/duckdb.test.ts +0 -141
- package/templates/nextjs-standalone/src/lib/db/__tests__/salesforce.test.ts +0 -339
- package/templates/nextjs-standalone/src/lib/db/__tests__/snowflake.test.ts +0 -217
- package/templates/nextjs-standalone/src/lib/db/duckdb.ts +0 -122
- package/templates/nextjs-standalone/src/lib/db/salesforce.ts +0 -342
- package/templates/nextjs-standalone/src/lib/tools/__tests__/salesforce-tool.test.ts +0 -154
- package/templates/nextjs-standalone/src/lib/tools/__tests__/soql-validation.test.ts +0 -303
- package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-duckdb.test.ts +0 -233
- package/templates/nextjs-standalone/src/lib/tools/salesforce.ts +0 -138
- package/templates/nextjs-standalone/src/lib/tools/soql-validation.ts +0 -172
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
metrics:
|
|
2
|
+
- id: total_mrr
|
|
3
|
+
label: Total MRR
|
|
4
|
+
description: Total Monthly Recurring Revenue across all active accounts.
|
|
5
|
+
type: atomic
|
|
6
|
+
unit: USD
|
|
7
|
+
source:
|
|
8
|
+
entity: Accounts
|
|
9
|
+
measure: total_mrr
|
|
10
|
+
sql: |-
|
|
11
|
+
SELECT SUM(monthly_value) AS total_mrr
|
|
12
|
+
FROM accounts
|
|
13
|
+
WHERE status = 'Active'
|
|
14
|
+
aggregation: sum
|
|
15
|
+
objective: maximize
|
|
16
|
+
|
|
17
|
+
- id: active_accounts
|
|
18
|
+
label: Active Accounts
|
|
19
|
+
description: Number of accounts with status = 'Active'.
|
|
20
|
+
type: atomic
|
|
21
|
+
sql: |-
|
|
22
|
+
SELECT COUNT(*) AS active_accounts
|
|
23
|
+
FROM accounts
|
|
24
|
+
WHERE status = 'Active'
|
|
25
|
+
aggregation: count
|
|
26
|
+
|
|
27
|
+
- id: arpa
|
|
28
|
+
label: ARPA (Avg Revenue Per Account)
|
|
29
|
+
description: Average MRR per active account.
|
|
30
|
+
type: derived
|
|
31
|
+
unit: USD
|
|
32
|
+
sql: |-
|
|
33
|
+
SELECT AVG(monthly_value) AS arpa
|
|
34
|
+
FROM accounts
|
|
35
|
+
WHERE status = 'Active'
|
|
36
|
+
aggregation: avg
|
|
37
|
+
|
|
38
|
+
- id: churn_rate
|
|
39
|
+
label: Churn Rate
|
|
40
|
+
description: Percentage of all accounts that have churned.
|
|
41
|
+
type: derived
|
|
42
|
+
unit: percent
|
|
43
|
+
sql: |-
|
|
44
|
+
SELECT ROUND(100.0 * COUNT(*) FILTER (WHERE status = 'Churned') / COUNT(*), 1) AS churn_rate
|
|
45
|
+
FROM accounts
|
|
46
|
+
aggregation: ratio
|
|
47
|
+
objective: minimize
|
|
48
|
+
|
|
49
|
+
- id: mrr_by_plan
|
|
50
|
+
label: MRR by Plan
|
|
51
|
+
description: MRR breakdown by subscription plan tier.
|
|
52
|
+
type: breakdown
|
|
53
|
+
unit: USD
|
|
54
|
+
sql: |-
|
|
55
|
+
SELECT plan,
|
|
56
|
+
SUM(monthly_value) AS total_mrr,
|
|
57
|
+
COUNT(*) AS account_count,
|
|
58
|
+
AVG(monthly_value) AS avg_mrr
|
|
59
|
+
FROM accounts
|
|
60
|
+
WHERE status = 'Active'
|
|
61
|
+
GROUP BY plan
|
|
62
|
+
ORDER BY total_mrr DESC
|
|
63
|
+
|
|
64
|
+
- id: churn_by_plan
|
|
65
|
+
label: Churn Rate by Plan
|
|
66
|
+
description: Churn rate broken down by plan tier.
|
|
67
|
+
type: breakdown
|
|
68
|
+
unit: percent
|
|
69
|
+
sql: |-
|
|
70
|
+
SELECT plan,
|
|
71
|
+
COUNT(*) FILTER (WHERE status = 'Churned') AS churned,
|
|
72
|
+
COUNT(*) AS total,
|
|
73
|
+
ROUND(100.0 * COUNT(*) FILTER (WHERE status = 'Churned') / COUNT(*), 1) AS churn_pct
|
|
74
|
+
FROM accounts
|
|
75
|
+
GROUP BY plan
|
|
76
|
+
ORDER BY churn_pct DESC
|
|
77
|
+
objective: minimize
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
metrics:
|
|
2
|
+
- id: total_customers
|
|
3
|
+
label: Total Customers
|
|
4
|
+
description: Number of unique customer companies.
|
|
5
|
+
type: atomic
|
|
6
|
+
sql: |-
|
|
7
|
+
SELECT COUNT(DISTINCT id) AS total_customers
|
|
8
|
+
FROM companies
|
|
9
|
+
aggregation: count_distinct
|
|
10
|
+
|
|
11
|
+
- id: avg_customer_revenue
|
|
12
|
+
label: Avg Customer Revenue
|
|
13
|
+
description: Average annual revenue across customer companies.
|
|
14
|
+
type: atomic
|
|
15
|
+
unit: USD
|
|
16
|
+
source:
|
|
17
|
+
entity: Companies
|
|
18
|
+
measure: avg_revenue
|
|
19
|
+
sql: |-
|
|
20
|
+
SELECT AVG(revenue) AS avg_customer_revenue
|
|
21
|
+
FROM companies
|
|
22
|
+
aggregation: avg
|
|
23
|
+
|
|
24
|
+
- id: customers_by_industry
|
|
25
|
+
label: Customers by Industry
|
|
26
|
+
description: Customer count and average revenue by industry vertical.
|
|
27
|
+
type: breakdown
|
|
28
|
+
sql: |-
|
|
29
|
+
SELECT industry,
|
|
30
|
+
COUNT(*) AS customer_count,
|
|
31
|
+
AVG(revenue) AS avg_revenue,
|
|
32
|
+
AVG(employee_count) AS avg_headcount
|
|
33
|
+
FROM companies
|
|
34
|
+
GROUP BY industry
|
|
35
|
+
ORDER BY customer_count DESC
|
|
36
|
+
|
|
37
|
+
- id: customers_by_country
|
|
38
|
+
label: Customers by Country
|
|
39
|
+
description: Customer distribution by HQ country.
|
|
40
|
+
type: breakdown
|
|
41
|
+
sql: |-
|
|
42
|
+
SELECT country,
|
|
43
|
+
COUNT(*) AS customer_count,
|
|
44
|
+
SUM(revenue) AS total_revenue
|
|
45
|
+
FROM companies
|
|
46
|
+
GROUP BY country
|
|
47
|
+
ORDER BY customer_count DESC
|
|
48
|
+
|
|
49
|
+
- id: revenue_per_customer
|
|
50
|
+
label: Revenue per Customer (our MRR)
|
|
51
|
+
description: Total MRR we earn from each customer company.
|
|
52
|
+
type: derived
|
|
53
|
+
unit: USD
|
|
54
|
+
sql: |-
|
|
55
|
+
SELECT c.name AS company,
|
|
56
|
+
c.industry,
|
|
57
|
+
SUM(a.monthly_value) AS total_mrr,
|
|
58
|
+
COUNT(a.id) AS account_count
|
|
59
|
+
FROM companies c
|
|
60
|
+
JOIN accounts a ON a.company_id = c.id
|
|
61
|
+
WHERE a.status = 'Active'
|
|
62
|
+
GROUP BY c.name, c.industry
|
|
63
|
+
ORDER BY total_mrr DESC
|
|
@@ -5,16 +5,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
|
5
5
|
bash coreutils grep findutils tree \
|
|
6
6
|
&& rm -rf /var/lib/apt/lists/*
|
|
7
7
|
|
|
8
|
-
RUN useradd -r -s /bin/false
|
|
8
|
+
RUN useradd -r -s /bin/false sandbox || true
|
|
9
9
|
|
|
10
10
|
WORKDIR /app
|
|
11
11
|
|
|
12
|
-
# Copy sidecar source (
|
|
13
|
-
COPY
|
|
12
|
+
# Copy sidecar source (root directory = sidecar/)
|
|
13
|
+
COPY server.ts ./server.ts
|
|
14
14
|
|
|
15
|
-
#
|
|
16
|
-
|
|
17
|
-
RUN chmod -R a-w /semantic/
|
|
15
|
+
# Create semantic directory — populated at runtime or via volume mount
|
|
16
|
+
RUN mkdir -p /semantic && chmod a+r /semantic
|
|
18
17
|
|
|
19
18
|
# Keep this image minimal — adding packages or env vars weakens the isolation model
|
|
20
19
|
|
|
@@ -153,6 +153,8 @@ mock.module("@atlas/api/lib/db/connection", () => ({
|
|
|
153
153
|
getDBType: () => "postgres" as const,
|
|
154
154
|
getTargetHost: () => "localhost",
|
|
155
155
|
getValidator: () => undefined,
|
|
156
|
+
getParserDialect: () => undefined,
|
|
157
|
+
getForbiddenPatterns: () => [],
|
|
156
158
|
list: () => ["default"],
|
|
157
159
|
describe: () => [
|
|
158
160
|
{ id: "default", dbType: "postgres", description: "Test DB" },
|
|
@@ -161,8 +163,6 @@ mock.module("@atlas/api/lib/db/connection", () => ({
|
|
|
161
163
|
},
|
|
162
164
|
detectDBType: () => "postgres" as const,
|
|
163
165
|
extractTargetHost: () => "localhost",
|
|
164
|
-
rewriteClickHouseUrl: (url: string) => url,
|
|
165
|
-
parseSnowflakeURL: () => ({}),
|
|
166
166
|
ConnectionRegistry: class {},
|
|
167
167
|
}));
|
|
168
168
|
|
|
@@ -197,13 +197,13 @@ const mockPluginHealthCheck: Mock<() => Promise<unknown>> = mock(() =>
|
|
|
197
197
|
mock.module("@atlas/api/lib/plugins/registry", () => ({
|
|
198
198
|
plugins: {
|
|
199
199
|
describe: () => [
|
|
200
|
-
{ id: "test-plugin",
|
|
200
|
+
{ id: "test-plugin", types: ["context"], version: "1.0.0", name: "Test Plugin", status: "healthy" },
|
|
201
201
|
],
|
|
202
202
|
get: (id: string) => {
|
|
203
203
|
if (id === "test-plugin") {
|
|
204
204
|
return {
|
|
205
205
|
id: "test-plugin",
|
|
206
|
-
|
|
206
|
+
types: ["context"],
|
|
207
207
|
version: "1.0.0",
|
|
208
208
|
name: "Test Plugin",
|
|
209
209
|
healthCheck: mockPluginHealthCheck,
|
|
@@ -212,7 +212,7 @@ mock.module("@atlas/api/lib/plugins/registry", () => ({
|
|
|
212
212
|
if (id === "no-health-plugin") {
|
|
213
213
|
return {
|
|
214
214
|
id: "no-health-plugin",
|
|
215
|
-
|
|
215
|
+
types: ["action"],
|
|
216
216
|
version: "0.1.0",
|
|
217
217
|
name: "No Health Plugin",
|
|
218
218
|
};
|
|
@@ -355,7 +355,7 @@ describe("Admin routes — auth enforcement", () => {
|
|
|
355
355
|
expect(res.status).toBe(401);
|
|
356
356
|
});
|
|
357
357
|
|
|
358
|
-
it("
|
|
358
|
+
it("allows access when auth mode is none (implicit admin in dev)", async () => {
|
|
359
359
|
mockAuthenticateRequest.mockResolvedValue({
|
|
360
360
|
authenticated: true,
|
|
361
361
|
mode: "none",
|
|
@@ -363,7 +363,7 @@ describe("Admin routes — auth enforcement", () => {
|
|
|
363
363
|
});
|
|
364
364
|
|
|
365
365
|
const res = await app.fetch(adminRequest("/api/v1/admin/overview"));
|
|
366
|
-
expect(res.status).toBe(
|
|
366
|
+
expect(res.status).toBe(200);
|
|
367
367
|
});
|
|
368
368
|
|
|
369
369
|
it("returns 500 when authenticateRequest throws", async () => {
|
|
@@ -45,13 +45,20 @@ mock.module("@atlas/api/lib/db/connection", () => ({
|
|
|
45
45
|
getDBType: () => "postgres" as const,
|
|
46
46
|
getTargetHost: () => "localhost",
|
|
47
47
|
getValidator: () => undefined,
|
|
48
|
+
getParserDialect: () => undefined,
|
|
49
|
+
getForbiddenPatterns: () => [],
|
|
48
50
|
list: () => [],
|
|
49
51
|
describe: () => [],
|
|
50
52
|
},
|
|
51
53
|
detectDBType: () => "postgres" as const,
|
|
54
|
+
resolveDatasourceUrl: () => process.env.ATLAS_DATASOURCE_URL || null,
|
|
52
55
|
ConnectionRegistry: class {},
|
|
53
56
|
}));
|
|
54
57
|
|
|
58
|
+
mock.module("@atlas/api/lib/providers", () => ({
|
|
59
|
+
getDefaultProvider: () => "anthropic",
|
|
60
|
+
}));
|
|
61
|
+
|
|
55
62
|
mock.module("@atlas/api/lib/semantic", () => ({
|
|
56
63
|
getWhitelistedTables: () => new Set(["companies"]),
|
|
57
64
|
_resetWhitelists: () => {},
|
|
@@ -45,13 +45,20 @@ mock.module("@atlas/api/lib/db/connection", () => ({
|
|
|
45
45
|
getDBType: () => "postgres" as const,
|
|
46
46
|
getTargetHost: () => "localhost",
|
|
47
47
|
getValidator: () => undefined,
|
|
48
|
+
getParserDialect: () => undefined,
|
|
49
|
+
getForbiddenPatterns: () => [],
|
|
48
50
|
list: () => connMetadata.map((m) => m.id),
|
|
49
51
|
describe: () => connMetadata,
|
|
50
52
|
},
|
|
51
53
|
detectDBType: () => "postgres" as const,
|
|
54
|
+
resolveDatasourceUrl: () => process.env.ATLAS_DATASOURCE_URL || null,
|
|
52
55
|
ConnectionRegistry: class {},
|
|
53
56
|
}));
|
|
54
57
|
|
|
58
|
+
mock.module("@atlas/api/lib/providers", () => ({
|
|
59
|
+
getDefaultProvider: () => "anthropic",
|
|
60
|
+
}));
|
|
61
|
+
|
|
55
62
|
mock.module("@atlas/api/lib/semantic", () => ({
|
|
56
63
|
getWhitelistedTables: () => new Set(["companies"]),
|
|
57
64
|
_resetWhitelists: () => {},
|
|
@@ -180,12 +187,13 @@ describe("GET /api/health — sources section", () => {
|
|
|
180
187
|
expect(sources.default).toBeDefined();
|
|
181
188
|
const defaultSource = sources.default as Record<string, unknown>;
|
|
182
189
|
expect(defaultSource.status).toBe("healthy");
|
|
183
|
-
|
|
190
|
+
// Live probe latency overrides the registry's cached value for default connection
|
|
191
|
+
expect(typeof defaultSource.latencyMs).toBe("number");
|
|
184
192
|
expect(defaultSource.dbType).toBe("postgres");
|
|
185
193
|
expect(defaultSource.checkedAt).toBe("2026-01-15T12:00:00.000Z");
|
|
186
194
|
});
|
|
187
195
|
|
|
188
|
-
it("promotes top-level status to 'error' when a source is unhealthy", async () => {
|
|
196
|
+
it("promotes top-level status to 'error' when a non-default source is unhealthy", async () => {
|
|
189
197
|
const unhealthy: HealthCheckResult = {
|
|
190
198
|
status: "unhealthy",
|
|
191
199
|
latencyMs: 5000,
|
|
@@ -193,7 +201,7 @@ describe("GET /api/health — sources section", () => {
|
|
|
193
201
|
checkedAt: new Date(),
|
|
194
202
|
};
|
|
195
203
|
connMetadata = [
|
|
196
|
-
{ id: "
|
|
204
|
+
{ id: "warehouse", dbType: "postgres", health: unhealthy },
|
|
197
205
|
];
|
|
198
206
|
|
|
199
207
|
const response = await app.fetch(healthRequest());
|
|
@@ -202,10 +210,10 @@ describe("GET /api/health — sources section", () => {
|
|
|
202
210
|
const body = (await response.json()) as Record<string, unknown>;
|
|
203
211
|
expect(body.status).toBe("error");
|
|
204
212
|
const sources = body.sources as Record<string, unknown>;
|
|
205
|
-
expect((sources.
|
|
213
|
+
expect((sources.warehouse as Record<string, unknown>).status).toBe("unhealthy");
|
|
206
214
|
});
|
|
207
215
|
|
|
208
|
-
it("promotes top-level status to 'degraded' when a source is degraded and no other errors", async () => {
|
|
216
|
+
it("promotes top-level status to 'degraded' when a non-default source is degraded and no other errors", async () => {
|
|
209
217
|
const degraded: HealthCheckResult = {
|
|
210
218
|
status: "degraded",
|
|
211
219
|
latencyMs: 2000,
|
|
@@ -213,7 +221,7 @@ describe("GET /api/health — sources section", () => {
|
|
|
213
221
|
checkedAt: new Date(),
|
|
214
222
|
};
|
|
215
223
|
connMetadata = [
|
|
216
|
-
{ id: "
|
|
224
|
+
{ id: "warehouse", dbType: "postgres", health: degraded },
|
|
217
225
|
];
|
|
218
226
|
|
|
219
227
|
const response = await app.fetch(healthRequest());
|
|
@@ -246,7 +254,21 @@ describe("GET /api/health — sources section", () => {
|
|
|
246
254
|
expect((sources.warehouse as Record<string, unknown>).dbType).toBe("mysql");
|
|
247
255
|
});
|
|
248
256
|
|
|
249
|
-
it("returns status 'unknown' when source has no health check result", async () => {
|
|
257
|
+
it("returns status 'unknown' when non-default source has no health check result", async () => {
|
|
258
|
+
connMetadata = [
|
|
259
|
+
{ id: "warehouse", dbType: "mysql" },
|
|
260
|
+
];
|
|
261
|
+
|
|
262
|
+
const response = await app.fetch(healthRequest());
|
|
263
|
+
const body = (await response.json()) as Record<string, unknown>;
|
|
264
|
+
const sources = body.sources as Record<string, unknown>;
|
|
265
|
+
const warehouseSource = sources.warehouse as Record<string, unknown>;
|
|
266
|
+
|
|
267
|
+
expect(warehouseSource.status).toBe("unknown");
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it("uses live probe results for default source status", async () => {
|
|
271
|
+
// Even if registry reports no health, the live probe succeeds → healthy
|
|
250
272
|
connMetadata = [
|
|
251
273
|
{ id: "default", dbType: "postgres" },
|
|
252
274
|
];
|
|
@@ -256,6 +278,6 @@ describe("GET /api/health — sources section", () => {
|
|
|
256
278
|
const sources = body.sources as Record<string, unknown>;
|
|
257
279
|
const defaultSource = sources.default as Record<string, unknown>;
|
|
258
280
|
|
|
259
|
-
expect(defaultSource.status).toBe("
|
|
281
|
+
expect(defaultSource.status).toBe("healthy");
|
|
260
282
|
});
|
|
261
283
|
});
|