@littlebearapps/platform-admin-sdk 1.4.2 → 2.0.0

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.
Files changed (189) hide show
  1. package/dist/templates.d.ts +1 -1
  2. package/dist/templates.js +232 -2
  3. package/package.json +1 -1
  4. package/templates/full/config/audit-targets.yaml +72 -0
  5. package/templates/full/dashboard/src/components/notifications/NotificationBell.tsx +30 -0
  6. package/templates/full/dashboard/src/components/notifications/NotificationList.tsx +116 -0
  7. package/templates/full/dashboard/src/components/notifications/index.ts +2 -0
  8. package/templates/full/dashboard/src/components/patterns/ActivePatterns.tsx +62 -0
  9. package/templates/full/dashboard/src/components/patterns/PatternStats.tsx +60 -0
  10. package/templates/full/dashboard/src/components/patterns/PatternTabs.tsx +116 -0
  11. package/templates/full/dashboard/src/components/patterns/SuggestionsQueue.tsx +115 -0
  12. package/templates/full/dashboard/src/components/patterns/SystemPatterns.tsx +52 -0
  13. package/templates/full/dashboard/src/components/patterns/index.ts +5 -0
  14. package/templates/full/dashboard/src/components/reports/GapDetectionReport.tsx +69 -0
  15. package/templates/full/dashboard/src/components/reports/SdkAuditReport.tsx +72 -0
  16. package/templates/full/dashboard/src/components/reports/index.ts +2 -0
  17. package/templates/full/dashboard/src/components/search/SearchModal.tsx +108 -0
  18. package/templates/full/dashboard/src/pages/api/notifications/[id]/read.ts +37 -0
  19. package/templates/full/dashboard/src/pages/api/notifications/index.ts +47 -0
  20. package/templates/full/dashboard/src/pages/api/notifications/read-all.ts +28 -0
  21. package/templates/full/dashboard/src/pages/api/notifications/unread-count.ts +31 -0
  22. package/templates/full/dashboard/src/pages/api/patterns/approve.ts +55 -0
  23. package/templates/full/dashboard/src/pages/api/patterns/cache-refresh.ts +38 -0
  24. package/templates/full/dashboard/src/pages/api/patterns/discover.ts +36 -0
  25. package/templates/full/dashboard/src/pages/api/patterns/index.ts +36 -0
  26. package/templates/full/dashboard/src/pages/api/patterns/ready-for-review.ts +39 -0
  27. package/templates/full/dashboard/src/pages/api/patterns/reject.ts +54 -0
  28. package/templates/full/dashboard/src/pages/api/patterns/stats.ts +39 -0
  29. package/templates/full/dashboard/src/pages/api/patterns/suggestions.ts +43 -0
  30. package/templates/full/dashboard/src/pages/api/reports/audit.ts +45 -0
  31. package/templates/full/dashboard/src/pages/api/reports/usage.ts +52 -0
  32. package/templates/full/dashboard/src/pages/api/search/index.ts +74 -0
  33. package/templates/full/dashboard/src/pages/api/search/reindex.ts +28 -0
  34. package/templates/full/dashboard/src/pages/api/search/stats.ts +27 -0
  35. package/templates/full/dashboard/src/pages/api/settings/index.ts +37 -0
  36. package/templates/full/dashboard/src/pages/api/settings/update.ts +41 -0
  37. package/templates/full/dashboard/src/pages/api/topology/index.ts +56 -0
  38. package/templates/full/dashboard/src/pages/notifications.astro +11 -0
  39. package/templates/full/migrations/008_auditor.sql +99 -0
  40. package/templates/full/migrations/010_pricing_versions.sql +110 -0
  41. package/templates/full/migrations/011_multi_account.sql +51 -0
  42. package/templates/full/scripts/ops/set-kv-pricing.ts +182 -0
  43. package/templates/full/scripts/ops/universal-backfill.ts +147 -0
  44. package/templates/full/workers/lib/ai-judge-schema.ts +181 -0
  45. package/templates/full/workers/lib/auditor/comprehensive-report.ts +407 -0
  46. package/templates/full/workers/lib/auditor/feature-coverage.ts +348 -0
  47. package/templates/full/workers/lib/auditor/index.ts +9 -0
  48. package/templates/full/workers/lib/auditor/types.ts +167 -0
  49. package/templates/full/workers/platform-auditor.ts +1071 -0
  50. package/templates/full/wrangler.auditor.jsonc.hbs +75 -0
  51. package/templates/shared/.github/workflows/contract-check.yml.hbs +42 -0
  52. package/templates/shared/.github/workflows/dashboard-deploy.yml.hbs +39 -0
  53. package/templates/shared/.github/workflows/platform-check.yml.hbs +28 -0
  54. package/templates/shared/.github/workflows/security.yml +33 -0
  55. package/templates/shared/config/observability.yaml.hbs +276 -0
  56. package/templates/shared/contracts/schemas/envelope.v1.schema.json +64 -0
  57. package/templates/shared/contracts/schemas/error_report.v1.schema.json +65 -0
  58. package/templates/shared/contracts/types/telemetry-envelope.types.ts +139 -0
  59. package/templates/shared/dashboard/astro.config.mjs +21 -0
  60. package/templates/shared/dashboard/package.json.hbs +29 -0
  61. package/templates/shared/dashboard/src/components/Header.astro +29 -0
  62. package/templates/shared/dashboard/src/components/Nav.astro.hbs +59 -0
  63. package/templates/shared/dashboard/src/components/infrastructure/AlertHistory.tsx +57 -0
  64. package/templates/shared/dashboard/src/components/infrastructure/InfrastructureStats.tsx +73 -0
  65. package/templates/shared/dashboard/src/components/infrastructure/ServiceRegistry.tsx +55 -0
  66. package/templates/shared/dashboard/src/components/infrastructure/UptimeStatus.tsx +56 -0
  67. package/templates/shared/dashboard/src/components/infrastructure/index.ts +4 -0
  68. package/templates/shared/dashboard/src/components/overview/ActivityFeed.tsx +134 -0
  69. package/templates/shared/dashboard/src/components/overview/CostQuadrant.tsx +131 -0
  70. package/templates/shared/dashboard/src/components/overview/ErrorsQuadrant.tsx +113 -0
  71. package/templates/shared/dashboard/src/components/overview/HealthQuadrant.tsx +87 -0
  72. package/templates/shared/dashboard/src/components/overview/MissionControl.tsx +139 -0
  73. package/templates/shared/dashboard/src/components/resources/AllowanceStatus.tsx +44 -0
  74. package/templates/shared/dashboard/src/components/resources/CostCentreOverview.tsx +42 -0
  75. package/templates/shared/dashboard/src/components/resources/ResourceTabs.tsx +69 -0
  76. package/templates/shared/dashboard/src/components/resources/index.ts +3 -0
  77. package/templates/shared/dashboard/src/components/settings/SettingsCard.tsx +21 -0
  78. package/templates/shared/dashboard/src/components/settings/index.ts +1 -0
  79. package/templates/shared/dashboard/src/components/ui/AlertBanner.tsx +39 -0
  80. package/templates/shared/dashboard/src/components/ui/Breadcrumbs.tsx +27 -0
  81. package/templates/shared/dashboard/src/components/ui/EmptyState.tsx +26 -0
  82. package/templates/shared/dashboard/src/components/ui/ErrorBoundary.tsx +42 -0
  83. package/templates/shared/dashboard/src/components/ui/LoadingSkeleton.tsx +18 -0
  84. package/templates/shared/dashboard/src/components/ui/PageShell.tsx +26 -0
  85. package/templates/shared/dashboard/src/components/ui/Sparkline.tsx +127 -0
  86. package/templates/shared/dashboard/src/components/ui/StatusDot.tsx +21 -0
  87. package/templates/shared/dashboard/src/components/ui/Toast.tsx +44 -0
  88. package/templates/shared/dashboard/src/components/ui/index.ts +9 -0
  89. package/templates/shared/dashboard/src/components/usage/AnomaliesWidget.tsx +68 -0
  90. package/templates/shared/dashboard/src/components/usage/HourlyUsageChart.tsx +55 -0
  91. package/templates/shared/dashboard/src/components/usage/PlanAllowanceDashboard.tsx +67 -0
  92. package/templates/shared/dashboard/src/components/usage/ProjectCostBreakdown.tsx +55 -0
  93. package/templates/shared/dashboard/src/components/usage/index.ts +4 -0
  94. package/templates/shared/dashboard/src/env.d.ts.hbs +34 -0
  95. package/templates/shared/dashboard/src/layouts/DashboardLayout.astro +37 -0
  96. package/templates/shared/dashboard/src/lib/cloudflare/costs.ts +21 -0
  97. package/templates/shared/dashboard/src/lib/fetch.ts +29 -0
  98. package/templates/shared/dashboard/src/lib/types.ts +72 -0
  99. package/templates/shared/dashboard/src/middleware/auth.ts +100 -0
  100. package/templates/shared/dashboard/src/middleware/index.ts +1 -0
  101. package/templates/shared/dashboard/src/pages/api/costs/overview.ts +65 -0
  102. package/templates/shared/dashboard/src/pages/api/costs/providers.ts +47 -0
  103. package/templates/shared/dashboard/src/pages/api/infrastructure/services.ts +55 -0
  104. package/templates/shared/dashboard/src/pages/api/infrastructure/stats.ts +99 -0
  105. package/templates/shared/dashboard/src/pages/api/overview/summary.ts +311 -0
  106. package/templates/shared/dashboard/src/pages/api/usage/allowances.ts +56 -0
  107. package/templates/shared/dashboard/src/pages/api/usage/anomalies.ts +45 -0
  108. package/templates/shared/dashboard/src/pages/api/usage/billing.ts +53 -0
  109. package/templates/shared/dashboard/src/pages/api/usage/circuit-breakers.ts +44 -0
  110. package/templates/shared/dashboard/src/pages/api/usage/granular.ts +50 -0
  111. package/templates/shared/dashboard/src/pages/api/usage/hourly.ts +45 -0
  112. package/templates/shared/dashboard/src/pages/api/usage/projects.ts +51 -0
  113. package/templates/shared/dashboard/src/pages/api/usage/status.ts +42 -0
  114. package/templates/shared/dashboard/src/pages/api/user/identity.ts +11 -0
  115. package/templates/shared/dashboard/src/pages/dashboard.astro +11 -0
  116. package/templates/shared/dashboard/src/pages/index.astro +3 -0
  117. package/templates/shared/dashboard/src/pages/resources.astro +11 -0
  118. package/templates/shared/dashboard/src/pages/settings/index.astro +28 -0
  119. package/templates/shared/dashboard/src/pages/settings/notifications.astro +34 -0
  120. package/templates/shared/dashboard/src/pages/settings/thresholds.astro +39 -0
  121. package/templates/shared/dashboard/src/pages/settings/usage.astro +28 -0
  122. package/templates/shared/dashboard/src/styles/global.css +29 -0
  123. package/templates/shared/dashboard/tailwind.config.mjs +9 -0
  124. package/templates/shared/dashboard/tsconfig.json +9 -0
  125. package/templates/shared/dashboard/wrangler.json.hbs +47 -0
  126. package/templates/shared/docs/architecture.md +89 -0
  127. package/templates/shared/docs/post-deploy-runbook.md +126 -0
  128. package/templates/shared/docs/troubleshooting.md +91 -0
  129. package/templates/shared/package.json.hbs +17 -1
  130. package/templates/shared/scripts/ops/backfill-cloudflare-daily.ts +145 -0
  131. package/templates/shared/scripts/ops/backfill-cloudflare-hourly.ts +473 -0
  132. package/templates/shared/scripts/ops/backfill-monthly-rollups.ts +125 -0
  133. package/templates/shared/scripts/ops/discover-graphql-datasets.ts +482 -0
  134. package/templates/shared/scripts/ops/reset-budget-state.ts +279 -0
  135. package/templates/shared/scripts/ops/validate-controls.js +141 -0
  136. package/templates/shared/scripts/ops/validate-pipeline.ts +237 -0
  137. package/templates/shared/scripts/ops/verify-account-completeness.ts +236 -0
  138. package/templates/shared/scripts/validate-schemas.js +61 -0
  139. package/templates/shared/tests/contract/validate-schemas.test.ts +130 -0
  140. package/templates/shared/tests/fixtures/telemetry-envelope-invalid.json +9 -0
  141. package/templates/shared/tests/fixtures/telemetry-envelope-valid.json +27 -0
  142. package/templates/shared/tests/helpers/mock-d1.ts +61 -0
  143. package/templates/shared/tests/helpers/mock-kv.ts +37 -0
  144. package/templates/shared/tests/unit/workers/batch-persistence.test.ts +133 -0
  145. package/templates/shared/tests/unit/workers/budget-enforcement.test.ts +214 -0
  146. package/templates/shared/vitest.config.ts +18 -0
  147. package/templates/shared/workers/lib/usage/collectors/anthropic.ts +114 -0
  148. package/templates/shared/workers/lib/usage/collectors/apify.ts +96 -0
  149. package/templates/shared/workers/lib/usage/collectors/custom-http.ts +151 -0
  150. package/templates/shared/workers/lib/usage/collectors/deepseek.ts +92 -0
  151. package/templates/shared/workers/lib/usage/collectors/gemini.ts +263 -0
  152. package/templates/shared/workers/lib/usage/collectors/github.ts +362 -0
  153. package/templates/shared/workers/lib/usage/collectors/index.ts +31 -15
  154. package/templates/shared/workers/lib/usage/collectors/minimax.ts +106 -0
  155. package/templates/shared/workers/lib/usage/collectors/openai.ts +171 -0
  156. package/templates/shared/workers/lib/usage/collectors/resend.ts +79 -0
  157. package/templates/shared/workers/lib/usage/collectors/stripe.ts +192 -0
  158. package/templates/shared/workers/lib/usage/shared/types.ts +46 -0
  159. package/templates/shared/workers/platform-usage.ts +98 -8
  160. package/templates/standard/dashboard/src/components/errors/ErrorStats.tsx +53 -0
  161. package/templates/standard/dashboard/src/components/errors/ErrorsTable.tsx +133 -0
  162. package/templates/standard/dashboard/src/components/errors/index.ts +2 -0
  163. package/templates/standard/dashboard/src/components/health/CircuitBreakerEvents.tsx +69 -0
  164. package/templates/standard/dashboard/src/components/health/CircuitBreakerPanel.tsx +97 -0
  165. package/templates/standard/dashboard/src/components/health/DlqStatusCard.tsx +52 -0
  166. package/templates/standard/dashboard/src/components/health/HealthTabs.tsx +86 -0
  167. package/templates/standard/dashboard/src/components/health/index.ts +4 -0
  168. package/templates/standard/dashboard/src/lib/errors.ts +28 -0
  169. package/templates/standard/dashboard/src/pages/api/errors/[fingerprint]/mute.ts +49 -0
  170. package/templates/standard/dashboard/src/pages/api/errors/[fingerprint]/resolve.ts +36 -0
  171. package/templates/standard/dashboard/src/pages/api/errors/[fingerprint].ts +55 -0
  172. package/templates/standard/dashboard/src/pages/api/errors/index.ts +58 -0
  173. package/templates/standard/dashboard/src/pages/api/errors/stats.ts +55 -0
  174. package/templates/standard/dashboard/src/pages/api/health/audit-history.ts +37 -0
  175. package/templates/standard/dashboard/src/pages/api/health/dlq.ts +43 -0
  176. package/templates/standard/dashboard/src/pages/circuit-breakers.astro +13 -0
  177. package/templates/standard/dashboard/src/pages/errors.astro +13 -0
  178. package/templates/standard/dashboard/src/pages/health.astro +11 -0
  179. package/templates/standard/migrations/009_topology_mapper.sql +65 -0
  180. package/templates/standard/tests/unit/error-collector/capture.test.ts +106 -0
  181. package/templates/standard/tests/unit/error-collector/fingerprint.test.ts +155 -0
  182. package/templates/standard/workers/lib/error-collector/email-health-alerts.ts +37 -3
  183. package/templates/standard/workers/lib/error-collector/gap-alerts.ts +32 -1
  184. package/templates/standard/workers/lib/mapper/attribution-check.ts +339 -0
  185. package/templates/standard/workers/lib/mapper/index.ts +7 -0
  186. package/templates/standard/workers/platform-mapper.ts +482 -0
  187. package/templates/standard/workers/platform-sdk-test-client.ts +125 -0
  188. package/templates/standard/wrangler.mapper.jsonc.hbs +85 -0
  189. package/templates/standard/wrangler.sdk-test-client.jsonc.hbs +62 -0
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import type { Tier } from './prompts.js';
8
8
  /** Single source of truth for the SDK version. */
