nuxt-observe 0.0.2

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 (435) hide show
  1. package/README.md +92 -0
  2. package/dist/module.d.mts +7 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +393 -0
  5. package/dist/runtime/app/assets/css/main.css +1 -0
  6. package/dist/runtime/app/components/ObserveActivityFeed.d.vue.ts +13 -0
  7. package/dist/runtime/app/components/ObserveActivityFeed.vue +77 -0
  8. package/dist/runtime/app/components/ObserveActivityFeed.vue.d.ts +13 -0
  9. package/dist/runtime/app/components/ObserveActivityTable.d.vue.ts +30 -0
  10. package/dist/runtime/app/components/ObserveActivityTable.vue +187 -0
  11. package/dist/runtime/app/components/ObserveActivityTable.vue.d.ts +30 -0
  12. package/dist/runtime/app/components/ObserveCan.d.vue.ts +27 -0
  13. package/dist/runtime/app/components/ObserveCan.vue +16 -0
  14. package/dist/runtime/app/components/ObserveCan.vue.d.ts +27 -0
  15. package/dist/runtime/app/components/ObserveErrorsTable.d.vue.ts +19 -0
  16. package/dist/runtime/app/components/ObserveErrorsTable.vue +105 -0
  17. package/dist/runtime/app/components/ObserveErrorsTable.vue.d.ts +19 -0
  18. package/dist/runtime/app/components/ObserveHealthHero.d.vue.ts +16 -0
  19. package/dist/runtime/app/components/ObserveHealthHero.vue +114 -0
  20. package/dist/runtime/app/components/ObserveHealthHero.vue.d.ts +16 -0
  21. package/dist/runtime/app/components/ObserveJourneySearch.d.vue.ts +13 -0
  22. package/dist/runtime/app/components/ObserveJourneySearch.vue +55 -0
  23. package/dist/runtime/app/components/ObserveJourneySearch.vue.d.ts +13 -0
  24. package/dist/runtime/app/components/ObserveJourneyTimeline.d.vue.ts +14 -0
  25. package/dist/runtime/app/components/ObserveJourneyTimeline.vue +119 -0
  26. package/dist/runtime/app/components/ObserveJourneyTimeline.vue.d.ts +14 -0
  27. package/dist/runtime/app/components/ObserveLogDetail.d.vue.ts +12 -0
  28. package/dist/runtime/app/components/ObserveLogDetail.vue +187 -0
  29. package/dist/runtime/app/components/ObserveLogDetail.vue.d.ts +12 -0
  30. package/dist/runtime/app/components/ObserveLogLevelBadge.d.vue.ts +10 -0
  31. package/dist/runtime/app/components/ObserveLogLevelBadge.vue +29 -0
  32. package/dist/runtime/app/components/ObserveLogLevelBadge.vue.d.ts +10 -0
  33. package/dist/runtime/app/components/ObserveLogsFilterBar.d.vue.ts +20 -0
  34. package/dist/runtime/app/components/ObserveLogsFilterBar.vue +134 -0
  35. package/dist/runtime/app/components/ObserveLogsFilterBar.vue.d.ts +20 -0
  36. package/dist/runtime/app/components/ObserveLogsTable.d.vue.ts +20 -0
  37. package/dist/runtime/app/components/ObserveLogsTable.vue +92 -0
  38. package/dist/runtime/app/components/ObserveLogsTable.vue.d.ts +20 -0
  39. package/dist/runtime/app/components/ObservePeriodSelector.d.vue.ts +3 -0
  40. package/dist/runtime/app/components/ObservePeriodSelector.vue +22 -0
  41. package/dist/runtime/app/components/ObservePeriodSelector.vue.d.ts +3 -0
  42. package/dist/runtime/app/components/ObserveRegressionAlert.d.vue.ts +12 -0
  43. package/dist/runtime/app/components/ObserveRegressionAlert.vue +27 -0
  44. package/dist/runtime/app/components/ObserveRegressionAlert.vue.d.ts +12 -0
  45. package/dist/runtime/app/components/ObserveServiceSwitcher.d.vue.ts +3 -0
  46. package/dist/runtime/app/components/ObserveServiceSwitcher.vue +49 -0
  47. package/dist/runtime/app/components/ObserveServiceSwitcher.vue.d.ts +3 -0
  48. package/dist/runtime/app/components/ObserveServicesTable.d.vue.ts +15 -0
  49. package/dist/runtime/app/components/ObserveServicesTable.vue +109 -0
  50. package/dist/runtime/app/components/ObserveServicesTable.vue.d.ts +15 -0
  51. package/dist/runtime/app/components/ObserveStatCard.d.vue.ts +14 -0
  52. package/dist/runtime/app/components/ObserveStatCard.vue +34 -0
  53. package/dist/runtime/app/components/ObserveStatCard.vue.d.ts +14 -0
  54. package/dist/runtime/app/components/charts/ObserveErrorRateChart.client.d.vue.ts +15 -0
  55. package/dist/runtime/app/components/charts/ObserveErrorRateChart.client.vue +170 -0
  56. package/dist/runtime/app/components/charts/ObserveErrorRateChart.client.vue.d.ts +15 -0
  57. package/dist/runtime/app/components/charts/ObserveServiceBreakdownChart.client.d.vue.ts +17 -0
  58. package/dist/runtime/app/components/charts/ObserveServiceBreakdownChart.client.vue +208 -0
  59. package/dist/runtime/app/components/charts/ObserveServiceBreakdownChart.client.vue.d.ts +17 -0
  60. package/dist/runtime/app/components/charts/ObserveVersionAdoptionChart.client.d.vue.ts +14 -0
  61. package/dist/runtime/app/components/charts/ObserveVersionAdoptionChart.client.vue +208 -0
  62. package/dist/runtime/app/components/charts/ObserveVersionAdoptionChart.client.vue.d.ts +14 -0
  63. package/dist/runtime/app/components/charts/ObserveVersionCompareChart.client.d.vue.ts +14 -0
  64. package/dist/runtime/app/components/charts/ObserveVersionCompareChart.client.vue +190 -0
  65. package/dist/runtime/app/components/charts/ObserveVersionCompareChart.client.vue.d.ts +14 -0
  66. package/dist/runtime/app/components/charts/ObserveVolumeChart.client.d.vue.ts +16 -0
  67. package/dist/runtime/app/components/charts/ObserveVolumeChart.client.vue +199 -0
  68. package/dist/runtime/app/components/charts/ObserveVolumeChart.client.vue.d.ts +16 -0
  69. package/dist/runtime/app/components/charts/chart-core.d.ts +64 -0
  70. package/dist/runtime/app/components/charts/chart-core.js +136 -0
  71. package/dist/runtime/app/components/settings/ObserveApiKeyPanel.d.vue.ts +8 -0
  72. package/dist/runtime/app/components/settings/ObserveApiKeyPanel.vue +145 -0
  73. package/dist/runtime/app/components/settings/ObserveApiKeyPanel.vue.d.ts +8 -0
  74. package/dist/runtime/app/components/settings/ObserveApiKeyRevealModal.d.vue.ts +19 -0
  75. package/dist/runtime/app/components/settings/ObserveApiKeyRevealModal.vue +106 -0
  76. package/dist/runtime/app/components/settings/ObserveApiKeyRevealModal.vue.d.ts +19 -0
  77. package/dist/runtime/app/components/settings/ObserveAssignmentEditor.d.vue.ts +12 -0
  78. package/dist/runtime/app/components/settings/ObserveAssignmentEditor.vue +67 -0
  79. package/dist/runtime/app/components/settings/ObserveAssignmentEditor.vue.d.ts +12 -0
  80. package/dist/runtime/app/components/settings/ObserveGroupFormModal.d.vue.ts +18 -0
  81. package/dist/runtime/app/components/settings/ObserveGroupFormModal.vue +60 -0
  82. package/dist/runtime/app/components/settings/ObserveGroupFormModal.vue.d.ts +18 -0
  83. package/dist/runtime/app/components/settings/ObserveGroupMembershipEditor.d.vue.ts +20 -0
  84. package/dist/runtime/app/components/settings/ObserveGroupMembershipEditor.vue +21 -0
  85. package/dist/runtime/app/components/settings/ObserveGroupMembershipEditor.vue.d.ts +20 -0
  86. package/dist/runtime/app/components/settings/ObserveOriginAllowlistEditor.d.vue.ts +15 -0
  87. package/dist/runtime/app/components/settings/ObserveOriginAllowlistEditor.vue +63 -0
  88. package/dist/runtime/app/components/settings/ObserveOriginAllowlistEditor.vue.d.ts +15 -0
  89. package/dist/runtime/app/components/settings/ObserveServiceEditForm.d.vue.ts +38 -0
  90. package/dist/runtime/app/components/settings/ObserveServiceEditForm.vue +216 -0
  91. package/dist/runtime/app/components/settings/ObserveServiceEditForm.vue.d.ts +38 -0
  92. package/dist/runtime/app/components/settings/ObserveServiceFormModal.d.vue.ts +37 -0
  93. package/dist/runtime/app/components/settings/ObserveServiceFormModal.vue +192 -0
  94. package/dist/runtime/app/components/settings/ObserveServiceFormModal.vue.d.ts +37 -0
  95. package/dist/runtime/app/components/settings/ObserveServiceTypeBadge.d.vue.ts +11 -0
  96. package/dist/runtime/app/components/settings/ObserveServiceTypeBadge.vue +18 -0
  97. package/dist/runtime/app/components/settings/ObserveServiceTypeBadge.vue.d.ts +11 -0
  98. package/dist/runtime/app/components/settings/ObserveSettingsServicesTable.d.vue.ts +19 -0
  99. package/dist/runtime/app/components/settings/ObserveSettingsServicesTable.vue +132 -0
  100. package/dist/runtime/app/components/settings/ObserveSettingsServicesTable.vue.d.ts +19 -0
  101. package/dist/runtime/app/components/settings/ObserveUserFormModal.d.vue.ts +27 -0
  102. package/dist/runtime/app/components/settings/ObserveUserFormModal.vue +108 -0
  103. package/dist/runtime/app/components/settings/ObserveUserFormModal.vue.d.ts +27 -0
  104. package/dist/runtime/app/components/settings/ObserveVersionTrackingField.d.vue.ts +17 -0
  105. package/dist/runtime/app/components/settings/ObserveVersionTrackingField.vue +20 -0
  106. package/dist/runtime/app/components/settings/ObserveVersionTrackingField.vue.d.ts +17 -0
  107. package/dist/runtime/app/composables/useObserveAbility.d.ts +15 -0
  108. package/dist/runtime/app/composables/useObserveAbility.js +20 -0
  109. package/dist/runtime/app/composables/useObserveActivity.d.ts +22 -0
  110. package/dist/runtime/app/composables/useObserveActivity.js +44 -0
  111. package/dist/runtime/app/composables/useObserveApiKeys.d.ts +15 -0
  112. package/dist/runtime/app/composables/useObserveApiKeys.js +19 -0
  113. package/dist/runtime/app/composables/useObserveAssignments.d.ts +19 -0
  114. package/dist/runtime/app/composables/useObserveAssignments.js +16 -0
  115. package/dist/runtime/app/composables/useObserveErrors.d.ts +33 -0
  116. package/dist/runtime/app/composables/useObserveErrors.js +85 -0
  117. package/dist/runtime/app/composables/useObserveGroups.d.ts +27 -0
  118. package/dist/runtime/app/composables/useObserveGroups.js +33 -0
  119. package/dist/runtime/app/composables/useObserveJourney.d.ts +19 -0
  120. package/dist/runtime/app/composables/useObserveJourney.js +19 -0
  121. package/dist/runtime/app/composables/useObserveLogFacets.d.ts +11 -0
  122. package/dist/runtime/app/composables/useObserveLogFacets.js +21 -0
  123. package/dist/runtime/app/composables/useObserveLogs.d.ts +28 -0
  124. package/dist/runtime/app/composables/useObserveLogs.js +100 -0
  125. package/dist/runtime/app/composables/useObserveMigrations.d.ts +17 -0
  126. package/dist/runtime/app/composables/useObserveMigrations.js +49 -0
  127. package/dist/runtime/app/composables/useObserveOverview.d.ts +14 -0
  128. package/dist/runtime/app/composables/useObserveOverview.js +23 -0
  129. package/dist/runtime/app/composables/useObservePeriod.d.ts +11 -0
  130. package/dist/runtime/app/composables/useObservePeriod.js +18 -0
  131. package/dist/runtime/app/composables/useObserveRollout.d.ts +20 -0
  132. package/dist/runtime/app/composables/useObserveRollout.js +55 -0
  133. package/dist/runtime/app/composables/useObserveScope.d.ts +13 -0
  134. package/dist/runtime/app/composables/useObserveScope.js +17 -0
  135. package/dist/runtime/app/composables/useObserveServices.d.ts +26 -0
  136. package/dist/runtime/app/composables/useObserveServices.js +33 -0
  137. package/dist/runtime/app/composables/useObserveStats.d.ts +14 -0
  138. package/dist/runtime/app/composables/useObserveStats.js +23 -0
  139. package/dist/runtime/app/composables/useObserveUsers.d.ts +29 -0
  140. package/dist/runtime/app/composables/useObserveUsers.js +33 -0
  141. package/dist/runtime/app/layouts/observe.d.vue.ts +13 -0
  142. package/dist/runtime/app/layouts/observe.vue +138 -0
  143. package/dist/runtime/app/layouts/observe.vue.d.ts +13 -0
  144. package/dist/runtime/app/middleware/observe-auth.global.d.ts +9 -0
  145. package/dist/runtime/app/middleware/observe-auth.global.js +8 -0
  146. package/dist/runtime/app/pages/activity.d.vue.ts +3 -0
  147. package/dist/runtime/app/pages/activity.vue +54 -0
  148. package/dist/runtime/app/pages/activity.vue.d.ts +3 -0
  149. package/dist/runtime/app/pages/error-detail.d.vue.ts +3 -0
  150. package/dist/runtime/app/pages/error-detail.vue +190 -0
  151. package/dist/runtime/app/pages/error-detail.vue.d.ts +3 -0
  152. package/dist/runtime/app/pages/errors.d.vue.ts +3 -0
  153. package/dist/runtime/app/pages/errors.vue +47 -0
  154. package/dist/runtime/app/pages/errors.vue.d.ts +3 -0
  155. package/dist/runtime/app/pages/journey.d.vue.ts +3 -0
  156. package/dist/runtime/app/pages/journey.vue +96 -0
  157. package/dist/runtime/app/pages/journey.vue.d.ts +3 -0
  158. package/dist/runtime/app/pages/log-detail.d.vue.ts +3 -0
  159. package/dist/runtime/app/pages/log-detail.vue +35 -0
  160. package/dist/runtime/app/pages/log-detail.vue.d.ts +3 -0
  161. package/dist/runtime/app/pages/login.d.vue.ts +3 -0
  162. package/dist/runtime/app/pages/login.vue +69 -0
  163. package/dist/runtime/app/pages/login.vue.d.ts +3 -0
  164. package/dist/runtime/app/pages/logs.d.vue.ts +3 -0
  165. package/dist/runtime/app/pages/logs.vue +36 -0
  166. package/dist/runtime/app/pages/logs.vue.d.ts +3 -0
  167. package/dist/runtime/app/pages/metrics.d.vue.ts +3 -0
  168. package/dist/runtime/app/pages/metrics.vue +68 -0
  169. package/dist/runtime/app/pages/metrics.vue.d.ts +3 -0
  170. package/dist/runtime/app/pages/overview.d.vue.ts +3 -0
  171. package/dist/runtime/app/pages/overview.vue +65 -0
  172. package/dist/runtime/app/pages/overview.vue.d.ts +3 -0
  173. package/dist/runtime/app/pages/rollout.d.vue.ts +3 -0
  174. package/dist/runtime/app/pages/rollout.vue +188 -0
  175. package/dist/runtime/app/pages/rollout.vue.d.ts +3 -0
  176. package/dist/runtime/app/pages/settings/group-detail.d.vue.ts +3 -0
  177. package/dist/runtime/app/pages/settings/group-detail.vue +149 -0
  178. package/dist/runtime/app/pages/settings/group-detail.vue.d.ts +3 -0
  179. package/dist/runtime/app/pages/settings/groups.d.vue.ts +3 -0
  180. package/dist/runtime/app/pages/settings/groups.vue +107 -0
  181. package/dist/runtime/app/pages/settings/groups.vue.d.ts +3 -0
  182. package/dist/runtime/app/pages/settings/index.d.vue.ts +3 -0
  183. package/dist/runtime/app/pages/settings/index.vue +47 -0
  184. package/dist/runtime/app/pages/settings/index.vue.d.ts +3 -0
  185. package/dist/runtime/app/pages/settings/migrations.d.vue.ts +3 -0
  186. package/dist/runtime/app/pages/settings/migrations.vue +275 -0
  187. package/dist/runtime/app/pages/settings/migrations.vue.d.ts +3 -0
  188. package/dist/runtime/app/pages/settings/service-detail.d.vue.ts +3 -0
  189. package/dist/runtime/app/pages/settings/service-detail.vue +133 -0
  190. package/dist/runtime/app/pages/settings/service-detail.vue.d.ts +3 -0
  191. package/dist/runtime/app/pages/settings/services.d.vue.ts +3 -0
  192. package/dist/runtime/app/pages/settings/services.vue +66 -0
  193. package/dist/runtime/app/pages/settings/services.vue.d.ts +3 -0
  194. package/dist/runtime/app/pages/settings/users/[id].d.vue.ts +3 -0
  195. package/dist/runtime/app/pages/settings/users/[id].vue +243 -0
  196. package/dist/runtime/app/pages/settings/users/[id].vue.d.ts +3 -0
  197. package/dist/runtime/app/pages/settings/users/index.d.vue.ts +3 -0
  198. package/dist/runtime/app/pages/settings/users/index.vue +129 -0
  199. package/dist/runtime/app/pages/settings/users/index.vue.d.ts +3 -0
  200. package/dist/runtime/options.d.ts +1 -0
  201. package/dist/runtime/options.js +1 -0
  202. package/dist/runtime/server/api/observe/activity.get.d.ts +3 -0
  203. package/dist/runtime/server/api/observe/activity.get.js +30 -0
  204. package/dist/runtime/server/api/observe/auth/login.post.d.ts +4 -0
  205. package/dist/runtime/server/api/observe/auth/login.post.js +13 -0
  206. package/dist/runtime/server/api/observe/auth/logout.post.d.ts +4 -0
  207. package/dist/runtime/server/api/observe/auth/logout.post.js +6 -0
  208. package/dist/runtime/server/api/observe/auth/me.get.d.ts +2 -0
  209. package/dist/runtime/server/api/observe/auth/me.get.js +3 -0
  210. package/dist/runtime/server/api/observe/errors/[fingerprint].get.d.ts +3 -0
  211. package/dist/runtime/server/api/observe/errors/[fingerprint].get.js +56 -0
  212. package/dist/runtime/server/api/observe/errors/index.get.d.ts +3 -0
  213. package/dist/runtime/server/api/observe/errors/index.get.js +41 -0
  214. package/dist/runtime/server/api/observe/facets.get.d.ts +8 -0
  215. package/dist/runtime/server/api/observe/facets.get.js +12 -0
  216. package/dist/runtime/server/api/observe/groups/[id]/assignments.put.d.ts +3 -0
  217. package/dist/runtime/server/api/observe/groups/[id]/assignments.put.js +12 -0
  218. package/dist/runtime/server/api/observe/groups/[id]/services.put.d.ts +5 -0
  219. package/dist/runtime/server/api/observe/groups/[id]/services.put.js +13 -0
  220. package/dist/runtime/server/api/observe/groups/[id].delete.d.ts +5 -0
  221. package/dist/runtime/server/api/observe/groups/[id].delete.js +11 -0
  222. package/dist/runtime/server/api/observe/groups/[id].get.d.ts +6 -0
  223. package/dist/runtime/server/api/observe/groups/[id].get.js +14 -0
  224. package/dist/runtime/server/api/observe/groups/[id].patch.d.ts +3 -0
  225. package/dist/runtime/server/api/observe/groups/[id].patch.js +12 -0
  226. package/dist/runtime/server/api/observe/groups/index.get.d.ts +3 -0
  227. package/dist/runtime/server/api/observe/groups/index.get.js +7 -0
  228. package/dist/runtime/server/api/observe/groups/index.post.d.ts +3 -0
  229. package/dist/runtime/server/api/observe/groups/index.post.js +11 -0
  230. package/dist/runtime/server/api/observe/health.get.d.ts +6 -0
  231. package/dist/runtime/server/api/observe/health.get.js +10 -0
  232. package/dist/runtime/server/api/observe/ingest/frogger.d.ts +5 -0
  233. package/dist/runtime/server/api/observe/ingest/frogger.js +42 -0
  234. package/dist/runtime/server/api/observe/ingest.d.ts +5 -0
  235. package/dist/runtime/server/api/observe/ingest.js +38 -0
  236. package/dist/runtime/server/api/observe/journey.get.d.ts +9 -0
  237. package/dist/runtime/server/api/observe/journey.get.js +31 -0
  238. package/dist/runtime/server/api/observe/logs/[id].get.d.ts +3 -0
  239. package/dist/runtime/server/api/observe/logs/[id].get.js +19 -0
  240. package/dist/runtime/server/api/observe/logs.get.d.ts +3 -0
  241. package/dist/runtime/server/api/observe/logs.get.js +54 -0
  242. package/dist/runtime/server/api/observe/migrations/index.get.d.ts +9 -0
  243. package/dist/runtime/server/api/observe/migrations/index.get.js +14 -0
  244. package/dist/runtime/server/api/observe/migrations/run.post.d.ts +13 -0
  245. package/dist/runtime/server/api/observe/migrations/run.post.js +35 -0
  246. package/dist/runtime/server/api/observe/overview.get.d.ts +3 -0
  247. package/dist/runtime/server/api/observe/overview.get.js +19 -0
  248. package/dist/runtime/server/api/observe/rollout/compare.get.d.ts +3 -0
  249. package/dist/runtime/server/api/observe/rollout/compare.get.js +24 -0
  250. package/dist/runtime/server/api/observe/rollout/regressions.get.d.ts +3 -0
  251. package/dist/runtime/server/api/observe/rollout/regressions.get.js +31 -0
  252. package/dist/runtime/server/api/observe/rollout/versions.get.d.ts +3 -0
  253. package/dist/runtime/server/api/observe/rollout/versions.get.js +20 -0
  254. package/dist/runtime/server/api/observe/services/[id]/assignments.put.d.ts +7 -0
  255. package/dist/runtime/server/api/observe/services/[id]/assignments.put.js +12 -0
  256. package/dist/runtime/server/api/observe/services/[id]/keys/[keyId]/rotate.post.d.ts +4 -0
  257. package/dist/runtime/server/api/observe/services/[id]/keys/[keyId]/rotate.post.js +14 -0
  258. package/dist/runtime/server/api/observe/services/[id]/keys/[keyId].delete.d.ts +4 -0
  259. package/dist/runtime/server/api/observe/services/[id]/keys/[keyId].delete.js +14 -0
  260. package/dist/runtime/server/api/observe/services/[id]/keys/index.get.d.ts +3 -0
  261. package/dist/runtime/server/api/observe/services/[id]/keys/index.get.js +10 -0
  262. package/dist/runtime/server/api/observe/services/[id]/keys/index.post.d.ts +3 -0
  263. package/dist/runtime/server/api/observe/services/[id]/keys/index.post.js +11 -0
  264. package/dist/runtime/server/api/observe/services/[id]/restore.post.d.ts +4 -0
  265. package/dist/runtime/server/api/observe/services/[id]/restore.post.js +11 -0
  266. package/dist/runtime/server/api/observe/services/[id].delete.d.ts +11 -0
  267. package/dist/runtime/server/api/observe/services/[id].delete.js +11 -0
  268. package/dist/runtime/server/api/observe/services/[id].get.d.ts +3 -0
  269. package/dist/runtime/server/api/observe/services/[id].get.js +12 -0
  270. package/dist/runtime/server/api/observe/services/[id].patch.d.ts +3 -0
  271. package/dist/runtime/server/api/observe/services/[id].patch.js +13 -0
  272. package/dist/runtime/server/api/observe/services/index.get.d.ts +3 -0
  273. package/dist/runtime/server/api/observe/services/index.get.js +7 -0
  274. package/dist/runtime/server/api/observe/services/index.post.d.ts +3 -0
  275. package/dist/runtime/server/api/observe/services/index.post.js +16 -0
  276. package/dist/runtime/server/api/observe/stats.get.d.ts +3 -0
  277. package/dist/runtime/server/api/observe/stats.get.js +28 -0
  278. package/dist/runtime/server/api/observe/users/[id]/assignments.put.d.ts +3 -0
  279. package/dist/runtime/server/api/observe/users/[id]/assignments.put.js +14 -0
  280. package/dist/runtime/server/api/observe/users/[id].delete.d.ts +4 -0
  281. package/dist/runtime/server/api/observe/users/[id].delete.js +15 -0
  282. package/dist/runtime/server/api/observe/users/[id].get.d.ts +3 -0
  283. package/dist/runtime/server/api/observe/users/[id].get.js +11 -0
  284. package/dist/runtime/server/api/observe/users/[id].patch.d.ts +3 -0
  285. package/dist/runtime/server/api/observe/users/[id].patch.js +25 -0
  286. package/dist/runtime/server/api/observe/users/index.get.d.ts +8 -0
  287. package/dist/runtime/server/api/observe/users/index.get.js +7 -0
  288. package/dist/runtime/server/api/observe/users/index.post.d.ts +3 -0
  289. package/dist/runtime/server/api/observe/users/index.post.js +29 -0
  290. package/dist/runtime/server/auth/authorization.d.ts +7 -0
  291. package/dist/runtime/server/auth/authorization.js +5 -0
  292. package/dist/runtime/server/auth/provider.d.ts +17 -0
  293. package/dist/runtime/server/auth/provider.js +44 -0
  294. package/dist/runtime/server/auth/providers/config-provider.d.ts +18 -0
  295. package/dist/runtime/server/auth/providers/config-provider.js +54 -0
  296. package/dist/runtime/server/auth/providers/db-provider.d.ts +16 -0
  297. package/dist/runtime/server/auth/providers/db-provider.js +42 -0
  298. package/dist/runtime/server/auth/providers/jwt-provider.d.ts +24 -0
  299. package/dist/runtime/server/auth/providers/jwt-provider.js +72 -0
  300. package/dist/runtime/server/migrations/0001-services-kind.d.ts +8 -0
  301. package/dist/runtime/server/migrations/0001-services-kind.js +14 -0
  302. package/dist/runtime/server/migrations/0002-services-type.d.ts +7 -0
  303. package/dist/runtime/server/migrations/0002-services-type.js +14 -0
  304. package/dist/runtime/server/migrations/0003-services-deleted-at.d.ts +6 -0
  305. package/dist/runtime/server/migrations/0003-services-deleted-at.js +14 -0
  306. package/dist/runtime/server/migrations/0004-logs-error-fingerprint.d.ts +11 -0
  307. package/dist/runtime/server/migrations/0004-logs-error-fingerprint.js +15 -0
  308. package/dist/runtime/server/migrations/0005-users-columns.d.ts +9 -0
  309. package/dist/runtime/server/migrations/0005-users-columns.js +25 -0
  310. package/dist/runtime/server/migrations/index.d.ts +13 -0
  311. package/dist/runtime/server/migrations/index.js +13 -0
  312. package/dist/runtime/server/migrations/types.d.ts +15 -0
  313. package/dist/runtime/server/migrations/types.js +0 -0
  314. package/dist/runtime/server/plugins/observe-migrate.server.d.ts +2 -0
  315. package/dist/runtime/server/plugins/observe-migrate.server.js +18 -0
  316. package/dist/runtime/server/tasks/backfill-fingerprints.d.ts +11 -0
  317. package/dist/runtime/server/tasks/backfill-fingerprints.js +41 -0
  318. package/dist/runtime/server/tasks/purge.d.ts +5 -0
  319. package/dist/runtime/server/tasks/purge.js +12 -0
  320. package/dist/runtime/server/tsconfig.json +3 -0
  321. package/dist/runtime/server/utils/activity-query.d.ts +28 -0
  322. package/dist/runtime/server/utils/activity-query.js +70 -0
  323. package/dist/runtime/server/utils/api-keys.d.ts +48 -0
  324. package/dist/runtime/server/utils/api-keys.js +67 -0
  325. package/dist/runtime/server/utils/authz.d.ts +50 -0
  326. package/dist/runtime/server/utils/authz.js +60 -0
  327. package/dist/runtime/server/utils/db/users.d.ts +91 -0
  328. package/dist/runtime/server/utils/db/users.js +128 -0
  329. package/dist/runtime/server/utils/db.d.ts +10 -0
  330. package/dist/runtime/server/utils/db.js +5 -0
  331. package/dist/runtime/server/utils/frogger-adapter.d.ts +40 -0
  332. package/dist/runtime/server/utils/frogger-adapter.js +97 -0
  333. package/dist/runtime/server/utils/groups.d.ts +35 -0
  334. package/dist/runtime/server/utils/groups.js +59 -0
  335. package/dist/runtime/server/utils/ingest-cors.d.ts +23 -0
  336. package/dist/runtime/server/utils/ingest-cors.js +27 -0
  337. package/dist/runtime/server/utils/journey.d.ts +20 -0
  338. package/dist/runtime/server/utils/journey.js +44 -0
  339. package/dist/runtime/server/utils/logs.d.ts +50 -0
  340. package/dist/runtime/server/utils/logs.js +154 -0
  341. package/dist/runtime/server/utils/loop-guard.d.ts +11 -0
  342. package/dist/runtime/server/utils/loop-guard.js +11 -0
  343. package/dist/runtime/server/utils/migrate.d.ts +21 -0
  344. package/dist/runtime/server/utils/migrate.js +144 -0
  345. package/dist/runtime/server/utils/migration-runner.d.ts +42 -0
  346. package/dist/runtime/server/utils/migration-runner.js +129 -0
  347. package/dist/runtime/server/utils/observe-errors.d.ts +58 -0
  348. package/dist/runtime/server/utils/observe-errors.js +206 -0
  349. package/dist/runtime/server/utils/overview.d.ts +20 -0
  350. package/dist/runtime/server/utils/overview.js +119 -0
  351. package/dist/runtime/server/utils/provisioning.d.ts +62 -0
  352. package/dist/runtime/server/utils/provisioning.js +299 -0
  353. package/dist/runtime/server/utils/rate-limit.d.ts +11 -0
  354. package/dist/runtime/server/utils/rate-limit.js +22 -0
  355. package/dist/runtime/server/utils/require-observe-session.d.ts +15 -0
  356. package/dist/runtime/server/utils/require-observe-session.js +25 -0
  357. package/dist/runtime/server/utils/rollout.d.ts +19 -0
  358. package/dist/runtime/server/utils/rollout.js +56 -0
  359. package/dist/runtime/server/utils/scope.d.ts +14 -0
  360. package/dist/runtime/server/utils/scope.js +28 -0
  361. package/dist/runtime/server/utils/seed.d.ts +18 -0
  362. package/dist/runtime/server/utils/seed.js +70 -0
  363. package/dist/runtime/server/utils/services.d.ts +91 -0
  364. package/dist/runtime/server/utils/services.js +142 -0
  365. package/dist/runtime/server/utils/stats-query.d.ts +40 -0
  366. package/dist/runtime/server/utils/stats-query.js +104 -0
  367. package/dist/runtime/shared/auth/roles.d.ts +34 -0
  368. package/dist/runtime/shared/auth/roles.js +6 -0
  369. package/dist/runtime/shared/auth/schema.d.ts +85 -0
  370. package/dist/runtime/shared/auth/schema.js +41 -0
  371. package/dist/runtime/shared/auth/types.d.ts +68 -0
  372. package/dist/runtime/shared/auth/types.js +0 -0
  373. package/dist/runtime/shared/rbac/capabilities.d.ts +46 -0
  374. package/dist/runtime/shared/rbac/capabilities.js +48 -0
  375. package/dist/runtime/shared/schema/activity.d.ts +77 -0
  376. package/dist/runtime/shared/schema/activity.js +22 -0
  377. package/dist/runtime/shared/schema/adapters/frogger.d.ts +52 -0
  378. package/dist/runtime/shared/schema/adapters/frogger.js +17 -0
  379. package/dist/runtime/shared/schema/batch.d.ts +33 -0
  380. package/dist/runtime/shared/schema/batch.js +9 -0
  381. package/dist/runtime/shared/schema/error-fingerprint.d.ts +53 -0
  382. package/dist/runtime/shared/schema/error-fingerprint.js +47 -0
  383. package/dist/runtime/shared/schema/errors-query.d.ts +136 -0
  384. package/dist/runtime/shared/schema/errors-query.js +47 -0
  385. package/dist/runtime/shared/schema/event.d.ts +48 -0
  386. package/dist/runtime/shared/schema/event.js +41 -0
  387. package/dist/runtime/shared/schema/frogger-map.d.ts +62 -0
  388. package/dist/runtime/shared/schema/frogger-map.js +30 -0
  389. package/dist/runtime/shared/schema/index.d.ts +17 -0
  390. package/dist/runtime/shared/schema/index.js +17 -0
  391. package/dist/runtime/shared/schema/journey.d.ts +99 -0
  392. package/dist/runtime/shared/schema/journey.js +96 -0
  393. package/dist/runtime/shared/schema/levels.d.ts +37 -0
  394. package/dist/runtime/shared/schema/levels.js +72 -0
  395. package/dist/runtime/shared/schema/log-row.d.ts +31 -0
  396. package/dist/runtime/shared/schema/log-row.js +0 -0
  397. package/dist/runtime/shared/schema/logs-query.d.ts +91 -0
  398. package/dist/runtime/shared/schema/logs-query.js +72 -0
  399. package/dist/runtime/shared/schema/migrations.d.ts +34 -0
  400. package/dist/runtime/shared/schema/migrations.js +0 -0
  401. package/dist/runtime/shared/schema/overview.d.ts +78 -0
  402. package/dist/runtime/shared/schema/overview.js +9 -0
  403. package/dist/runtime/shared/schema/provisioning.d.ts +230 -0
  404. package/dist/runtime/shared/schema/provisioning.js +52 -0
  405. package/dist/runtime/shared/schema/registry.d.ts +115 -0
  406. package/dist/runtime/shared/schema/registry.js +27 -0
  407. package/dist/runtime/shared/schema/rollout.d.ts +103 -0
  408. package/dist/runtime/shared/schema/rollout.js +66 -0
  409. package/dist/runtime/shared/schema/stats.d.ts +64 -0
  410. package/dist/runtime/shared/schema/stats.js +15 -0
  411. package/dist/runtime/shared/schema/tiers.d.ts +5 -0
  412. package/dist/runtime/shared/schema/tiers.js +9 -0
  413. package/dist/runtime/shared/types/module-options.d.ts +119 -0
  414. package/dist/runtime/shared/types/module-options.js +13 -0
  415. package/dist/runtime/shared/types/storage.d.ts +31 -0
  416. package/dist/runtime/shared/types/storage.js +0 -0
  417. package/dist/runtime/shared/utils/format-relative.d.ts +7 -0
  418. package/dist/runtime/shared/utils/format-relative.js +11 -0
  419. package/dist/runtime/shared/utils/frogger-snippet.d.ts +19 -0
  420. package/dist/runtime/shared/utils/frogger-snippet.js +33 -0
  421. package/dist/runtime/shared/utils/observe-config.d.ts +9 -0
  422. package/dist/runtime/shared/utils/observe-config.js +17 -0
  423. package/dist/runtime/shared/utils/period.d.ts +13 -0
  424. package/dist/runtime/shared/utils/period.js +15 -0
  425. package/dist/runtime/shared/utils/slug.d.ts +1 -0
  426. package/dist/runtime/shared/utils/slug.js +5 -0
  427. package/dist/runtime/shared/utils/uuid.d.ts +187 -0
  428. package/dist/runtime/shared/utils/uuid.js +345 -0
  429. package/dist/runtime/types/nuxt-auth-utils-imports.d.ts +25 -0
  430. package/dist/runtime/types/observe-app-imports.d.ts +20 -0
  431. package/dist/runtime/types/session.d.ts +17 -0
  432. package/dist/schema.d.mts +1318 -0
  433. package/dist/schema.mjs +629 -0
  434. package/dist/types.d.mts +3 -0
  435. package/package.json +93 -0
