@terreno/mcp 57.3.0 → 57.4.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 (250) hide show
  1. package/README.md +7 -1
  2. package/dist/bootstrap.d.ts +0 -18
  3. package/dist/bootstrap.d.ts.map +1 -1
  4. package/dist/bootstrap.js +10 -2428
  5. package/dist/bootstrap.js.map +1 -1
  6. package/dist/docs/guidelines/admin-frontend/guidelines/core.md +5 -1
  7. package/dist/docs/guidelines/api/skills/mongoose-schema-safety/SKILL.md +23 -10
  8. package/dist/docs/resources/syncdb.md +4 -1
  9. package/dist/docs/upgrades/57.4.0.md +140 -0
  10. package/dist/docs/versioned/next/README.md +3 -0
  11. package/dist/docs/versioned/next/explanation/README.md +4 -1
  12. package/dist/docs/versioned/next/explanation/admin-interface.md +20 -13
  13. package/dist/docs/versioned/next/explanation/charts.md +29 -0
  14. package/dist/docs/versioned/next/explanation/deployment-architecture-gcp.md +32 -0
  15. package/dist/docs/versioned/next/explanation/deployment-baseline.md +1 -1
  16. package/dist/docs/versioned/next/explanation/example-coverage.md +43 -0
  17. package/dist/docs/versioned/next/explanation/local-first-data.md +5 -2
  18. package/dist/docs/versioned/next/explanation/loop-engineering.md +9 -6
  19. package/dist/docs/versioned/next/explanation/model-router-actions.md +19 -2
  20. package/dist/docs/versioned/next/explanation/organizations.md +88 -0
  21. package/dist/docs/versioned/next/explanation/planning-plugins.md +114 -0
  22. package/dist/docs/versioned/next/explanation/positioning.md +3 -3
  23. package/dist/docs/versioned/next/explanation/repository-settings.md +6 -5
  24. package/dist/docs/versioned/next/explanation/roadmap-seed-issues.md +44 -34
  25. package/dist/docs/versioned/next/explanation/source-rules.md +1 -1
  26. package/dist/docs/versioned/next/explanation/static-analysis.md +76 -16
  27. package/dist/docs/versioned/next/how-to/README.md +10 -0
  28. package/dist/docs/versioned/next/how-to/add-gpt-chat-mascot.md +92 -0
  29. package/dist/docs/versioned/next/how-to/add-organizations.md +204 -0
  30. package/dist/docs/versioned/next/how-to/admin-add-model.md +9 -1
  31. package/dist/docs/versioned/next/how-to/admin-import-prebuilt.md +7 -1
  32. package/dist/docs/versioned/next/how-to/audit-log.md +85 -0
  33. package/dist/docs/versioned/next/how-to/background-jobs.md +296 -0
  34. package/dist/docs/versioned/next/how-to/build-admin-screens.md +42 -13
  35. package/dist/docs/versioned/next/how-to/charts-and-dashboards.md +37 -0
  36. package/dist/docs/versioned/next/how-to/circleci.md +136 -27
  37. package/dist/docs/versioned/next/how-to/compare-chart-rendered-snapshots.md +36 -0
  38. package/dist/docs/versioned/next/how-to/configure-better-auth.md +4 -0
  39. package/dist/docs/versioned/next/how-to/create-a-terreno-app.md +154 -0
  40. package/dist/docs/versioned/next/how-to/deploy-backend-to-cloud-run.md +2 -0
  41. package/dist/docs/versioned/next/how-to/github-actions-ci.md +4 -3
  42. package/dist/docs/versioned/next/how-to/github-issue-lifecycle.md +12 -8
  43. package/dist/docs/versioned/next/how-to/in-app-notifications.md +147 -0
  44. package/dist/docs/versioned/next/how-to/install-agent-skills.md +24 -12
  45. package/dist/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +19 -3
  46. package/dist/docs/versioned/next/how-to/product-announcements.md +155 -0
  47. package/dist/docs/versioned/next/how-to/run-mongodb-migrations.md +127 -0
  48. package/dist/docs/versioned/next/how-to/run-tests-locally.md +102 -0
  49. package/dist/docs/versioned/next/how-to/seed-a-database.md +7 -2
  50. package/dist/docs/versioned/next/implementationPlans/README.md +8 -5
  51. package/dist/docs/versioned/next/implementationPlans/admin-scripts-durable-jobs.md +44 -0
  52. package/dist/docs/versioned/next/implementationPlans/agent-ui-blocks.md +386 -0
  53. package/dist/docs/versioned/next/implementationPlans/agentic-sdlc-plugin.md +11 -8
  54. package/dist/docs/versioned/next/implementationPlans/announcements-surfaces.md +231 -0
  55. package/dist/docs/versioned/next/implementationPlans/announcements.md +289 -0
  56. package/dist/docs/versioned/next/implementationPlans/b2b-platform-program.md +3 -1
  57. package/dist/docs/versioned/next/implementationPlans/charts-and-dashboards.md +246 -0
  58. package/dist/docs/versioned/next/implementationPlans/comms-admin-dashboard.md +4 -3
  59. package/dist/docs/versioned/next/implementationPlans/create-terreno-app.md +177 -0
  60. package/dist/docs/versioned/next/implementationPlans/datatable-server-side-filtering.md +219 -0
  61. package/dist/docs/versioned/next/implementationPlans/examples-demo-coverage.md +17 -17
  62. package/dist/docs/versioned/next/implementationPlans/framework-audit-log.md +247 -0
  63. package/dist/docs/versioned/next/implementationPlans/gpt-chat-mascot.md +40 -0
  64. package/dist/docs/versioned/next/implementationPlans/job-queues.md +330 -0
  65. package/dist/docs/versioned/next/implementationPlans/knip-cleanup.md +136 -0
  66. package/dist/docs/versioned/next/implementationPlans/migrate-admin-to-syncdb.md +210 -0
  67. package/dist/docs/versioned/next/implementationPlans/mongodb-migrations-tooling.md +254 -0
  68. package/dist/docs/versioned/next/implementationPlans/notification-center.md +185 -0
  69. package/dist/docs/versioned/next/implementationPlans/org-management-ui.md +8 -3
  70. package/dist/docs/versioned/next/implementationPlans/positioning-django-rails-universal.md +1 -1
  71. package/dist/docs/versioned/next/reference/README.md +4 -0
  72. package/dist/docs/versioned/next/reference/admin-backend.md +83 -5
  73. package/dist/docs/versioned/next/reference/admin-config.md +7 -0
  74. package/dist/docs/versioned/next/reference/admin-frontend.md +178 -5
  75. package/dist/docs/versioned/next/reference/admin-spa.md +18 -1
  76. package/dist/docs/versioned/next/reference/ai.md +2 -0
  77. package/dist/docs/versioned/next/reference/announcements.md +179 -0
  78. package/dist/docs/versioned/next/reference/api.md +343 -4
  79. package/dist/docs/versioned/next/reference/comms.md +33 -0
  80. package/dist/docs/versioned/next/reference/create-terreno-app.md +44 -0
  81. package/dist/docs/versioned/next/reference/environment-variables.md +29 -0
  82. package/dist/docs/versioned/next/reference/jobs.md +319 -0
  83. package/dist/docs/versioned/next/reference/legacy/rtk.md +5 -1
  84. package/dist/docs/versioned/next/reference/lifecycle-plugin.md +29 -11
  85. package/dist/docs/versioned/next/reference/mcp-server.md +2 -43
  86. package/dist/docs/versioned/next/reference/scan-plugin.md +169 -0
  87. package/dist/docs/versioned/next/reference/syncdb.md +38 -12
  88. package/dist/docs/versioned/next/reference/test.md +57 -6
  89. package/dist/docs/versioned/next/reference/ui-performance.md +2 -1
  90. package/dist/docs/versioned/next/reference/ui.md +257 -3
  91. package/dist/docs/versioned/next/tasks/admin-scripts-durable-jobs.md +10 -0
  92. package/dist/docs/versioned/next/tasks/agent-ui-blocks.md +114 -0
  93. package/dist/docs/versioned/next/tasks/announcements-surfaces.md +101 -0
  94. package/dist/docs/versioned/next/tasks/announcements.md +173 -0
  95. package/dist/docs/versioned/next/tasks/charts-and-dashboards.md +120 -0
  96. package/dist/docs/versioned/next/tasks/create-terreno-app.md +82 -0
  97. package/dist/docs/versioned/next/tasks/datatable-server-side-filtering.md +87 -0
  98. package/dist/docs/versioned/next/tasks/examples-demo-coverage.md +123 -17
  99. package/dist/docs/versioned/next/tasks/framework-audit-log.md +86 -0
  100. package/dist/docs/versioned/next/tasks/gpt-chat-mascot.md +13 -0
  101. package/dist/docs/versioned/next/tasks/job-queues.md +144 -0
  102. package/dist/docs/versioned/next/tasks/knip-cleanup.md +146 -0
  103. package/dist/docs/versioned/next/tasks/migrate-admin-to-syncdb.md +209 -0
  104. package/dist/docs/versioned/next/tasks/mongodb-migrations-tooling.md +107 -0
  105. package/dist/docs/versioned/next/tasks/notification-center.md +102 -0
  106. package/dist/docs/versioned/next/tasks/org-management-ui.md +14 -14
  107. package/dist/docs/versioned/next/tutorials/README.md +1 -1
  108. package/dist/docs/versioned/next/tutorials/getting-started.md +62 -22
  109. package/dist/help/excerpt.d.ts +2 -0
  110. package/dist/help/excerpt.d.ts.map +1 -0
  111. package/dist/help/excerpt.js +8 -0
  112. package/dist/help/excerpt.js.map +1 -0
  113. package/dist/help/updateNotes.d.ts +42 -0
  114. package/dist/help/updateNotes.d.ts.map +1 -0
  115. package/dist/help/updateNotes.js +235 -0
  116. package/dist/help/updateNotes.js.map +1 -0
  117. package/dist/index.js +1 -1
  118. package/dist/index.js.map +1 -1
  119. package/dist/local/tools/databaseQuery.d.ts +1 -0
  120. package/dist/local/tools/databaseQuery.d.ts.map +1 -1
  121. package/dist/local/tools/databaseQuery.js +1 -0
  122. package/dist/local/tools/databaseQuery.js.map +1 -1
  123. package/dist/packageGuidelines.d.ts +2 -2
  124. package/dist/packageGuidelines.d.ts.map +1 -1
  125. package/dist/packageGuidelines.js +2 -8
  126. package/dist/packageGuidelines.js.map +1 -1
  127. package/dist/resources.d.ts +3 -0
  128. package/dist/resources.d.ts.map +1 -1
  129. package/dist/resources.js +3 -0
  130. package/dist/resources.js.map +1 -1
  131. package/dist/search/chunker.d.ts +1 -0
  132. package/dist/search/chunker.d.ts.map +1 -1
  133. package/dist/search/chunker.js +1 -0
  134. package/dist/search/chunker.js.map +1 -1
  135. package/dist/search/docIndex.d.ts +1 -5
  136. package/dist/search/docIndex.d.ts.map +1 -1
  137. package/dist/search/docIndex.js +1 -0
  138. package/dist/search/docIndex.js.map +1 -1
  139. package/dist/search/docVersion.d.ts +2 -1
  140. package/dist/search/docVersion.d.ts.map +1 -1
  141. package/dist/search/docVersion.js +3 -1
  142. package/dist/search/docVersion.js.map +1 -1
  143. package/dist/tools.d.ts +2 -2
  144. package/dist/tools.d.ts.map +1 -1
  145. package/dist/tools.js +113 -2
  146. package/dist/tools.js.map +1 -1
  147. package/package.json +28 -27
  148. package/src/docs/guidelines/admin-frontend/guidelines/core.md +5 -1
  149. package/src/docs/guidelines/api/skills/mongoose-schema-safety/SKILL.md +23 -10
  150. package/src/docs/resources/syncdb.md +4 -1
  151. package/src/docs/upgrades/57.4.0.md +140 -0
  152. package/src/docs/versioned/next/README.md +3 -0
  153. package/src/docs/versioned/next/explanation/README.md +4 -1
  154. package/src/docs/versioned/next/explanation/admin-interface.md +20 -13
  155. package/src/docs/versioned/next/explanation/charts.md +29 -0
  156. package/src/docs/versioned/next/explanation/deployment-architecture-gcp.md +32 -0
  157. package/src/docs/versioned/next/explanation/deployment-baseline.md +1 -1
  158. package/src/docs/versioned/next/explanation/example-coverage.md +43 -0
  159. package/src/docs/versioned/next/explanation/local-first-data.md +5 -2
  160. package/src/docs/versioned/next/explanation/loop-engineering.md +9 -6
  161. package/src/docs/versioned/next/explanation/model-router-actions.md +19 -2
  162. package/src/docs/versioned/next/explanation/organizations.md +88 -0
  163. package/src/docs/versioned/next/explanation/planning-plugins.md +114 -0
  164. package/src/docs/versioned/next/explanation/positioning.md +3 -3
  165. package/src/docs/versioned/next/explanation/repository-settings.md +6 -5
  166. package/src/docs/versioned/next/explanation/roadmap-seed-issues.md +44 -34
  167. package/src/docs/versioned/next/explanation/source-rules.md +1 -1
  168. package/src/docs/versioned/next/explanation/static-analysis.md +76 -16
  169. package/src/docs/versioned/next/how-to/README.md +10 -0
  170. package/src/docs/versioned/next/how-to/add-gpt-chat-mascot.md +92 -0
  171. package/src/docs/versioned/next/how-to/add-organizations.md +204 -0
  172. package/src/docs/versioned/next/how-to/admin-add-model.md +9 -1
  173. package/src/docs/versioned/next/how-to/admin-import-prebuilt.md +7 -1
  174. package/src/docs/versioned/next/how-to/audit-log.md +85 -0
  175. package/src/docs/versioned/next/how-to/background-jobs.md +296 -0
  176. package/src/docs/versioned/next/how-to/build-admin-screens.md +42 -13
  177. package/src/docs/versioned/next/how-to/charts-and-dashboards.md +37 -0
  178. package/src/docs/versioned/next/how-to/circleci.md +136 -27
  179. package/src/docs/versioned/next/how-to/compare-chart-rendered-snapshots.md +36 -0
  180. package/src/docs/versioned/next/how-to/configure-better-auth.md +4 -0
  181. package/src/docs/versioned/next/how-to/create-a-terreno-app.md +154 -0
  182. package/src/docs/versioned/next/how-to/deploy-backend-to-cloud-run.md +2 -0
  183. package/src/docs/versioned/next/how-to/github-actions-ci.md +4 -3
  184. package/src/docs/versioned/next/how-to/github-issue-lifecycle.md +12 -8
  185. package/src/docs/versioned/next/how-to/in-app-notifications.md +147 -0
  186. package/src/docs/versioned/next/how-to/install-agent-skills.md +24 -12
  187. package/src/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +19 -3
  188. package/src/docs/versioned/next/how-to/product-announcements.md +155 -0
  189. package/src/docs/versioned/next/how-to/run-mongodb-migrations.md +127 -0
  190. package/src/docs/versioned/next/how-to/run-tests-locally.md +102 -0
  191. package/src/docs/versioned/next/how-to/seed-a-database.md +7 -2
  192. package/src/docs/versioned/next/implementationPlans/README.md +8 -5
  193. package/src/docs/versioned/next/implementationPlans/admin-scripts-durable-jobs.md +44 -0
  194. package/src/docs/versioned/next/implementationPlans/agent-ui-blocks.md +386 -0
  195. package/src/docs/versioned/next/implementationPlans/agentic-sdlc-plugin.md +11 -8
  196. package/src/docs/versioned/next/implementationPlans/announcements-surfaces.md +231 -0
  197. package/src/docs/versioned/next/implementationPlans/announcements.md +289 -0
  198. package/src/docs/versioned/next/implementationPlans/b2b-platform-program.md +3 -1
  199. package/src/docs/versioned/next/implementationPlans/charts-and-dashboards.md +246 -0
  200. package/src/docs/versioned/next/implementationPlans/comms-admin-dashboard.md +4 -3
  201. package/src/docs/versioned/next/implementationPlans/create-terreno-app.md +177 -0
  202. package/src/docs/versioned/next/implementationPlans/datatable-server-side-filtering.md +219 -0
  203. package/src/docs/versioned/next/implementationPlans/examples-demo-coverage.md +17 -17
  204. package/src/docs/versioned/next/implementationPlans/framework-audit-log.md +247 -0
  205. package/src/docs/versioned/next/implementationPlans/gpt-chat-mascot.md +40 -0
  206. package/src/docs/versioned/next/implementationPlans/job-queues.md +330 -0
  207. package/src/docs/versioned/next/implementationPlans/knip-cleanup.md +136 -0
  208. package/src/docs/versioned/next/implementationPlans/migrate-admin-to-syncdb.md +210 -0
  209. package/src/docs/versioned/next/implementationPlans/mongodb-migrations-tooling.md +254 -0
  210. package/src/docs/versioned/next/implementationPlans/notification-center.md +185 -0
  211. package/src/docs/versioned/next/implementationPlans/org-management-ui.md +8 -3
  212. package/src/docs/versioned/next/implementationPlans/positioning-django-rails-universal.md +1 -1
  213. package/src/docs/versioned/next/reference/README.md +4 -0
  214. package/src/docs/versioned/next/reference/admin-backend.md +83 -5
  215. package/src/docs/versioned/next/reference/admin-config.md +7 -0
  216. package/src/docs/versioned/next/reference/admin-frontend.md +178 -5
  217. package/src/docs/versioned/next/reference/admin-spa.md +18 -1
  218. package/src/docs/versioned/next/reference/ai.md +2 -0
  219. package/src/docs/versioned/next/reference/announcements.md +179 -0
  220. package/src/docs/versioned/next/reference/api.md +343 -4
  221. package/src/docs/versioned/next/reference/comms.md +33 -0
  222. package/src/docs/versioned/next/reference/create-terreno-app.md +44 -0
  223. package/src/docs/versioned/next/reference/environment-variables.md +29 -0
  224. package/src/docs/versioned/next/reference/jobs.md +319 -0
  225. package/src/docs/versioned/next/reference/legacy/rtk.md +5 -1
  226. package/src/docs/versioned/next/reference/lifecycle-plugin.md +29 -11
  227. package/src/docs/versioned/next/reference/mcp-server.md +2 -43
  228. package/src/docs/versioned/next/reference/scan-plugin.md +169 -0
  229. package/src/docs/versioned/next/reference/syncdb.md +38 -12
  230. package/src/docs/versioned/next/reference/test.md +57 -6
  231. package/src/docs/versioned/next/reference/ui-performance.md +2 -1
  232. package/src/docs/versioned/next/reference/ui.md +257 -3
  233. package/src/docs/versioned/next/tasks/admin-scripts-durable-jobs.md +10 -0
  234. package/src/docs/versioned/next/tasks/agent-ui-blocks.md +114 -0
  235. package/src/docs/versioned/next/tasks/announcements-surfaces.md +101 -0
  236. package/src/docs/versioned/next/tasks/announcements.md +173 -0
  237. package/src/docs/versioned/next/tasks/charts-and-dashboards.md +120 -0
  238. package/src/docs/versioned/next/tasks/create-terreno-app.md +82 -0
  239. package/src/docs/versioned/next/tasks/datatable-server-side-filtering.md +87 -0
  240. package/src/docs/versioned/next/tasks/examples-demo-coverage.md +123 -17
  241. package/src/docs/versioned/next/tasks/framework-audit-log.md +86 -0
  242. package/src/docs/versioned/next/tasks/gpt-chat-mascot.md +13 -0
  243. package/src/docs/versioned/next/tasks/job-queues.md +144 -0
  244. package/src/docs/versioned/next/tasks/knip-cleanup.md +146 -0
  245. package/src/docs/versioned/next/tasks/migrate-admin-to-syncdb.md +209 -0
  246. package/src/docs/versioned/next/tasks/mongodb-migrations-tooling.md +107 -0
  247. package/src/docs/versioned/next/tasks/notification-center.md +102 -0
  248. package/src/docs/versioned/next/tasks/org-management-ui.md +14 -14
  249. package/src/docs/versioned/next/tutorials/README.md +1 -1
  250. package/src/docs/versioned/next/tutorials/getting-started.md +62 -22