9
- export declare const SDK_VERSION = "1.4.2";
9
+ export declare const SDK_VERSION = "2.0.0";
10
10
  /** Returns true if `to` is the same or higher tier than `from`. */
11
11
  export declare function isTierUpgradeOrSame(from: Tier, to: Tier): boolean;
12
12
  /** Check if a template file is a numbered migration (not seed.sql). */
package/dist/templates.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * All other files are copied verbatim.
6
6
  */
7
7
  /** Single source of truth for the SDK version. */
8
- export const SDK_VERSION = '1.4.2';
8
+ export const SDK_VERSION = '2.0.0';
9
9
  /** Tier ordering for upgrade validation. */
10
10
  const TIER_ORDER = { minimal: 0, standard: 1, full: 2 };
11
11
  /** Returns true if `to` is the same or higher tier than `from`. */
@@ -22,6 +22,16 @@ const SHARED_FILES = [
22
22
  { src: 'shared/config/budgets.yaml.hbs', dest: 'platform/config/budgets.yaml', template: true },
23
23
  // Scripts
24
24
  { src: 'shared/scripts/sync-config.ts', dest: 'scripts/sync-config.ts', template: false },
25
+ { src: 'shared/scripts/validate-schemas.js', dest: 'scripts/validate-schemas.js', template: false },
26
+ // Operational scripts
27
+ { src: 'shared/scripts/ops/backfill-cloudflare-hourly.ts', dest: 'scripts/ops/backfill-cloudflare-hourly.ts', template: false },
28
+ { src: 'shared/scripts/ops/reset-budget-state.ts', dest: 'scripts/ops/reset-budget-state.ts', template: false },
29
+ { src: 'shared/scripts/ops/verify-account-completeness.ts', dest: 'scripts/ops/verify-account-completeness.ts', template: false },
30
+ { src: 'shared/scripts/ops/validate-pipeline.ts', dest: 'scripts/ops/validate-pipeline.ts', template: false },
31
+ // Contracts — JSON schemas + TypeScript types
32
+ { src: 'shared/contracts/schemas/envelope.v1.schema.json', dest: 'contracts/schemas/envelope.v1.schema.json', template: false },
33
+ { src: 'shared/contracts/schemas/error_report.v1.schema.json', dest: 'contracts/schemas/error_report.v1.schema.json', template: false },
34
+ { src: 'shared/contracts/types/telemetry-envelope.types.ts', dest: 'contracts/types/telemetry-envelope.types.ts', template: false },
25
35
  // Migrations (minimal tier)
26
36
  { src: 'shared/migrations/001_core_tables.sql', dest: 'storage/d1/migrations/001_core_tables.sql', template: false },
27
37
  { src: 'shared/migrations/002_usage_warehouse.sql', dest: 'storage/d1/migrations/002_usage_warehouse.sql', template: false },
@@ -79,11 +89,130 @@ const SHARED_FILES = [
79
89
  { src: 'shared/workers/lib/usage/scheduled/anomaly-detection.ts', dest: 'workers/lib/usage/scheduled/anomaly-detection.ts', template: false },
80
90
  { src: 'shared/workers/lib/usage/scheduled/rollups.ts', dest: 'workers/lib/usage/scheduled/rollups.ts', template: false },
81
91
  { src: 'shared/workers/lib/usage/scheduled/error-digest.ts', dest: 'workers/lib/usage/scheduled/error-digest.ts', template: false },
82
- // Workers — lib/usage/collectors (pluggable interface + example)
92
+ // Workers — lib/usage/collectors (framework + 10 provider collectors + example)
83
93
  { src: 'shared/workers/lib/usage/collectors/index.ts', dest: 'workers/lib/usage/collectors/index.ts', template: false },
84
94
  { src: 'shared/workers/lib/usage/collectors/example.ts', dest: 'workers/lib/usage/collectors/example.ts', template: false },
95
+ { src: 'shared/workers/lib/usage/collectors/openai.ts', dest: 'workers/lib/usage/collectors/openai.ts', template: false },
96
+ { src: 'shared/workers/lib/usage/collectors/anthropic.ts', dest: 'workers/lib/usage/collectors/anthropic.ts', template: false },
97
+ { src: 'shared/workers/lib/usage/collectors/github.ts', dest: 'workers/lib/usage/collectors/github.ts', template: false },
98
+ { src: 'shared/workers/lib/usage/collectors/stripe.ts', dest: 'workers/lib/usage/collectors/stripe.ts', template: false },
99
+ { src: 'shared/workers/lib/usage/collectors/apify.ts', dest: 'workers/lib/usage/collectors/apify.ts', template: false },
100
+ { src: 'shared/workers/lib/usage/collectors/resend.ts', dest: 'workers/lib/usage/collectors/resend.ts', template: false },
101
+ { src: 'shared/workers/lib/usage/collectors/deepseek.ts', dest: 'workers/lib/usage/collectors/deepseek.ts', template: false },
102
+ { src: 'shared/workers/lib/usage/collectors/minimax.ts', dest: 'workers/lib/usage/collectors/minimax.ts', template: false },
103
+ { src: 'shared/workers/lib/usage/collectors/gemini.ts', dest: 'workers/lib/usage/collectors/gemini.ts', template: false },
104
+ { src: 'shared/workers/lib/usage/collectors/custom-http.ts', dest: 'workers/lib/usage/collectors/custom-http.ts', template: false },
85
105
  // Documentation
86
106
  { src: 'shared/docs/kv-key-patterns.md', dest: 'docs/kv-key-patterns.md', template: false },
107
+ // Observability config
108
+ { src: 'shared/config/observability.yaml.hbs', dest: 'platform/config/observability.yaml', template: true },
109
+ // GraphQL dataset discovery script
110
+ { src: 'shared/scripts/ops/discover-graphql-datasets.ts', dest: 'scripts/ops/discover-graphql-datasets.ts', template: false },
111
+ // CI workflow (caller for reusable consumer-check)
112
+ { src: 'shared/.github/workflows/platform-check.yml.hbs', dest: '.github/workflows/platform-check.yml', template: true },
113
+ // Dashboard — shared tier (Astro SSR + Cloudflare Pages)
114
+ { src: 'shared/dashboard/package.json.hbs', dest: 'dashboard/package.json', template: true },
115
+ { src: 'shared/dashboard/astro.config.mjs', dest: 'dashboard/astro.config.mjs', template: false },
116
+ { src: 'shared/dashboard/tailwind.config.mjs', dest: 'dashboard/tailwind.config.mjs', template: false },
117
+ { src: 'shared/dashboard/tsconfig.json', dest: 'dashboard/tsconfig.json', template: false },
118
+ { src: 'shared/dashboard/wrangler.json.hbs', dest: 'dashboard/wrangler.json', template: true },
119
+ { src: 'shared/dashboard/src/env.d.ts.hbs', dest: 'dashboard/src/env.d.ts', template: true },
120
+ { src: 'shared/dashboard/src/styles/global.css', dest: 'dashboard/src/styles/global.css', template: false },
121
+ { src: 'shared/dashboard/src/middleware/auth.ts', dest: 'dashboard/src/middleware/auth.ts', template: false },
122
+ { src: 'shared/dashboard/src/middleware/index.ts', dest: 'dashboard/src/middleware/index.ts', template: false },
123
+ { src: 'shared/dashboard/src/layouts/DashboardLayout.astro', dest: 'dashboard/src/layouts/DashboardLayout.astro', template: false },
124
+ { src: 'shared/dashboard/src/components/Nav.astro.hbs', dest: 'dashboard/src/components/Nav.astro', template: true },
125
+ { src: 'shared/dashboard/src/components/Header.astro', dest: 'dashboard/src/components/Header.astro', template: false },
126
+ { src: 'shared/dashboard/src/pages/index.astro', dest: 'dashboard/src/pages/index.astro', template: false },
127
+ { src: 'shared/dashboard/src/pages/dashboard.astro', dest: 'dashboard/src/pages/dashboard.astro', template: false },
128
+ { src: 'shared/dashboard/src/pages/resources.astro', dest: 'dashboard/src/pages/resources.astro', template: false },
129
+ { src: 'shared/dashboard/src/pages/settings/index.astro', dest: 'dashboard/src/pages/settings/index.astro', template: false },
130
+ { src: 'shared/dashboard/src/pages/api/overview/summary.ts', dest: 'dashboard/src/pages/api/overview/summary.ts', template: false },
131
+ { src: 'shared/dashboard/src/pages/api/usage/circuit-breakers.ts', dest: 'dashboard/src/pages/api/usage/circuit-breakers.ts', template: false },
132
+ { src: 'shared/dashboard/src/pages/api/usage/status.ts', dest: 'dashboard/src/pages/api/usage/status.ts', template: false },
133
+ { src: 'shared/dashboard/src/components/overview/MissionControl.tsx', dest: 'dashboard/src/components/overview/MissionControl.tsx', template: false },
134
+ { src: 'shared/dashboard/src/components/overview/HealthQuadrant.tsx', dest: 'dashboard/src/components/overview/HealthQuadrant.tsx', template: false },
135
+ { src: 'shared/dashboard/src/components/overview/ErrorsQuadrant.tsx', dest: 'dashboard/src/components/overview/ErrorsQuadrant.tsx', template: false },
136
+ { src: 'shared/dashboard/src/components/overview/CostQuadrant.tsx', dest: 'dashboard/src/components/overview/CostQuadrant.tsx', template: false },
137
+ { src: 'shared/dashboard/src/components/overview/ActivityFeed.tsx', dest: 'dashboard/src/components/overview/ActivityFeed.tsx', template: false },
138
+ { src: 'shared/dashboard/src/components/ui/AlertBanner.tsx', dest: 'dashboard/src/components/ui/AlertBanner.tsx', template: false },
139
+ { src: 'shared/dashboard/src/components/ui/Sparkline.tsx', dest: 'dashboard/src/components/ui/Sparkline.tsx', template: false },
140
+ { src: 'shared/dashboard/src/components/ui/StatusDot.tsx', dest: 'dashboard/src/components/ui/StatusDot.tsx', template: false },
141
+ { src: 'shared/dashboard/src/components/ui/index.ts', dest: 'dashboard/src/components/ui/index.ts', template: false },
142
+ { src: 'shared/dashboard/src/components/resources/ResourceTabs.tsx', dest: 'dashboard/src/components/resources/ResourceTabs.tsx', template: false },
143
+ { src: 'shared/dashboard/src/components/resources/CostCentreOverview.tsx', dest: 'dashboard/src/components/resources/CostCentreOverview.tsx', template: false },
144
+ { src: 'shared/dashboard/src/components/resources/AllowanceStatus.tsx', dest: 'dashboard/src/components/resources/AllowanceStatus.tsx', template: false },
145
+ { src: 'shared/dashboard/src/components/resources/index.ts', dest: 'dashboard/src/components/resources/index.ts', template: false },
146
+ { src: 'shared/dashboard/src/components/settings/SettingsCard.tsx', dest: 'dashboard/src/components/settings/SettingsCard.tsx', template: false },
147
+ { src: 'shared/dashboard/src/components/settings/index.ts', dest: 'dashboard/src/components/settings/index.ts', template: false },
148
+ { src: 'shared/dashboard/src/lib/types.ts', dest: 'dashboard/src/lib/types.ts', template: false },
149
+ { src: 'shared/dashboard/src/lib/fetch.ts', dest: 'dashboard/src/lib/fetch.ts', template: false },
150
+ // Dashboard — shared tier: UI primitives (v1.6.0)
151
+ { src: 'shared/dashboard/src/components/ui/EmptyState.tsx', dest: 'dashboard/src/components/ui/EmptyState.tsx', template: false },
152
+ { src: 'shared/dashboard/src/components/ui/LoadingSkeleton.tsx', dest: 'dashboard/src/components/ui/LoadingSkeleton.tsx', template: false },
153
+ { src: 'shared/dashboard/src/components/ui/Breadcrumbs.tsx', dest: 'dashboard/src/components/ui/Breadcrumbs.tsx', template: false },
154
+ { src: 'shared/dashboard/src/components/ui/Toast.tsx', dest: 'dashboard/src/components/ui/Toast.tsx', template: false },
155
+ // Dashboard — shared tier: usage API routes (v1.6.0)
156
+ { src: 'shared/dashboard/src/pages/api/usage/billing.ts', dest: 'dashboard/src/pages/api/usage/billing.ts', template: false },
157
+ { src: 'shared/dashboard/src/pages/api/usage/hourly.ts', dest: 'dashboard/src/pages/api/usage/hourly.ts', template: false },
158
+ { src: 'shared/dashboard/src/pages/api/usage/granular.ts', dest: 'dashboard/src/pages/api/usage/granular.ts', template: false },
159
+ { src: 'shared/dashboard/src/pages/api/usage/projects.ts', dest: 'dashboard/src/pages/api/usage/projects.ts', template: false },
160
+ { src: 'shared/dashboard/src/pages/api/usage/allowances.ts', dest: 'dashboard/src/pages/api/usage/allowances.ts', template: false },
161
+ { src: 'shared/dashboard/src/pages/api/usage/anomalies.ts', dest: 'dashboard/src/pages/api/usage/anomalies.ts', template: false },
162
+ // Dashboard — shared tier: costs API routes (v1.6.0)
163
+ { src: 'shared/dashboard/src/pages/api/costs/overview.ts', dest: 'dashboard/src/pages/api/costs/overview.ts', template: false },
164
+ { src: 'shared/dashboard/src/pages/api/costs/providers.ts', dest: 'dashboard/src/pages/api/costs/providers.ts', template: false },
165
+ // Dashboard — shared tier: infrastructure API routes (v1.6.0)
166
+ { src: 'shared/dashboard/src/pages/api/infrastructure/stats.ts', dest: 'dashboard/src/pages/api/infrastructure/stats.ts', template: false },
167
+ { src: 'shared/dashboard/src/pages/api/infrastructure/services.ts', dest: 'dashboard/src/pages/api/infrastructure/services.ts', template: false },
168
+ // Dashboard — shared tier: user API route (v1.6.0)
169
+ { src: 'shared/dashboard/src/pages/api/user/identity.ts', dest: 'dashboard/src/pages/api/user/identity.ts', template: false },
170
+ // Dashboard — shared tier: cloudflare lib (v1.6.0)
171
+ { src: 'shared/dashboard/src/lib/cloudflare/costs.ts', dest: 'dashboard/src/lib/cloudflare/costs.ts', template: false },
172
+ // Dashboard — shared tier: infrastructure components (v1.6.0)
173
+ { src: 'shared/dashboard/src/components/infrastructure/InfrastructureStats.tsx', dest: 'dashboard/src/components/infrastructure/InfrastructureStats.tsx', template: false },
174
+ { src: 'shared/dashboard/src/components/infrastructure/index.ts', dest: 'dashboard/src/components/infrastructure/index.ts', template: false },
175
+ // Dashboard — shared tier: usage components (v1.6.0)
176
+ { src: 'shared/dashboard/src/components/usage/HourlyUsageChart.tsx', dest: 'dashboard/src/components/usage/HourlyUsageChart.tsx', template: false },
177
+ { src: 'shared/dashboard/src/components/usage/PlanAllowanceDashboard.tsx', dest: 'dashboard/src/components/usage/PlanAllowanceDashboard.tsx', template: false },
178
+ { src: 'shared/dashboard/src/components/usage/AnomaliesWidget.tsx', dest: 'dashboard/src/components/usage/AnomaliesWidget.tsx', template: false },
179
+ { src: 'shared/dashboard/src/components/usage/index.ts', dest: 'dashboard/src/components/usage/index.ts', template: false },
180
+ // Dashboard — shared tier: settings pages (v1.6.0)
181
+ { src: 'shared/dashboard/src/pages/settings/notifications.astro', dest: 'dashboard/src/pages/settings/notifications.astro', template: false },
182
+ { src: 'shared/dashboard/src/pages/settings/thresholds.astro', dest: 'dashboard/src/pages/settings/thresholds.astro', template: false },
183
+ { src: 'shared/dashboard/src/pages/settings/usage.astro', dest: 'dashboard/src/pages/settings/usage.astro', template: false },
184
+ // CI — dashboard deploy workflow (v1.6.0)
185
+ { src: 'shared/.github/workflows/dashboard-deploy.yml.hbs', dest: '.github/workflows/dashboard-deploy.yml', template: true },
186
+ // Test infrastructure (v1.7.0)
187
+ { src: 'shared/vitest.config.ts', dest: 'vitest.config.ts', template: false },
188
+ { src: 'shared/tests/helpers/mock-kv.ts', dest: 'tests/helpers/mock-kv.ts', template: false },
189
+ { src: 'shared/tests/helpers/mock-d1.ts', dest: 'tests/helpers/mock-d1.ts', template: false },
190
+ { src: 'shared/tests/fixtures/telemetry-envelope-valid.json', dest: 'tests/fixtures/telemetry-envelope-valid.json', template: false },
191
+ { src: 'shared/tests/fixtures/telemetry-envelope-invalid.json', dest: 'tests/fixtures/telemetry-envelope-invalid.json', template: false },
192
+ // Shared tests (v1.7.0)
193
+ { src: 'shared/tests/unit/workers/budget-enforcement.test.ts', dest: 'tests/unit/workers/budget-enforcement.test.ts', template: false },
194
+ { src: 'shared/tests/unit/workers/batch-persistence.test.ts', dest: 'tests/unit/workers/batch-persistence.test.ts', template: false },
195
+ { src: 'shared/tests/contract/validate-schemas.test.ts', dest: 'tests/contract/validate-schemas.test.ts', template: false },
196
+ // Backfill scripts (v1.8.0)
197
+ { src: 'shared/scripts/ops/backfill-cloudflare-daily.ts', dest: 'scripts/ops/backfill-cloudflare-daily.ts', template: false },
198
+ { src: 'shared/scripts/ops/backfill-monthly-rollups.ts', dest: 'scripts/ops/backfill-monthly-rollups.ts', template: false },
199
+ { src: 'shared/scripts/ops/validate-controls.js', dest: 'scripts/ops/validate-controls.js', template: false },
200
+ // Dashboard — shared tier: additional infrastructure components (v2.0.0)
201
+ { src: 'shared/dashboard/src/components/infrastructure/UptimeStatus.tsx', dest: 'dashboard/src/components/infrastructure/UptimeStatus.tsx', template: false },
202
+ { src: 'shared/dashboard/src/components/infrastructure/ServiceRegistry.tsx', dest: 'dashboard/src/components/infrastructure/ServiceRegistry.tsx', template: false },
203
+ { src: 'shared/dashboard/src/components/infrastructure/AlertHistory.tsx', dest: 'dashboard/src/components/infrastructure/AlertHistory.tsx', template: false },
204
+ // Dashboard — shared tier: additional usage components (v2.0.0)
205
+ { src: 'shared/dashboard/src/components/usage/ProjectCostBreakdown.tsx', dest: 'dashboard/src/components/usage/ProjectCostBreakdown.tsx', template: false },
206
+ // Dashboard — shared tier: additional UI components (v2.0.0)
207
+ { src: 'shared/dashboard/src/components/ui/ErrorBoundary.tsx', dest: 'dashboard/src/components/ui/ErrorBoundary.tsx', template: false },
208
+ { src: 'shared/dashboard/src/components/ui/PageShell.tsx', dest: 'dashboard/src/components/ui/PageShell.tsx', template: false },
209
+ // CI — contract check + security workflows (v2.0.0)
210
+ { src: 'shared/.github/workflows/contract-check.yml.hbs', dest: '.github/workflows/contract-check.yml', template: true },
211
+ { src: 'shared/.github/workflows/security.yml', dest: '.github/workflows/security.yml', template: false },
212
+ // Documentation (v2.0.0)
213
+ { src: 'shared/docs/troubleshooting.md', dest: 'docs/troubleshooting.md', template: false },
214
+ { src: 'shared/docs/architecture.md', dest: 'docs/architecture.md', template: false },
215
+ { src: 'shared/docs/post-deploy-runbook.md', dest: 'docs/post-deploy-runbook.md', template: false },
87
216
  ];
88
217
  const STANDARD_FILES = [
89
218
  // Additional migrations
@@ -105,6 +234,42 @@ const STANDARD_FILES = [
105
234
  { src: 'standard/workers/lib/sentinel/gap-detection.ts', dest: 'workers/lib/sentinel/gap-detection.ts', template: false },
106
235
  // Workers — shared lib (used by standard-tier workers)
107
236
  { src: 'standard/workers/lib/shared/slack-alerts.ts', dest: 'workers/lib/shared/slack-alerts.ts', template: false },
237
+ // Topology mapper (infrastructure discovery + attribution)
238
+ { src: 'standard/migrations/009_topology_mapper.sql', dest: 'storage/d1/migrations/009_topology_mapper.sql', template: false },
239
+ { src: 'standard/wrangler.mapper.jsonc.hbs', dest: 'wrangler.{{projectSlug}}-mapper.jsonc', template: true },
240
+ { src: 'standard/workers/platform-mapper.ts', dest: 'workers/platform-mapper.ts', template: false },
241
+ { src: 'standard/workers/lib/mapper/index.ts', dest: 'workers/lib/mapper/index.ts', template: false },
242
+ { src: 'standard/workers/lib/mapper/attribution-check.ts', dest: 'workers/lib/mapper/attribution-check.ts', template: false },
243
+ // SDK test client (telemetry + circuit breaker validation)
244
+ { src: 'standard/wrangler.sdk-test-client.jsonc.hbs', dest: 'wrangler.{{projectSlug}}-sdk-test-client.jsonc', template: true },
245
+ { src: 'standard/workers/platform-sdk-test-client.ts', dest: 'workers/platform-sdk-test-client.ts', template: false },
246
+ // Dashboard — standard tier (error management, health, DLQ)
247
+ { src: 'standard/dashboard/src/pages/health.astro', dest: 'dashboard/src/pages/health.astro', template: false },
248
+ { src: 'standard/dashboard/src/pages/errors.astro', dest: 'dashboard/src/pages/errors.astro', template: false },
249
+ { src: 'standard/dashboard/src/pages/api/errors/index.ts', dest: 'dashboard/src/pages/api/errors/index.ts', template: false },
250
+ { src: 'standard/dashboard/src/pages/api/errors/stats.ts', dest: 'dashboard/src/pages/api/errors/stats.ts', template: false },
251
+ { src: 'standard/dashboard/src/pages/api/health/dlq.ts', dest: 'dashboard/src/pages/api/health/dlq.ts', template: false },
252
+ { src: 'standard/dashboard/src/components/health/HealthTabs.tsx', dest: 'dashboard/src/components/health/HealthTabs.tsx', template: false },
253
+ { src: 'standard/dashboard/src/components/health/DlqStatusCard.tsx', dest: 'dashboard/src/components/health/DlqStatusCard.tsx', template: false },
254
+ { src: 'standard/dashboard/src/components/health/index.ts', dest: 'dashboard/src/components/health/index.ts', template: false },
255
+ { src: 'standard/dashboard/src/components/errors/ErrorsTable.tsx', dest: 'dashboard/src/components/errors/ErrorsTable.tsx', template: false },
256
+ { src: 'standard/dashboard/src/components/errors/ErrorStats.tsx', dest: 'dashboard/src/components/errors/ErrorStats.tsx', template: false },
257
+ { src: 'standard/dashboard/src/components/errors/index.ts', dest: 'dashboard/src/components/errors/index.ts', template: false },
258
+ { src: 'standard/dashboard/src/lib/errors.ts', dest: 'dashboard/src/lib/errors.ts', template: false },
259
+ // Dashboard — standard tier: error detail API routes (v1.6.0)
260
+ { src: 'standard/dashboard/src/pages/api/errors/[fingerprint].ts', dest: 'dashboard/src/pages/api/errors/[fingerprint].ts', template: false },
261
+ { src: 'standard/dashboard/src/pages/api/errors/[fingerprint]/mute.ts', dest: 'dashboard/src/pages/api/errors/[fingerprint]/mute.ts', template: false },
262
+ { src: 'standard/dashboard/src/pages/api/errors/[fingerprint]/resolve.ts', dest: 'dashboard/src/pages/api/errors/[fingerprint]/resolve.ts', template: false },
263
+ // Dashboard — standard tier: circuit breaker components (v1.6.0)
264
+ { src: 'standard/dashboard/src/components/health/CircuitBreakerPanel.tsx', dest: 'dashboard/src/components/health/CircuitBreakerPanel.tsx', template: false },
265
+ { src: 'standard/dashboard/src/components/health/CircuitBreakerEvents.tsx', dest: 'dashboard/src/components/health/CircuitBreakerEvents.tsx', template: false },
266
+ // Dashboard — standard tier: circuit breakers page (v1.6.0)
267
+ { src: 'standard/dashboard/src/pages/circuit-breakers.astro', dest: 'dashboard/src/pages/circuit-breakers.astro', template: false },
268
+ // Standard tests (v1.7.0)
269
+ { src: 'standard/tests/unit/error-collector/fingerprint.test.ts', dest: 'tests/unit/error-collector/fingerprint.test.ts', template: false },
270
+ { src: 'standard/tests/unit/error-collector/capture.test.ts', dest: 'tests/unit/error-collector/capture.test.ts', template: false },
271
+ // Dashboard — standard tier: audit history API route (v2.0.0)
272
+ { src: 'standard/dashboard/src/pages/api/health/audit-history.ts', dest: 'dashboard/src/pages/api/health/audit-history.ts', template: false },
108
273
  ];
109
274
  const FULL_FILES = [
110
275
  // Additional migrations
@@ -133,6 +298,71 @@ const FULL_FILES = [
133
298
  { src: 'full/workers/platform-search.ts', dest: 'workers/platform-search.ts', template: false },
134
299
  // Workers — platform-settings (settings management API)
135
300
  { src: 'full/workers/platform-settings.ts', dest: 'workers/platform-settings.ts', template: false },
301
+ // Additional migrations — auditor
302
+ { src: 'full/migrations/008_auditor.sql', dest: 'storage/d1/migrations/008_auditor.sql', template: false },
303
+ // Auditor config
304
+ { src: 'full/config/audit-targets.yaml', dest: 'config/audit-targets.yaml', template: false },
305
+ // Wrangler config — auditor
306
+ { src: 'full/wrangler.auditor.jsonc.hbs', dest: 'wrangler.{{projectSlug}}-auditor.jsonc', template: true },
307
+ // Workers — platform-auditor (SDK integration auditor + AI Judge)
308
+ { src: 'full/workers/platform-auditor.ts', dest: 'workers/platform-auditor.ts', template: false },
309
+ { src: 'full/workers/lib/ai-judge-schema.ts', dest: 'workers/lib/ai-judge-schema.ts', template: false },
310
+ { src: 'full/workers/lib/auditor/index.ts', dest: 'workers/lib/auditor/index.ts', template: false },
311
+ { src: 'full/workers/lib/auditor/types.ts', dest: 'workers/lib/auditor/types.ts', template: false },
312
+ { src: 'full/workers/lib/auditor/feature-coverage.ts', dest: 'workers/lib/auditor/feature-coverage.ts', template: false },
313
+ { src: 'full/workers/lib/auditor/comprehensive-report.ts', dest: 'workers/lib/auditor/comprehensive-report.ts', template: false },
314
+ // Pricing version tracking
315
+ { src: 'full/migrations/010_pricing_versions.sql', dest: 'storage/d1/migrations/010_pricing_versions.sql', template: false },
316
+ // Multi-account Cloudflare support
317
+ { src: 'full/migrations/011_multi_account.sql', dest: 'storage/d1/migrations/011_multi_account.sql', template: false },
318
+ // KV pricing configuration script
319
+ { src: 'full/scripts/ops/set-kv-pricing.ts', dest: 'scripts/ops/set-kv-pricing.ts', template: false },
320
+ // Universal backfill cascade (v1.8.0)
321
+ { src: 'full/scripts/ops/universal-backfill.ts', dest: 'scripts/ops/universal-backfill.ts', template: false },
322
+ // Dashboard — full tier (patterns, notifications, search)
323
+ { src: 'full/dashboard/src/pages/notifications.astro', dest: 'dashboard/src/pages/notifications.astro', template: false },
324
+ { src: 'full/dashboard/src/pages/api/patterns/index.ts', dest: 'dashboard/src/pages/api/patterns/index.ts', template: false },
325
+ { src: 'full/dashboard/src/pages/api/patterns/approve.ts', dest: 'dashboard/src/pages/api/patterns/approve.ts', template: false },
326
+ { src: 'full/dashboard/src/pages/api/patterns/reject.ts', dest: 'dashboard/src/pages/api/patterns/reject.ts', template: false },
327
+ { src: 'full/dashboard/src/pages/api/notifications/index.ts', dest: 'dashboard/src/pages/api/notifications/index.ts', template: false },
328
+ { src: 'full/dashboard/src/pages/api/notifications/unread-count.ts', dest: 'dashboard/src/pages/api/notifications/unread-count.ts', template: false },
329
+ { src: 'full/dashboard/src/pages/api/search/index.ts', dest: 'dashboard/src/pages/api/search/index.ts', template: false },
330
+ { src: 'full/dashboard/src/components/patterns/SuggestionsQueue.tsx', dest: 'dashboard/src/components/patterns/SuggestionsQueue.tsx', template: false },
331
+ { src: 'full/dashboard/src/components/patterns/PatternStats.tsx', dest: 'dashboard/src/components/patterns/PatternStats.tsx', template: false },
332
+ { src: 'full/dashboard/src/components/patterns/index.ts', dest: 'dashboard/src/components/patterns/index.ts', template: false },
333
+ { src: 'full/dashboard/src/components/notifications/NotificationBell.tsx', dest: 'dashboard/src/components/notifications/NotificationBell.tsx', template: false },
334
+ { src: 'full/dashboard/src/components/notifications/NotificationList.tsx', dest: 'dashboard/src/components/notifications/NotificationList.tsx', template: false },
335
+ { src: 'full/dashboard/src/components/notifications/index.ts', dest: 'dashboard/src/components/notifications/index.ts', template: false },
336
+ { src: 'full/dashboard/src/components/search/SearchModal.tsx', dest: 'dashboard/src/components/search/SearchModal.tsx', template: false },
337
+ // Dashboard — full tier: pattern tabs component (v1.6.0)
338
+ { src: 'full/dashboard/src/components/patterns/PatternTabs.tsx', dest: 'dashboard/src/components/patterns/PatternTabs.tsx', template: false },
339
+ // Dashboard — full tier: additional pattern API routes (v2.0.0)
340
+ { src: 'full/dashboard/src/pages/api/patterns/discover.ts', dest: 'dashboard/src/pages/api/patterns/discover.ts', template: false },
341
+ { src: 'full/dashboard/src/pages/api/patterns/suggestions.ts', dest: 'dashboard/src/pages/api/patterns/suggestions.ts', template: false },
342
+ { src: 'full/dashboard/src/pages/api/patterns/ready-for-review.ts', dest: 'dashboard/src/pages/api/patterns/ready-for-review.ts', template: false },
343
+ { src: 'full/dashboard/src/pages/api/patterns/cache-refresh.ts', dest: 'dashboard/src/pages/api/patterns/cache-refresh.ts', template: false },
344
+ { src: 'full/dashboard/src/pages/api/patterns/stats.ts', dest: 'dashboard/src/pages/api/patterns/stats.ts', template: false },
345
+ // Dashboard — full tier: settings API routes (v2.0.0)
346
+ { src: 'full/dashboard/src/pages/api/settings/index.ts', dest: 'dashboard/src/pages/api/settings/index.ts', template: false },
347
+ { src: 'full/dashboard/src/pages/api/settings/update.ts', dest: 'dashboard/src/pages/api/settings/update.ts', template: false },
348
+ // Dashboard — full tier: notification management (v2.0.0)
349
+ { src: 'full/dashboard/src/pages/api/notifications/[id]/read.ts', dest: 'dashboard/src/pages/api/notifications/[id]/read.ts', template: false },
350
+ { src: 'full/dashboard/src/pages/api/notifications/read-all.ts', dest: 'dashboard/src/pages/api/notifications/read-all.ts', template: false },
351
+ // Dashboard — full tier: search API routes (v2.0.0)
352
+ { src: 'full/dashboard/src/pages/api/search/reindex.ts', dest: 'dashboard/src/pages/api/search/reindex.ts', template: false },
353
+ { src: 'full/dashboard/src/pages/api/search/stats.ts', dest: 'dashboard/src/pages/api/search/stats.ts', template: false },
354
+ // Dashboard — full tier: reports API routes (v2.0.0)
355
+ { src: 'full/dashboard/src/pages/api/reports/audit.ts', dest: 'dashboard/src/pages/api/reports/audit.ts', template: false },
356
+ { src: 'full/dashboard/src/pages/api/reports/usage.ts', dest: 'dashboard/src/pages/api/reports/usage.ts', template: false },
357
+ // Dashboard — full tier: topology API route (v2.0.0)
358
+ { src: 'full/dashboard/src/pages/api/topology/index.ts', dest: 'dashboard/src/pages/api/topology/index.ts', template: false },
359
+ // Dashboard — full tier: additional pattern components (v2.0.0)
360
+ { src: 'full/dashboard/src/components/patterns/ActivePatterns.tsx', dest: 'dashboard/src/components/patterns/ActivePatterns.tsx', template: false },
361
+ { src: 'full/dashboard/src/components/patterns/SystemPatterns.tsx', dest: 'dashboard/src/components/patterns/SystemPatterns.tsx', template: false },
362
+ // Dashboard — full tier: reports components (v2.0.0)
363
+ { src: 'full/dashboard/src/components/reports/SdkAuditReport.tsx', dest: 'dashboard/src/components/reports/SdkAuditReport.tsx', template: false },
364
+ { src: 'full/dashboard/src/components/reports/GapDetectionReport.tsx', dest: 'dashboard/src/components/reports/GapDetectionReport.tsx', template: false },
365
+ { src: 'full/dashboard/src/components/reports/index.ts', dest: 'dashboard/src/components/reports/index.ts', template: false },
136
366
  ];
137
367
  export function getFilesForTier(tier) {
138
368
  const files = [...SHARED_FILES];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@littlebearapps/platform-admin-sdk",
3
- "version": "1.4.2",
3
+ "version": "2.0.0",
4
4
  "description": "Platform Admin SDK — scaffold backend infrastructure with workers, circuit breakers, and cost protection for Cloudflare",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,72 @@
1
+ # =============================================================================
2
+ # Audit Targets Configuration
3
+ # =============================================================================
4
+ # Define the projects that the platform-auditor worker should audit.
5
+ # Sync this to KV via: npm run sync:config
6
+ #
7
+ # Each target specifies:
8
+ # repo — GitHub org/repo path (for fetching source files)
9
+ # wranglerPath — Path to main wrangler config (for config checks)
10
+ # entryPoint — Primary SDK integration file (for code smell detection)
11
+ # expectedStatus — Expected audit result: HEALTHY, ZOMBIE, UNTRACKED, BROKEN
12
+ # notes — Human-readable description
13
+ # deepScanFiles — Files per audit dimension (for AI Judge analysis)
14
+ #
15
+ # Status definitions:
16
+ # HEALTHY — SDK integrated, heartbeats fresh, config correct
17
+ # ZOMBIE — Was integrated but dormant (no recent heartbeats)
18
+ # UNTRACKED — Running in production but not using SDK
19
+ # BROKEN — SDK integration present but misconfigured
20
+ # NOT_INTEGRATED — No SDK integration detected
21
+ # =============================================================================
22
+
23
+ targets: {}
24
+ # Example target (uncomment and customise):
25
+ #
26
+ # my-project:
27
+ # repo: my-org/my-project
28
+ # wranglerPath: wrangler.jsonc
29
+ # entryPoint: src/index.ts
30
+ # entryPointFallback: src/worker.ts
31
+ # expectedStatus: HEALTHY
32
+ # notes: Main application worker
33
+ # deepScanFiles:
34
+ # sdk:
35
+ # - src/index.ts
36
+ # - src/middleware/platform-sdk.ts
37
+ # - src/lib/features.ts
38
+ # observability:
39
+ # - src/lib/logger.ts
40
+ # - src/middleware/tracing.ts
41
+ # cost:
42
+ # - src/lib/budgets.ts
43
+ # - src/middleware/circuit-breaker.ts
44
+ # security:
45
+ # - src/middleware/auth.ts
46
+ # - src/lib/validation.ts
47
+
48
+ # SDK patterns to detect in source code (for code smell checks)
49
+ sdkPatterns:
50
+ - withFeatureBudget
51
+ - withCronBudget
52
+ - withQueueBudget
53
+ - trackedEnv
54
+ - platform-sdk
55
+ - completeTracking
56
+ - CircuitBreakerError
57
+ - PLATFORM_CACHE
58
+ - PLATFORM_TELEMETRY
59
+
60
+ # Rubric weights for composite score calculation (must sum to 1.0)
61
+ rubricWeights:
62
+ sdk: 0.3
63
+ observability: 0.25
64
+ costProtection: 0.25
65
+ security: 0.2
66
+
67
+ # Thresholds
68
+ heartbeatFreshnessHours: 24
69
+ focusedScanThreshold: 90
70
+ aiCacheTtlSeconds: 259200 # 3 days
71
+ behavioralAnalysisDays: 30
72
+ hotspotMinCommits: 3
@@ -0,0 +1,30 @@
1
+ import { useState, useEffect, useRef } from 'react';
2
+
3
+ export function NotificationBell() {
4
+ const [count, setCount] = useState(0);
5
+ const intervalRef = useRef<ReturnType<typeof setInterval>>();
6
+
7
+ useEffect(() => {
8
+ function fetchCount() {
9
+ fetch('/api/notifications/unread-count')
10
+ .then(res => res.json())
11
+ .then((data: { count: number }) => setCount(data.count ?? 0))
12
+ .catch(() => {});
13
+ }
14
+
15
+ fetchCount();
16
+ intervalRef.current = setInterval(fetchCount, 30000);
17
+ return () => clearInterval(intervalRef.current);
18
+ }, []);
19
+
20
+ return (
21
+ <a href="/notifications" className="relative p-2 rounded-md text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700">
22
+ <span className="text-lg">&#128276;</span>
23
+ {count > 0 && (
24
+ <span className="absolute -top-1 -right-1 inline-flex items-center justify-center w-5 h-5 text-xs font-bold text-white bg-red-500 rounded-full">
25
+ {count > 99 ? '99+' : count}
26
+ </span>
27
+ )}
28
+ </a>
29
+ );
30
+ }
@@ -0,0 +1,116 @@
1
+ import { useState, useEffect } from 'react';
2
+
3
+ interface Notification {
4
+ id: string;
5
+ title: string;
6
+ body: string | null;
7
+ category: string;
8
+ priority: string;
9
+ source: string;
10
+ created_at: number;
11
+ read_at: number | null;
12
+ action_url: string | null;
13
+ }
14
+
15
+ export function NotificationList() {
16
+ const [notifications, setNotifications] = useState<Notification[]>([]);
17
+ const [total, setTotal] = useState(0);
18
+ const [page, setPage] = useState(1);
19
+
20
+ useEffect(() => {
21
+ fetch(`/api/notifications?page=${page}&limit=20`)
22
+ .then(res => res.json())
23
+ .then((data: { notifications: Notification[]; total: number }) => {
24
+ setNotifications(data.notifications ?? []);
25
+ setTotal(data.total ?? 0);
26
+ })
27
+ .catch(() => {});
28
+ }, [page]);
29
+
30
+ function formatTime(ts: number): string {
31
+ const now = Date.now();
32
+ const diffMs = now - ts * 1000;
33
+ const diffMins = Math.floor(diffMs / 60000);
34
+ const diffHours = Math.floor(diffMs / 3600000);
35
+ const diffDays = Math.floor(diffMs / 86400000);
36
+
37
+ if (diffMins < 1) return 'Just now';
38
+ if (diffMins < 60) return `${diffMins}m ago`;
39
+ if (diffHours < 24) return `${diffHours}h ago`;
40
+ if (diffDays < 7) return `${diffDays}d ago`;
41
+ return new Date(ts * 1000).toLocaleDateString('en-AU', { day: 'numeric', month: 'short' });
42
+ }
43
+
44
+ const categoryIcons: Record<string, string> = {
45
+ error: '[ERR]',
46
+ warning: '[WARN]',
47
+ info: '[INFO]',
48
+ success: '[OK]',
49
+ };
50
+
51
+ return (
52
+ <div className="space-y-3">
53
+ {notifications.length === 0 ? (
54
+ <div className="text-center py-8 text-gray-500 dark:text-gray-400">
55
+ No notifications.
56
+ </div>
57
+ ) : (
58
+ notifications.map(n => (
59
+ <div
60
+ key={n.id}
61
+ className={`bg-white dark:bg-gray-800 rounded-lg border p-4 ${
62
+ n.read_at ? 'border-gray-200 dark:border-gray-700' : 'border-blue-300 dark:border-blue-700'
63
+ }`}
64
+ >
65
+ <div className="flex items-start gap-3">
66
+ <span className="text-xs font-mono text-gray-500 dark:text-gray-400 mt-0.5">
67
+ {categoryIcons[n.category] ?? '[INFO]'}
68
+ </span>
69
+ <div className="flex-1 min-w-0">
70
+ <div className="flex items-center justify-between gap-2">
71
+ <h4 className="text-sm font-medium text-gray-900 dark:text-white truncate">
72
+ {n.action_url ? (
73
+ <a href={n.action_url} className="hover:text-blue-600 dark:hover:text-blue-400">{n.title}</a>
74
+ ) : n.title}
75
+ </h4>
76
+ <span className="text-xs text-gray-400 dark:text-gray-500 flex-shrink-0">
77
+ {formatTime(n.created_at)}
78
+ </span>
79
+ </div>
80
+ {n.body && (
81
+ <p className="text-xs text-gray-500 dark:text-gray-400 mt-1 line-clamp-2">{n.body}</p>
82
+ )}
83
+ <div className="flex items-center gap-2 mt-1.5">
84
+ <span className="text-xs text-gray-400 dark:text-gray-500">{n.source}</span>
85
+ <span className="text-xs text-gray-400 dark:text-gray-500">{n.priority}</span>
86
+ </div>
87
+ </div>
88
+ </div>
89
+ </div>
90
+ ))
91
+ )}
92
+
93
+ {total > 20 && (
94
+ <div className="flex items-center justify-between pt-2">
95
+ <button
96
+ onClick={() => setPage(p => Math.max(1, p - 1))}
97
+ disabled={page === 1}
98
+ className="text-sm text-blue-600 dark:text-blue-400 disabled:opacity-50"
99
+ >
100
+ Previous
101
+ </button>
102
+ <span className="text-sm text-gray-500 dark:text-gray-400">
103
+ Page {page} of {Math.ceil(total / 20)}
104
+ </span>
105
+ <button
106
+ onClick={() => setPage(p => p + 1)}
107
+ disabled={page >= Math.ceil(total / 20)}
108
+ className="text-sm text-blue-600 dark:text-blue-400 disabled:opacity-50"
109
+ >
110
+ Next
111
+ </button>
112
+ </div>
113
+ )}
114
+ </div>
115
+ );
116
+ }
@@ -0,0 +1,2 @@
1
+ export { NotificationBell } from './NotificationBell';
2
+ export { NotificationList } from './NotificationList';
@@ -0,0 +1,62 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { LoadingSkeleton } from '../../components/ui/LoadingSkeleton';
3
+ import { EmptyState } from '../../components/ui/EmptyState';
4
+
5
+ interface Pattern {
6
+ id: number;
7
+ pattern_type: string;
8
+ pattern_value: string;
9
+ error_type: string;
10
+ priority: string;
11
+ match_count: number;
12
+ source: string;
13
+ is_protected: number;
14
+ }
15
+
16
+ export function ActivePatterns() {
17
+ const [patterns, setPatterns] = useState<Pattern[]>([]);
18
+ const [loading, setLoading] = useState(true);
19
+
20
+ useEffect(() => {
21
+ fetch('/api/patterns/suggestions?status=approved&limit=50')
22
+ .then((r) => r.json())
23
+ .then((data: { suggestions: Pattern[] }) => {
24
+ setPatterns(data.suggestions ?? []);
25
+ setLoading(false);
26
+ })
27
+ .catch(() => setLoading(false));
28
+ }, []);
29
+
30
+ if (loading) return <LoadingSkeleton lines={4} />;
31
+ if (patterns.length === 0) return <EmptyState title="No active patterns" description="Approved patterns will appear here." />;
32
+
33
+ return (
34
+ <div className="space-y-2">
35
+ {patterns.map((p) => (
36
+ <div
37
+ key={p.id}
38
+ className="flex items-center justify-between gap-3 py-2 px-3 bg-white dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700"
39
+ >
40
+ <div className="min-w-0">
41
+ <div className="flex items-center gap-2">
42
+ <span className="text-sm font-mono text-gray-900 dark:text-white truncate">{p.pattern_value}</span>
43
+ {p.is_protected === 1 && (
44
+ <span className="text-[10px] px-1.5 py-0.5 rounded bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400">
45
+ protected
46
+ </span>
47
+ )}
48
+ </div>
49
+ <div className="flex gap-3 mt-0.5 text-xs text-gray-500 dark:text-gray-400">
50
+ <span>{p.pattern_type}</span>
51
+ <span>{p.source}</span>
52
+ <span>Matches: {p.match_count}</span>
53
+ </div>
54
+ </div>
55
+ <span className="text-xs px-2 py-0.5 rounded bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300 shrink-0">
56
+ {p.priority}
57
+ </span>
58
+ </div>
59
+ ))}
60
+ </div>
61
+ );
62
+ }