@@ -0,0 +1,142 @@
1
+ import { uuidv7 } from "../../shared/utils/uuid.js";
2
+ import { hashApiKey } from "./api-keys.js";
3
+ import { useObserveDb } from "./db.js";
4
+ export const SERVICE_DELETE_RETENTION_MS = 60 * 60 * 1e3;
5
+ export async function createService(input, opts = {}) {
6
+ const db = opts.db ?? useObserveDb();
7
+ const id = uuidv7();
8
+ const now = Date.now();
9
+ await db.sql`
10
+ INSERT INTO services (id, slug, name, group_id, env, version_tracking, current_version, kind, type, created_by, created_at, updated_at)
11
+ VALUES (
12
+ ${id}, ${input.slug}, ${input.name}, ${input.groupId ?? null}, ${input.env ?? null},
13
+ ${input.versionTracking ? 1 : 0}, ${input.currentVersion ?? null}, ${input.kind ?? "server"}, ${input.type ?? "service"}, ${input.createdBy ?? null}, ${now}, ${now}
14
+ )
15
+ `;
16
+ return await getServiceById(id, opts);
17
+ }
18
+ export async function getServiceById(id, opts = {}) {
19
+ const db = opts.db ?? useObserveDb();
20
+ const row = await db.prepare("SELECT * FROM services WHERE id = ?").get(id);
21
+ return row ?? null;
22
+ }
23
+ export async function getServiceBySlug(slug, opts = {}) {
24
+ const db = opts.db ?? useObserveDb();
25
+ const row = await db.prepare("SELECT * FROM services WHERE slug = ?").get(slug);
26
+ return row ?? null;
27
+ }
28
+ export async function listServices(opts = {}) {
29
+ const db = opts.db ?? useObserveDb();
30
+ const where = opts.includeDeleted ? "" : "WHERE deleted_at IS NULL";
31
+ return await db.prepare(`SELECT * FROM services ${where} ORDER BY created_at`).all();
32
+ }
33
+ export async function updateService(id, patch, opts = {}) {
34
+ const db = opts.db ?? useObserveDb();
35
+ const existing = await getServiceById(id, opts);
36
+ if (!existing) return null;
37
+ const name = patch.name ?? existing.name;
38
+ const groupId = "groupId" in patch ? patch.groupId ?? null : existing.group_id;
39
+ const env = "env" in patch ? patch.env ?? null : existing.env;
40
+ const versionTracking = patch.versionTracking === void 0 ? existing.version_tracking : patch.versionTracking ? 1 : 0;
41
+ const currentVersion = "currentVersion" in patch ? patch.currentVersion ?? null : existing.current_version;
42
+ const kind = patch.kind ?? existing.kind;
43
+ const type = patch.type ?? existing.type;
44
+ await db.sql`
45
+ UPDATE services
46
+ SET name = ${name}, group_id = ${groupId}, env = ${env},
47
+ version_tracking = ${versionTracking}, current_version = ${currentVersion}, kind = ${kind}, type = ${type}, updated_at = ${Date.now()}
48
+ WHERE id = ${id}
49
+ `;
50
+ return await getServiceById(id, opts);
51
+ }
52
+ export async function softDeleteService(id, opts = {}) {
53
+ const db = opts.db ?? useObserveDb();
54
+ const existing = await getServiceById(id, opts);
55
+ if (!existing || existing.deleted_at !== null) return existing?.deleted_at ?? null;
56
+ const now = Date.now();
57
+ await db.sql`UPDATE services SET deleted_at = ${now}, updated_at = ${now} WHERE id = ${id}`;
58
+ return now;
59
+ }
60
+ export async function restoreService(id, opts = {}) {
61
+ const db = opts.db ?? useObserveDb();
62
+ const existing = await getServiceById(id, opts);
63
+ if (!existing) return null;
64
+ await db.sql`UPDATE services SET deleted_at = NULL, updated_at = ${Date.now()} WHERE id = ${id}`;
65
+ return await getServiceById(id, opts);
66
+ }
67
+ export async function deleteService(id, opts = {}) {
68
+ const db = opts.db ?? useObserveDb();
69
+ await db.sql`DELETE FROM service_app_names WHERE service_id = ${id}`;
70
+ await db.sql`DELETE FROM service_allowed_origins WHERE service_id = ${id}`;
71
+ await db.sql`DELETE FROM api_keys WHERE service_id = ${id}`;
72
+ await db.sql`DELETE FROM services WHERE id = ${id}`;
73
+ }
74
+ export async function purgeExpiredServices(retentionMs, opts = {}) {
75
+ const db = opts.db ?? useObserveDb();
76
+ const cutoff = Date.now() - retentionMs;
77
+ const rows = await db.prepare(
78
+ "SELECT id FROM services WHERE deleted_at IS NOT NULL AND deleted_at < ?"
79
+ ).all(cutoff);
80
+ for (const { id } of rows) {
81
+ await deleteService(id, opts);
82
+ }
83
+ return { purged: rows.length };
84
+ }
85
+ export async function setServiceAppNames(serviceId, appNames, opts = {}) {
86
+ const db = opts.db ?? useObserveDb();
87
+ await db.sql`BEGIN`;
88
+ try {
89
+ await db.sql`DELETE FROM service_app_names WHERE service_id = ${serviceId}`;
90
+ for (const appName of appNames) {
91
+ await db.sql`INSERT INTO service_app_names (service_id, app_name) VALUES (${serviceId}, ${appName})`;
92
+ }
93
+ await db.sql`COMMIT`;
94
+ } catch (e) {
95
+ await db.sql`ROLLBACK`;
96
+ throw e;
97
+ }
98
+ }
99
+ export async function getServiceAppNames(serviceId, opts = {}) {
100
+ const db = opts.db ?? useObserveDb();
101
+ const rows = await db.prepare("SELECT app_name FROM service_app_names WHERE service_id = ? ORDER BY app_name").all(serviceId);
102
+ return rows.map((r) => r.app_name);
103
+ }
104
+ export async function resolveServiceByAppName(appName, opts = {}) {
105
+ const db = opts.db ?? useObserveDb();
106
+ const row = await db.prepare(
107
+ "SELECT s.* FROM services s JOIN service_app_names a ON a.service_id = s.id WHERE a.app_name = ?"
108
+ ).get(appName);
109
+ return row ?? null;
110
+ }
111
+ export async function setServiceAllowedOrigins(serviceId, origins, opts = {}) {
112
+ const db = opts.db ?? useObserveDb();
113
+ const unique = [...new Set(origins)];
114
+ await db.sql`BEGIN`;
115
+ try {
116
+ await db.sql`DELETE FROM service_allowed_origins WHERE service_id = ${serviceId}`;
117
+ for (const origin of unique) {
118
+ await db.sql`INSERT INTO service_allowed_origins (service_id, origin) VALUES (${serviceId}, ${origin})`;
119
+ }
120
+ await db.sql`COMMIT`;
121
+ } catch (e) {
122
+ await db.sql`ROLLBACK`;
123
+ throw e;
124
+ }
125
+ }
126
+ export async function getServiceAllowedOrigins(serviceId, opts = {}) {
127
+ const db = opts.db ?? useObserveDb();
128
+ const rows = await db.prepare("SELECT origin FROM service_allowed_origins WHERE service_id = ?").all(serviceId);
129
+ return rows.map((r) => r.origin);
130
+ }
131
+ export async function resolveServiceCorsMeta(rawKey, opts = {}) {
132
+ if (!rawKey) return null;
133
+ const db = opts.db ?? useObserveDb();
134
+ const svc = await db.prepare(
135
+ `SELECT s.id AS service_id, s.kind AS kind
136
+ FROM api_keys k JOIN services s ON s.id = k.service_id
137
+ WHERE k.key_hash = ? AND k.revoked_at IS NULL`
138
+ ).get(hashApiKey(rawKey));
139
+ if (!svc) return null;
140
+ const origins = await getServiceAllowedOrigins(svc.service_id, { db });
141
+ return { serviceId: svc.service_id, kind: svc.kind === "browser" ? "browser" : "server", allowedOrigins: origins };
142
+ }
@@ -0,0 +1,40 @@
1
+ import type { StatsBucket, StatsData, StatsSeriesMeta } from '../../shared/schema/stats.js';
2
+ import type { Period } from '../../shared/utils/period.js';
3
+ import { type Database } from './db.js';
4
+ /**
5
+ * CP8 bucketed aggregates behind GET /api/observe/stats. Same contract as the CP7
6
+ * getOverview helper: takes a RESOLVED scope (string[] | '*'), not an event — the
7
+ * handler runs requireCapability/getAllowedServiceIds/resolveEffectiveScope first —
8
+ * so this stays pure and node-testable via `opts.db`.
9
+ *
10
+ * Bucketing is `CAST(time / ?bucketMs AS INTEGER)`: better-sqlite3 binds JS numbers
11
+ * as REAL, so a bound divisor does float division (a literal would int-divide); the
12
+ * CAST truncates toward zero, which equals floor for positive ms epochs, and keeps
13
+ * every value a bound parameter. GROUP BY on that index aggregates per window slice
14
+ * in SQL. The window is always time-bounded, riding idx_logs_service_time when
15
+ * scoped and idx_logs_time for admin. CP13 (rollout charts) reuses zeroFilledBuckets
16
+ * + the same GROUP BY shape with `version` as a second dimension.
17
+ */
18
+ interface DbOpts {
19
+ db?: Database;
20
+ }
21
+ export interface StatsFilters {
22
+ version?: string;
23
+ level?: number;
24
+ }
25
+ /** Per-period default bucket size, targeting <= ~200 points per window. */
26
+ export declare const DEFAULT_BUCKET_MS: Record<Period, number>;
27
+ /** Hard ceiling on buckets per response; an explicit ?bucketMs below it is a 400. */
28
+ export declare const MAX_BUCKETS = 500;
29
+ /** Top-N services kept as distinct breakdown series; the tail folds into 'other'. */
30
+ export declare const TOP_SERVICES = 8;
31
+ export declare const OTHER_SERIES: StatsSeriesMeta;
32
+ /**
33
+ * Contiguous zero-filled skeleton covering [from, to]: one bucket per integer index
34
+ * floor(time / bucketMs), ascending. Exported for CP13's rollout bucketing.
35
+ */
36
+ export declare function zeroFilledBuckets(from: number, to: number, bucketMs: number): StatsBucket[];
37
+ /** Zeroed response slice for an empty scope; never touches the db. */
38
+ export declare function emptyStats(from: number, to: number, bucketMs: number): StatsData;
39
+ export declare function getStats(scope: string[] | '*', from: number, to: number, bucketMs: number, filters?: StatsFilters, opts?: DbOpts): Promise<StatsData>;
40
+ export {};
@@ -0,0 +1,104 @@
1
+ import { useObserveDb } from "./db.js";
2
+ export const DEFAULT_BUCKET_MS = {
3
+ "15m": 15e3,
4
+ // 60 buckets
5
+ "1h": 6e4,
6
+ // 60 buckets
7
+ "24h": 9e5,
8
+ // 96 buckets
9
+ "7d": 36e5,
10
+ // 168 buckets
11
+ "30d": 216e5
12
+ // 120 buckets
13
+ };
14
+ export const MAX_BUCKETS = 500;
15
+ export const TOP_SERVICES = 8;
16
+ export const OTHER_SERIES = { id: "other", slug: "other", name: "Other" };
17
+ export function zeroFilledBuckets(from, to, bucketMs) {
18
+ const bFrom = Math.floor(from / bucketMs);
19
+ const bTo = Math.floor(to / bucketMs);
20
+ const buckets = [];
21
+ for (let idx = bFrom; idx <= bTo; idx++) {
22
+ buckets.push({ t: idx * bucketMs, count: 0, errorCount: 0, warnCount: 0, byService: {} });
23
+ }
24
+ return buckets;
25
+ }
26
+ export function emptyStats(from, to, bucketMs) {
27
+ return {
28
+ buckets: zeroFilledBuckets(from, to, bucketMs),
29
+ services: [],
30
+ totals: { count: 0, errorCount: 0, warnCount: 0, errorRatePct: 0 }
31
+ };
32
+ }
33
+ export async function getStats(scope, from, to, bucketMs, filters = {}, opts = {}) {
34
+ if (scope !== "*" && scope.length === 0) return emptyStats(from, to, bucketMs);
35
+ const db = opts.db ?? useObserveDb();
36
+ const scoped = scope === "*" ? { clause: "", params: [] } : { clause: `AND service_id IN (${scope.map(() => "?").join(",")})`, params: [...scope] };
37
+ const filt = [];
38
+ const filtParams = [];
39
+ if (filters.version != null) {
40
+ filt.push("AND version = ?");
41
+ filtParams.push(filters.version);
42
+ }
43
+ if (filters.level != null) {
44
+ filt.push("AND level = ?");
45
+ filtParams.push(filters.level);
46
+ }
47
+ const where = `WHERE time >= ? AND time <= ? ${scoped.clause} ${filt.join(" ")}`;
48
+ const params = [bucketMs, from, to, ...scoped.params, ...filtParams];
49
+ const totalsRows = await db.prepare(
50
+ `SELECT CAST(time / ? AS INTEGER) AS b,
51
+ COUNT(*) AS count,
52
+ SUM(level = 0) AS errorCount,
53
+ SUM(level = 1) AS warnCount
54
+ FROM logs ${where}
55
+ GROUP BY b
56
+ ORDER BY b`
57
+ ).all(...params);
58
+ const breakdownRows = await db.prepare(
59
+ `SELECT CAST(time / ? AS INTEGER) AS b, service_id AS sid, COUNT(*) AS count
60
+ FROM logs ${where}
61
+ GROUP BY b, sid
62
+ ORDER BY b`
63
+ ).all(...params);
64
+ const buckets = zeroFilledBuckets(from, to, bucketMs);
65
+ const bFrom = Math.floor(from / bucketMs);
66
+ const bucketAt = (b) => buckets[b - bFrom];
67
+ for (const row of totalsRows) {
68
+ const bucket = bucketAt(row.b);
69
+ if (!bucket) continue;
70
+ bucket.count += row.count;
71
+ bucket.errorCount += row.errorCount ?? 0;
72
+ bucket.warnCount += row.warnCount ?? 0;
73
+ }
74
+ const totalBySid = /* @__PURE__ */ new Map();
75
+ for (const row of breakdownRows) {
76
+ if (!row.sid) continue;
77
+ totalBySid.set(row.sid, (totalBySid.get(row.sid) ?? 0) + row.count);
78
+ }
79
+ const byVolume = [...totalBySid.entries()].sort((a, b) => b[1] - a[1]);
80
+ const topIds = new Set(byVolume.slice(0, TOP_SERVICES).map(([id]) => id));
81
+ const folded = byVolume.length > TOP_SERVICES;
82
+ for (const row of breakdownRows) {
83
+ if (!row.sid) continue;
84
+ const bucket = bucketAt(row.b);
85
+ if (!bucket) continue;
86
+ const key = topIds.has(row.sid) ? row.sid : OTHER_SERIES.id;
87
+ bucket.byService[key] = (bucket.byService[key] ?? 0) + row.count;
88
+ }
89
+ const ids = [...topIds];
90
+ const metaRows = ids.length ? await db.prepare(
91
+ `SELECT id, slug, name FROM services WHERE id IN (${ids.map(() => "?").join(",")})`
92
+ ).all(...ids) : [];
93
+ const meta = new Map(metaRows.map((r) => [r.id, r]));
94
+ const services = byVolume.slice(0, TOP_SERVICES).map(([id]) => meta.get(id) ?? { id, slug: id, name: id });
95
+ if (folded) services.push({ ...OTHER_SERIES });
96
+ const totals = { count: 0, errorCount: 0, warnCount: 0, errorRatePct: 0 };
97
+ for (const bucket of buckets) {
98
+ totals.count += bucket.count;
99
+ totals.errorCount += bucket.errorCount;
100
+ totals.warnCount += bucket.warnCount;
101
+ }
102
+ totals.errorRatePct = totals.count ? totals.errorCount / totals.count * 100 : 0;
103
+ return { buckets, services, totals };
104
+ }
@@ -0,0 +1,34 @@
1
+ import type { Role } from './types.js';
2
+ export declare const ROLES: readonly ["admin", "manager", "viewer"];
3
+ /** Assignment sentinel: every service / every group. Admins carry this. */
4
+ export declare const ALL: "*";
5
+ /** Higher = more privilege. CP6 compares ranks for role-gated capabilities. */
6
+ export declare const ROLE_RANK: Record<Role, number>;
7
+ export declare function isRole(x: unknown): x is Role;
8
+ /**
9
+ * CAPABILITY MATRIX — DOCUMENTED FOR CP6, NOT ENFORCED IN CP5.
10
+ * CP5 gates routes only with requireUserSession (logged-in vs not). CP6 implements
11
+ * these checks in the AuthorizationStore / route guards, scoped by Assignment.
12
+ *
13
+ * capability | admin | manager | viewer
14
+ * -------------------------------|-------|----------------|----------------
15
+ * view logs / dashboards | all | assigned only | assigned only
16
+ * manage services (create/edit) | yes | assigned only | no
17
+ * manage groups | yes | no | no
18
+ * mint / revoke api keys | yes | assigned only | no
19
+ * manage users + assignments | yes | no | no (CP16 UI)
20
+ * change retention / settings | yes | no | no
21
+ *
22
+ * Scoping rule CP6 consumes: a principal may act on service slug S iff
23
+ * assignment.services includes '*' OR S, OR S belongs to a group in assignment.groups.
24
+ * Admin's assignment is { services:['*'], groups:['*'] }, so every check short-circuits true.
25
+ *
26
+ * BOOTSTRAP-ADMIN LIFECYCLE (unified across phases — see CP5-HANDOFF §2 / PLAN CP16):
27
+ * Phase 1 (CP5, config provider): observe.auth.users is the whole user set. At least
28
+ * one admin is the bootstrap admin; you deploy with it and log in.
29
+ * Phase 2 (CP16, db provider): the `users` table is authoritative. The config bootstrap
30
+ * admin is honoured ONLY as a fallback while the DB has zero admin users. Creating a
31
+ * real DB admin closes the window automatically ("admin admin no longer needed"); the
32
+ * config admin is never written to the DB. Deleting every DB admin reopens it (recovery
33
+ * hatch). CP16 reuses this file's config-provider logic for that gated fallback.
34
+ */
@@ -0,0 +1,6 @@
1
+ export const ROLES = ["admin", "manager", "viewer"];
2
+ export const ALL = "*";
3
+ export const ROLE_RANK = { admin: 3, manager: 2, viewer: 1 };
4
+ export function isRole(x) {
5
+ return typeof x === "string" && ROLES.includes(x);
6
+ }
@@ -0,0 +1,85 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Pure zod + local only, mirroring the registry schema rule: this file must never
4
+ * import #imports, node:crypto, or any server util so it stays node-unit-testable
5
+ * and app-importable.
6
+ */
7
+ export declare const roleSchema: z.ZodEnum<{
8
+ admin: "admin";
9
+ manager: "manager";
10
+ viewer: "viewer";
11
+ }>;
12
+ export declare const assignmentSchema: z.ZodObject<{
13
+ services: z.ZodArray<z.ZodString>;
14
+ groups: z.ZodArray<z.ZodString>;
15
+ }, z.core.$strip>;
16
+ /**
17
+ * Build-time validation of a seeded user (observe.auth.users). At least one of
18
+ * passwordHash / passwordEnv is required — a user with neither can never authenticate.
19
+ * Plaintext passwords are NOT accepted in config: only a pre-computed scrypt hash, or
20
+ * the NAME of an env var holding the plaintext/hash, resolved at authenticate time.
21
+ */
22
+ export declare const observeUserSchema: z.ZodObject<{
23
+ name: z.ZodString;
24
+ role: z.ZodEnum<{
25
+ admin: "admin";
26
+ manager: "manager";
27
+ viewer: "viewer";
28
+ }>;
29
+ assignedServices: z.ZodOptional<z.ZodArray<z.ZodString>>;
30
+ assignedGroups: z.ZodOptional<z.ZodArray<z.ZodString>>;
31
+ passwordHash: z.ZodOptional<z.ZodString>;
32
+ passwordEnv: z.ZodOptional<z.ZodString>;
33
+ }, z.core.$strip>;
34
+ export declare const loginBodySchema: z.ZodObject<{
35
+ name: z.ZodString;
36
+ password: z.ZodString;
37
+ }, z.core.$strip>;
38
+ export declare const createUserSchema: z.ZodObject<{
39
+ username: z.ZodString;
40
+ displayName: z.ZodOptional<z.ZodString>;
41
+ role: z.ZodEnum<{
42
+ admin: "admin";
43
+ manager: "manager";
44
+ viewer: "viewer";
45
+ }>;
46
+ password: z.ZodOptional<z.ZodString>;
47
+ }, z.core.$strip>;
48
+ export declare const patchUserSchema: z.ZodObject<{
49
+ displayName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
50
+ role: z.ZodOptional<z.ZodEnum<{
51
+ admin: "admin";
52
+ manager: "manager";
53
+ viewer: "viewer";
54
+ }>>;
55
+ disabled: z.ZodOptional<z.ZodBoolean>;
56
+ password: z.ZodOptional<z.ZodString>;
57
+ }, z.core.$strip>;
58
+ /** Per-assignment role is stored now for a future per-scope-role feature (CP16 §2.2). */
59
+ export declare const userAssignmentsSchema: z.ZodObject<{
60
+ services: z.ZodDefault<z.ZodArray<z.ZodObject<{
61
+ serviceId: z.ZodString;
62
+ role: z.ZodEnum<{
63
+ admin: "admin";
64
+ manager: "manager";
65
+ viewer: "viewer";
66
+ }>;
67
+ }, z.core.$strip>>>;
68
+ groups: z.ZodDefault<z.ZodArray<z.ZodObject<{
69
+ groupId: z.ZodString;
70
+ role: z.ZodEnum<{
71
+ admin: "admin";
72
+ manager: "manager";
73
+ viewer: "viewer";
74
+ }>;
75
+ }, z.core.$strip>>>;
76
+ }, z.core.$strip>;
77
+ /** Router param: validate BEFORE any scope/DB call => 400 on a malformed id. */
78
+ export declare const userIdParams: z.ZodObject<{
79
+ id: z.ZodString;
80
+ }, z.core.$strip>;
81
+ export type ObserveUser = z.infer<typeof observeUserSchema>;
82
+ export type LoginBody = z.infer<typeof loginBodySchema>;
83
+ export type CreateUserInput = z.infer<typeof createUserSchema>;
84
+ export type PatchUserInput = z.infer<typeof patchUserSchema>;
85
+ export type UserAssignmentsInput = z.infer<typeof userAssignmentsSchema>;
@@ -0,0 +1,41 @@
1
+ import { z } from "zod";
2
+ import { ROLES } from "./roles.js";
3
+ export const roleSchema = z.enum(ROLES);
4
+ export const assignmentSchema = z.object({
5
+ services: z.array(z.string().min(1)),
6
+ // slugs or ['*']
7
+ groups: z.array(z.string().min(1))
8
+ });
9
+ export const observeUserSchema = z.object({
10
+ name: z.string().min(1),
11
+ role: roleSchema,
12
+ assignedServices: z.array(z.string().min(1)).optional(),
13
+ assignedGroups: z.array(z.string().min(1)).optional(),
14
+ passwordHash: z.string().min(1).optional(),
15
+ passwordEnv: z.string().min(1).optional()
16
+ }).refine((u) => !!(u.passwordHash || u.passwordEnv), {
17
+ message: "each observe.auth user needs passwordHash or passwordEnv"
18
+ });
19
+ export const loginBodySchema = z.object({
20
+ name: z.string().min(1),
21
+ password: z.string().min(1)
22
+ });
23
+ const passwordSchema = z.string().min(8).max(200);
24
+ export const createUserSchema = z.object({
25
+ username: z.string().min(1).max(80),
26
+ displayName: z.string().min(1).max(120).optional(),
27
+ role: roleSchema,
28
+ password: passwordSchema.optional()
29
+ // absent => JWT-only / no local login
30
+ });
31
+ export const patchUserSchema = z.object({
32
+ displayName: z.string().min(1).max(120).nullable().optional(),
33
+ role: roleSchema.optional(),
34
+ disabled: z.boolean().optional(),
35
+ password: passwordSchema.optional()
36
+ });
37
+ export const userAssignmentsSchema = z.object({
38
+ services: z.array(z.object({ serviceId: z.string().min(1), role: roleSchema })).default([]),
39
+ groups: z.array(z.object({ groupId: z.string().min(1), role: roleSchema })).default([])
40
+ });
41
+ export const userIdParams = z.object({ id: z.string().min(1) });
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Auth contract shared by app + server. Pure TS, no runtime imports beyond the
3
+ * inline h3 type — this file is pulled into both the Nitro server and the Nuxt
4
+ * app, and must stay dependency-free so neither side drags the other's runtime.
5
+ *
6
+ * This contract is FINAL for CP6 (RBAC enforcement + scoping) and CP16 (DB + JWT
7
+ * providers). Those checkpoints fill in behaviour behind these interfaces without
8
+ * changing a single field here or any call site. See CP5-HANDOFF §8.
9
+ */
10
+ /** Access tiers. Ordered by privilege in ROLE_RANK (roles.ts). */
11
+ export type Role = 'admin' | 'manager' | 'viewer';
12
+ /**
13
+ * What a principal may see/act on. Slug arrays reference services.slug / groups.slug
14
+ * (CP2). The '*' sentinel (ALL, roles.ts) means "every service" / "every group" and
15
+ * is what an admin carries. CP6 reads this to scope every query; it never re-derives
16
+ * scope from the role alone.
17
+ */
18
+ export interface Assignment {
19
+ /** service slugs, or ['*'] for all */
20
+ services: string[];
21
+ /** group slugs, or ['*'] for all */
22
+ groups: string[];
23
+ }
24
+ /**
25
+ * Provider-agnostic, session-shaped identity. This exact object is what
26
+ * setUserSession(event, { user: principal }) stores and requireObserveSession returns.
27
+ * sub stable identity: config -> user name; db -> row id; jwt -> `sub` claim
28
+ * provider which AuthProvider minted it (audit + re-hydration routing for CP16).
29
+ * 'config' also tags the bootstrap-admin path (see roles.ts / CP16 notes).
30
+ */
31
+ export interface Principal {
32
+ sub: string;
33
+ name: string;
34
+ role: Role;
35
+ assignment: Assignment;
36
+ provider: 'config' | 'db' | 'jwt';
37
+ }
38
+ /** Password login now; token login is the CP16 JWT path. Union so routes/providers stay forward-compatible. */
39
+ export type Credentials = {
40
+ name: string;
41
+ password: string;
42
+ } | {
43
+ token: string;
44
+ };
45
+ /** Uniform authenticate() outcome. `reason` is diagnostic only; never leak it to a 401 body. */
46
+ export interface AuthenticateResult {
47
+ ok: boolean;
48
+ principal?: Principal;
49
+ reason?: string;
50
+ }
51
+ /**
52
+ * The extension point CP5 exists to establish. Every route authenticates through
53
+ * getAuthProvider().authenticate(). resolvePrincipal is optional session re-hydration
54
+ * (CP16 db/jwt use it to refresh role/assignment from the source of truth per request).
55
+ */
56
+ export interface AuthProvider {
57
+ id: 'config' | 'db' | 'jwt';
58
+ authenticate(credentials: Credentials, event: import('h3').H3Event): Promise<AuthenticateResult>;
59
+ resolvePrincipal?(sub: string, event: import('h3').H3Event): Promise<Principal | null>;
60
+ }
61
+ /**
62
+ * Where a principal's Assignment comes from. CP5's ConfigAuthorizationStore returns
63
+ * principal.assignment verbatim (identity). CP16's db store looks assignments up by
64
+ * sub. CP6 adds capability checks HERE (documented in roles.ts, not implemented in CP5).
65
+ */
66
+ export interface AuthorizationStore {
67
+ getAssignment(principal: Principal, event: import('h3').H3Event): Promise<Assignment>;
68
+ }
File without changes
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Capability x scope authorization model, shared VERBATIM by server enforcement
3
+ * (server/utils/authz.ts) and client gating (app/composables/useObserveAbility.ts)
4
+ * so a gated control in the UI can never drift from what a route actually enforces.
5
+ *
6
+ * Framework-free: zod + the local auth contract only, no #imports / @nuxt/kit, so it
7
+ * loads identically in a node-env unit test, the Nitro server, and the browser.
8
+ *
9
+ * This implements the capability matrix DOCUMENTED (not enforced) in shared/auth/roles.ts.
10
+ * Two cells where that comment and the PLAN's CP6 table disagreed were resolved with the
11
+ * developer on 2026-07-06: `groups.manage` is admin-only, and `services.create` is split
12
+ * out of `services.manage` and is admin-only. See CP6-HANDOFF §9.2/§9.3.
13
+ */
14
+ import { z } from 'zod';
15
+ import type { Role } from '../auth/types.js';
16
+ import { roleSchema } from '../auth/schema.js';
17
+ /** What a held capability applies to. Absence from the matrix === 'none' (denied). */
18
+ export type Scope = 'all' | 'assigned' | 'none';
19
+ export type Capability = 'users.manage' | 'services.create' | 'services.manage' | 'groups.manage' | 'migrations.manage' | 'services.read' | 'logs.read' | 'stats.read';
20
+ export declare const CAPABILITIES: readonly ["users.manage", "services.create", "services.manage", "groups.manage", "migrations.manage", "services.read", "logs.read", "stats.read"];
21
+ export declare const scopeSchema: z.ZodEnum<{
22
+ none: "none";
23
+ all: "all";
24
+ assigned: "assigned";
25
+ }>;
26
+ export declare const capabilitySchema: z.ZodEnum<{
27
+ "users.manage": "users.manage";
28
+ "services.create": "services.create";
29
+ "services.manage": "services.manage";
30
+ "groups.manage": "groups.manage";
31
+ "migrations.manage": "migrations.manage";
32
+ "services.read": "services.read";
33
+ "logs.read": "logs.read";
34
+ "stats.read": "stats.read";
35
+ }>;
36
+ export { roleSchema };
37
+ /**
38
+ * (role, capability) -> scope. A capability ABSENT from a role's map is scope 'none':
39
+ * that role is denied it entirely (=> 403 at the choke point). The 'assigned' scope is
40
+ * short-circuited to unrestricted at resolution time when the principal carries a '*'
41
+ * assignment (getAllowedServiceIds); admin holds every capability at 'all'.
42
+ */
43
+ export declare const ROLE_CAPABILITIES: Record<Role, Partial<Record<Capability, Scope>>>;
44
+ /** The one resolver both server and client call. Returns the scope, or undefined when denied. */
45
+ export declare function roleCan(role: Role, capability: Capability): Scope | undefined;
46
+ export declare function hasCapability(role: Role, capability: Capability): boolean;
@@ -0,0 +1,48 @@
1
+ import { z } from "zod";
2
+ import { roleSchema } from "../auth/schema.js";
3
+ export const CAPABILITIES = [
4
+ "users.manage",
5
+ "services.create",
6
+ "services.manage",
7
+ "groups.manage",
8
+ "migrations.manage",
9
+ "services.read",
10
+ "logs.read",
11
+ "stats.read"
12
+ ];
13
+ export const scopeSchema = z.enum(["all", "assigned", "none"]);
14
+ export const capabilitySchema = z.enum(CAPABILITIES);
15
+ export { roleSchema };
16
+ export const ROLE_CAPABILITIES = {
17
+ admin: {
18
+ "users.manage": "all",
19
+ "services.create": "all",
20
+ "services.manage": "all",
21
+ "groups.manage": "all",
22
+ "migrations.manage": "all",
23
+ "services.read": "all",
24
+ "logs.read": "all",
25
+ "stats.read": "all"
26
+ },
27
+ manager: {
28
+ "services.manage": "assigned",
29
+ "services.read": "assigned",
30
+ "logs.read": "assigned",
31
+ "stats.read": "assigned"
32
+ // groups.manage absent => 'none': group management is admin-only (§9.2).
33
+ // services.create absent => 'none': a brand-new service has no assignment to scope
34
+ // a manager against, so creating one is admin-only (§9.3); a manager still edits
35
+ // (services.manage) the services already assigned to it.
36
+ },
37
+ viewer: {
38
+ "services.read": "assigned",
39
+ "logs.read": "assigned",
40
+ "stats.read": "assigned"
41
+ }
42
+ };
43
+ export function roleCan(role, capability) {
44
+ return ROLE_CAPABILITIES[role]?.[capability];
45
+ }
46
+ export function hasCapability(role, capability) {
47
+ return roleCan(role, capability) !== void 0;
48
+ }