@@ -50,7 +50,24 @@ admin-spa/
50
50
  dist/ # Pre-built static export (produced by build:web)
51
51
  ```
52
52
 
53
- Boot flow in the SPA: `AppConfigGate` fetches `${basePath}/app-config.json` → `StoreProvider` builds Better Auth + Redux → `AdminGate` redirects anonymous users to `/login` and non-admins to `/forbidden`.
53
+ Boot flow in the SPA: `AppConfigGate` fetches `${basePath}/app-config.json` →
54
+ `StoreProvider` builds Better Auth + Redux → `AdminGate` redirects anonymous
55
+ users to `/login` and non-admins to `/forbidden` → the authorized provider reads
56
+ `/admin/config`. When config contains String-`_id` models with `adminBroadcast`
57
+ and `syncCollection`, it starts a same-origin cookie-authenticated syncdb client
58
+ with those collections in window mode and forwards `useConflicts()` to the admin.
59
+ ObjectId and non-broadcast models remain on RTK.
60
+
61
+ When the backend enables organizations, the bundled SPA exposes:
62
+
63
+ - `/orgs` — operator-only organization directory;
64
+ - `/orgs/:orgId` — organization settings;
65
+ - `/orgs/:orgId/members` — organization memberships.
66
+
67
+ `AdminSpaShell` renders `OrgSwitcher` on every admin route. The switcher and
68
+ directory use `/orgs` API routes while generic model CRUD continues under the
69
+ configured `adminApiBasePath`. Org-admins do not receive the directory link.
70
+ The default `/console` mount therefore serves these as `/console/orgs/...`.
54
71
 
55
72
  ## AdminSpaServeApp
56
73
 
@@ -367,6 +367,8 @@ new LangfuseApp({
367
367
  | `evaluation.enabled` | — | Register evaluation scoring routes |
368
368
  | `cache` | — | Prompt/trace TTL overrides |
369
369
 
370
+ Client construction failures log a warning and skip the plugin so the API process still listens. Tracing init failures log and leave admin routes mounted. example-backend does not register `LangfuseApp` when `MONGO_DB_NAME` is a PR preview database (`terreno-example-pr-*`). GitHub Actions preview deploys omit Langfuse secrets and use `secrets_update_strategy: overwrite` so a previous revision cannot merge those keys into the preview.
371
+
370
372
  Calls `shutdownLangfuseClient()` and `shutdownTracing()` on `SIGTERM`.
371
373
 
372
374
  ## Langfuse integration
@@ -0,0 +1,179 @@
1
+ # Announcements reference
2
+
3
+ `@terreno/announcements` provides admin-managed in-app product update announcements.
4
+
5
+ ## Plugin
6
+
7
+ ```typescript
8
+ import {AnnouncementsApp} from "@terreno/announcements";
9
+
10
+ new TerrenoApp({ userModel: User })
11
+ .register(new AnnouncementsApp({
12
+ defaultAcknowledgementPolicy: "dismiss-only",
13
+ help: {enabled: true},
14
+ isStaff: (user) => user.admin === true,
15
+ matchAudience: (user, announcement) => true,
16
+ }))
17
+ .start();
18
+ ```
19
+
20
+ ### Plugin options
21
+
22
+ | Option | Type | Default | Description |
23
+ |--------|------|---------|-------------|
24
+ | `adminOverviewPermissions` | `PermissionMethod[]` | `IsAdmin` | Access methods for `GET /announcements/overview`; pass the consumer RBAC `adminAnnouncement:read` permission when the admin shell uses RBAC-only users |
25
+ | `basePath` | `string` | `"/announcements"` | Mount path for user and admin routes |
26
+ | `defaultAcknowledgementPolicy` | `"required" \| "dismiss-only"` | `"dismiss-only"` | Fills omitted per-announcement `acknowledgementPolicy` at read time and pre-fills the admin editor |
27
+ | `help.enabled` | `boolean` | `false` | Registers help search/detail routes for MCP and in-app help |
28
+ | `matchAudience` | `(user, announcement) => boolean` | always `true` | Opaque audience JSON filter composed with `audienceType` via `matchAudienceByType` |
29
+ | `isStaff` | `(user) => boolean` | `user.admin === true` | Staff check used by `matchAudienceByType` for `audienceType` |
30
+ | `permissions` | partial CRUD overrides | admin-only | Overrides default `IsAdmin` permissions on announcement CRUD |
31
+
32
+ ## Acknowledgement policy
33
+
34
+ Per-announcement `acknowledgementPolicy` controls whether users must acknowledge or may dismiss with an impression only.
35
+
36
+ | Policy | Pending queue advancement | Public DTO `requiresAcknowledgement` |
37
+ |--------|---------------------------|--------------------------------------|
38
+ | `required` | User must POST `/acknowledge` for the current `version` | `true` |
39
+ | `dismiss-only` | User may dismiss; POST `/impression` clears the item | `false` |
40
+
41
+ **Resolution order** (pending, feed, help, public DTO):
42
+
43
+ ```
44
+ policy = announcement.acknowledgementPolicy
45
+ ?? (legacy requiresAcknowledgement === true ? "required" : undefined)
46
+ ?? defaultAcknowledgementPolicy
47
+ ?? "dismiss-only"
48
+ requiresAcknowledgement = policy === "required"
49
+ ```
50
+
51
+ Legacy MongoDB documents that still store `requiresAcknowledgement: true` map to `"required"` on read. The boolean field is not part of the schema or admin create/update payloads.
52
+
53
+ ## Models
54
+
55
+ - **Announcement** — `title`, `body` (markdown), `status` (`draft` | `published` | `archived`), `version`, `priority`, `displayMode` (`modal` | `banner` | `feed`, default `modal`), `audienceType` (`staff` | `patient` | `all`, default `all`), `acknowledgementPolicy`, optional `minBuildNumber`, `audience` (Mixed), `publishAt`, `expiresAt`, `platforms`, `primaryAction`
56
+ - **AnnouncementAcknowledgement** — per-user acknowledgement at a specific `version`
57
+ - **AnnouncementImpression** — per-view analytics row
58
+ - **AnnouncementClickEvent** — per-click analytics row (`action: "primaryAction"`, `version` at click time, optional `platform`)
59
+
60
+ Legacy MongoDB documents without `displayMode` or `audienceType` behave as `modal` and `all` at read time.
61
+
62
+ ### `matchAudienceByType`
63
+
64
+ Exported helper composed with the plugin `matchAudience` callback (both must pass):
65
+
66
+ ```typescript
67
+ import {matchAudienceByType} from "@terreno/announcements";
68
+
69
+ matchAudienceByType({
70
+ user,
71
+ announcement,
72
+ isStaff: (candidate) => candidate.admin === true,
73
+ });
74
+ // all → true; staff → isStaff(user); patient → !isStaff(user)
75
+ ```
76
+
77
+ The plugin applies `matchAudienceByType` before `matchAudience`. When `isStaff` is omitted on `AnnouncementsApp`, it defaults to `user.admin === true`.
78
+
79
+ ## User routes
80
+
81
+ | Method | Path | Description |
82
+ |--------|------|-------------|
83
+ | GET | `/announcements/pending` | Current interrupt (`modal` or `banner` only) + `remainingCount` (`platform` query: `ios` \| `android` \| `web`; optional `version` build number) |
84
+ | GET | `/announcements/feed` | Paginated published changelog — all display modes (`platform` and optional `version` as above) |
85
+ | POST | `/announcements/:id/acknowledge` | Record acknowledgement (idempotent per version). Same visibility as pending/feed; **404** when not visible. |
86
+ | POST | `/announcements/:id/impression` | Record a view. Same visibility as pending/feed; **404** when not visible. |
87
+ | POST | `/announcements/:id/click` | Record a primary-action click (`{ action: "primaryAction", platform? }`; optional `?version=` for min-build visibility). Returns **404** when not visible (checked before action/CTA validation). **400** when `action` is invalid, `primaryAction` is absent, or an explicit `platform` value is invalid. |
88
+
89
+ `current` and feed items include resolved `requiresAcknowledgement` (boolean) and `displayMode` derived from policy resolution and stored fields above.
90
+
91
+ ### Query `version`
92
+
93
+ Optional integer build number on `GET /pending`, `GET /feed`, and help routes. When an announcement has `minBuildNumber` set:
94
+
95
+ - `?version=9` hides the item when `minBuildNumber` is `10`
96
+ - `?version=10` (or higher) shows it
97
+ - omitting `version` does **not** hide gated items
98
+
99
+ `POST /announcements/:id/acknowledge`, `POST /announcements/:id/impression`, and `POST /announcements/:id/click` use the same visibility rules as pending/feed (schedule, expiry, platform, min build, `audienceType`, and `matchAudience`). All three return **404** when the announcement is not visible to the caller, so targeted IDs cannot be confirmed by writing event rows. Click checks visibility before action/CTA validation. Returns **400** when `action` is not `"primaryAction"`, the announcement has no `primaryAction`, or an explicit body `platform` is not `ios` / `android` / `web` (omit `platform` to use query/user-agent resolution). Each click inserts a new row (not idempotent). Acknowledge is idempotent per `(userId, announcementId, version)`.
100
+
101
+ ## Admin routes
102
+
103
+ Admin CRUD is on `/announcements` via `modelRouter`. Custom actions:
104
+
105
+ - `GET /announcements/config` — returns `{ data: { defaultAcknowledgementPolicy } }` from the plugin constructor (admin only; defaults to `"dismiss-only"` when omitted). Used to pre-fill the admin editor acknowledgement policy field.
106
+ - `GET /announcements/overview` — paginated admin dashboard with per-announcement metrics and aggregate totals. Access uses `adminOverviewPermissions` (defaults to `IsAdmin`). Query: `page` (default `1`), `limit` (default `20`, max `100`).
107
+ - `POST /announcements/:id/publish` — draft → published
108
+ - `POST /announcements/:id/archive` — published → archived
109
+
110
+ ### `GET /announcements/overview`
111
+
112
+ Admin-only list for launch dashboards. Includes **all** lifecycle statuses (`draft`, `published`, `archived`). Soft-deleted announcements and event rows are excluded.
113
+
114
+ **Query**
115
+
116
+ | Param | Default | Max | Description |
117
+ |-------|---------|-----|-------------|
118
+ | `page` | `1` | — | 1-based page index |
119
+ | `limit` | `20` | `100` | Rows per page |
120
+
121
+ **Response** `{ data, totals, page, limit, total, more }`
122
+
123
+ - `data[]` — announcement rows sorted by `priority` desc, then `publishedAt` desc, then `_id` desc (deterministic pagination).
124
+ - Each row: `_id`, `title`, `status`, resolved `displayMode`, resolved `audienceType`, resolved `acknowledgementPolicy`, `priority`, `version`, `publishedAt`, `expiresAt` (ISO strings when set), and `metrics: { impressions, acknowledgements, clicks }`.
125
+ - Per-row metrics count **all event versions** for that announcement (aggregation grouped by `announcementId`, not N+1 queries).
126
+ - `totals` — `announcements`, `published`, `draft`, `archived`, plus global `impressions`, `acknowledgements`, and `clicks` across non-deleted event rows.
127
+
128
+ **Auth:** `401` unauthenticated; `403` when `adminOverviewPermissions` denies access.
129
+
130
+ Read-only admin lists: `/announcement-acknowledgements`, `/announcement-impressions`, `/announcement-click-events`.
131
+
132
+ Terreno RBAC includes `adminAnnouncementAcknowledgement`, `adminAnnouncementImpression`, and `adminAnnouncementClickEvent`. The built-in `admin` role receives read access to these audit models; `superadmin` receives all declared actions.
133
+
134
+ ## Help API (optional)
135
+
136
+ When `help.enabled` is true, authenticated users can search product update notes for MCP and in-app help. Draft announcements are never exposed. Results respect `matchAudienceByType`, `matchAudience`, `publishAt` / `expiresAt`, optional `?version=` min-build gating, and the same visibility rules as `/pending`.
137
+
138
+ | Method | Path | Description |
139
+ |--------|------|-------------|
140
+ | GET | `/announcements/help/search` | Search published notes (`q`, `limit`, `includeArchived`) |
141
+ | GET | `/announcements/help/:id` | Full update note by Mongo id (`includeArchived`) |
142
+
143
+ `includeArchived=true` includes `archived` announcements alongside `published`. Omit it (default) to search only published notes.
144
+
145
+ ## MCP integration
146
+
147
+ `@terreno/mcp` exposes three optional tools that search bundled `@terreno/*` upgrade markdown and, when configured, announcement help routes on your backend:
148
+
149
+ - `terreno_search_update_notes` — keyword search; returns summaries with ids
150
+ - `terreno_get_update_note` — full note by id (`upgrade:<semver>` or `announcement:<mongoId>`)
151
+ - `terreno_ask_update_help` — natural-language question with ranked matches and full bodies
152
+
153
+ Set these environment variables on the MCP server to include live announcements:
154
+
155
+ | Variable | Description |
156
+ |----------|-------------|
157
+ | `TERRENO_HELP_API_URL` | Backend base URL (e.g. `http://localhost:4000`) |
158
+ | `TERRENO_HELP_API_TOKEN` | Optional Bearer token for authenticated help routes |
159
+
160
+ ## Consumer UI
161
+
162
+ `@terreno/ui` exports `AnnouncementNavigator`, `AnnouncementScreen`, `AnnouncementBanner`, `useAnnouncements`, and `useAcknowledgeAnnouncement`. These are app-level product surfaces — they are not registered in the isolated UI component demo. Wire them in a consumer app (`example-frontend`) with a real API.
163
+
164
+ - Pending and feed requests send the current client platform (`ios`, `android`, or `web`) and, when available, the app build number from `Constants.expoConfig.extra.buildNumber` (same source as `useUpgradeCheck`).
165
+ - `requiresAcknowledgement` on pending/feed items is resolved server-side from `acknowledgementPolicy` and `defaultAcknowledgementPolicy`; the navigator trusts that flag.
166
+ - Feed failures do not block the modal queue — only pending errors surface in `AnnouncementNavigator`.
167
+ - Markdown bodies support YouTube and Loom embeds via `MarkdownView`; ordinary links open with `Linking.openURL`.
168
+
169
+ ### `useAcknowledgeAnnouncement`
170
+
171
+ Injects RTK Query mutations for acknowledgement, impression, and primary-action click tracking:
172
+
173
+ | Method | Route | Notes |
174
+ |--------|-------|-------|
175
+ | `acknowledge(id)` | `POST /announcements/:id/acknowledge` | Invalidates pending queue. Query includes `platform` and, when available, `version` (same visibility gate as pending/feed). |
176
+ | `recordImpression(id)` | `POST /announcements/:id/impression` | Sends current `platform` in body |
177
+ | `recordClick(id)` | `POST /announcements/:id/click` | Body `{ action: "primaryAction", platform }`; query includes `platform` and, when available, `version` (same visibility gate as pending/feed) |
178
+
179
+ `AnnouncementNavigator` wires `onPrimaryAction` for modal and banner surfaces: it calls `recordClick` once per primary CTA press (only when `primaryAction` is present), then opens the URL with `Linking`. Click POST failures log `console.warn` and do not block navigation. Standalone `AnnouncementScreen` / `AnnouncementBanner` usage without `onPrimaryAction` still opens the URL directly.