@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
@@ -0,0 +1,146 @@
1
+ # Task List: Remove the Knip baseline
2
+
3
+ See: [`docs/implementationPlans/knip-cleanup.md`](../implementationPlans/knip-cleanup.md)
4
+
5
+ **Status:** Complete
6
+ **RTK deprecation flag:** None
7
+
8
+ ## Instructions for the implementing agent
9
+
10
+ - Re-run Knip (JSON reporter, default + production, same as `scripts/static-analysis/full.ts`) at the start of every task. The IP inventory is a snapshot, not the live list.
11
+ - Disposition order: **entry → ignore (with comment) → unexport → delete**. Never `knip --fix`.
12
+ - Do not delete the old Knip baseline until Task 6.1. Earlier tasks must keep `bun run analyze:full` green while the live finding count falls.
13
+ - Do not remove symbols from published package public entries (`src/index.ts` / `src/index.tsx` / `package.json` `exports`).
14
+ - Do not remove Expo autolink, native, or Metro packages from `demo`, `admin-spa`, `example-frontend`, or `ui` `package.json` because Knip cannot see them.
15
+ - Tests: `bun test --only-failures` on the closest package; after config edits, `bun test scripts/static-analysis/lib.test.ts`.
16
+ - Supporting skills: `update-docs`. UI deletes also use `verify-ui-changes`.
17
+
18
+ ### Phase 1: Entry graph
19
+
20
+ - [x] **Task 1.1**: Register isolated suites and repo script tests as Knip entries
21
+ - Delivers: `*.isolated.ts(x)` and `scripts/**/*.test.ts` (plus `scripts/static-analysis/lib.test.ts`, `.github/scripts/*.test.ts`) stop reporting as unused files
22
+ - Files: `knip.jsonc`, `docs/explanation/static-analysis.md` (entry-graph section: isolated files and `scripts/` tests are first-class entries)
23
+ - Blocked by: none
24
+ - Docs: `docs/explanation/static-analysis.md`
25
+ - Skills: `update-docs`
26
+ - Acceptance: live default Knip report has no `files` finding whose path contains `.isolated.` or `scripts/` + `.test.`; `bun run analyze:full` exits 0; docs name this entry rule
27
+
28
+ - [x] **Task 1.2**: Put mcp-server tests back on the Bun plugin
29
+ - Delivers: `mcp-server/src/__tests__/**` are in the graph (today `workspaces.mcp-server.bun: false` because Knip 6.34 wants `test.preload` as an array)
30
+ - Files: `knip.jsonc` and/or `mcp-server/package.json` (`test.preload` array form if required)
31
+ - Blocked by: none
32
+ - Docs: none beyond a comment in `knip.jsonc`
33
+ - Acceptance: no default `files` findings under `mcp-server/src/__tests__/`; mcp `bun test` still runs; `analyze:full` exits 0
34
+
35
+ - [x] **Task 1.3**: Register codegen, Metro stubs, Playwright, fingerprint, and Docusaurus theme entries
36
+ - Delivers: tool-owned files are entries instead of “unused files”: `openapi-config.ts`, `comms-openapi-config.ts`, `jspdf-native-stub.js`, `fingerprint.config.js`, `playwright.circleci.config.ts`, `ui/babel.config.js`, `website/src/theme/**`, `scripts/ci/prepare-package-publish.mjs`, `scripts/planning/fingerprintRisk.ts`, `scripts/planning/updateDependenciesPr.ts` if they are invoked from `package.json` / CI
37
+ - Files: `knip.jsonc`; `package.json` scripts only if an entry name is wrong
38
+ - Blocked by: none
39
+ - Docs: `docs/explanation/static-analysis.md` — table row for Metro stubs / codegen configs
40
+ - Skills: `update-docs`
41
+ - Acceptance: those paths are absent from live `files` findings or listed as `entry`; comments explain each ignore glob if an ignore is used instead; `analyze:full` exits 0
42
+
43
+ - [x] **Task 1.4**: Ignore generated Expo skill script copies; keep the canonical copy in graph if it is real
44
+ - Delivers: duplicate `expo-cicd-workflows/scripts/{fetch,validate}.js` under `.agents/`, `.claude/`, `.cursor/`, `.devin/`, `.github/`, `.rulesync/`, `skills/` do not appear as unused files
45
+ - Files: `knip.jsonc` ignore globs; confirm canonical path (`.rulesync/skills/...` or `skills/...`)
46
+ - Blocked by: none
47
+ - Docs: one sentence in `docs/explanation/static-analysis.md` that generated skill copies are ignored
48
+ - Skills: `update-docs`
49
+ - Acceptance: no `files` findings whose path contains `expo-cicd-workflows/scripts/`; `analyze:full` exits 0
50
+
51
+ ### Phase 2: Documented ignores (cannot fix)
52
+
53
+ - [x] **Task 2.1**: Ignore Expo autolink / Metro / font / native `dependencies` Knip cannot see
54
+ - Delivers: `ignoreDependencies` (or workspace-scoped equivalent) for the live unused-deps list on `demo`, `admin-spa`, `example-frontend`, `ui` that exist for autolinking or Metro, including `jspdf` unlisted from metro stubs and `expo-system-ui` / `expo-updates` unlisted from `app.json`
55
+ - Files: `knip.jsonc`, `docs/explanation/static-analysis.md` (why these stay in `package.json`)
56
+ - Blocked by: Task 1.3
57
+ - Docs: `docs/explanation/static-analysis.md`
58
+ - Skills: `update-docs`
59
+ - Acceptance: those packages are gone from live `dependencies` / `unlisted` findings; each ignore has a comment; no app/`ui` `package.json` lost an Expo native dep; `analyze:full` exits 0
60
+
61
+ - [x] **Task 2.2**: Ignore binaries, catalog-only, and optional peers that are real
62
+ - Delivers: `eas`, `maestro`, catalog `@sentry/react-native` if unused in this repo but required by the catalog contract, `admin-frontend` optional `react-native-webview`
63
+ - Files: `knip.jsonc`
64
+ - Blocked by: none
65
+ - Docs: comment in `knip.jsonc`; mention binaries in `docs/explanation/static-analysis.md` if not already there
66
+ - Skills: `update-docs`
67
+ - Acceptance: live report has no `binaries` / `catalog` / `optionalPeerDependencies` findings except any still destined for Task 3.1 deletion; `analyze:full` exits 0
68
+
69
+ - [x] **Task 2.3**: Ignore remaining unlisted modules that are optional or type-only
70
+ - Delivers: honest ignores or `optionalDependencies` for `ioredis` (rate-limit redis store), `@ai-sdk/google-vertex`, `@docusaurus/plugin-content-docs`, `express` in ai tests, `@terreno/api` from `@terreno/test` if the graph cannot see the workspace package
71
+ - Files: `knip.jsonc` and/or the declaring `package.json` if the package should be listed instead of ignored
72
+ - Blocked by: Task 1.2
73
+ - Acceptance: Pick records in the task log each remaining unlisted name as either added to `package.json` or ignored with reason; live `unlisted` count is 0 or only items Task 3 will delete; `analyze:full` exits 0
74
+
75
+ ### Phase 3: Remove true unused packages
76
+
77
+ - [x] **Task 3.1**: Delete unused `devDependencies` after the graph is honest
78
+ - Delivers: remove packages that still appear as unused `devDependencies` and are not CLIs invoked from scripts (`sinon`, `@types/sinon`, `@types/bcrypt`, `@types/cron`, leftover `typedoc`/`prettier`/`ts-node`/`tsx` only if no script references them). Keep `@rtk-query/codegen-openapi`, `@biomejs/biome`, `mongodb` as a driver for example-backend tests, etc., when a script or plugin uses them — those become entries or ignores in Phase 1–2, not deletions
79
+ - Files: affected `package.json` files, lockfile via `bun install`
80
+ - Blocked by: Task 1.1, Task 1.2, Task 1.3, Task 2.2
81
+ - Docs: none unless a documented install step named a removed tool
82
+ - Acceptance: `rg` of the repo and `package.json` scripts show no remaining reference; `bun run compile` (or package `compile`) and the package test script still pass for each touched package; live unused-devDep list for those names is empty; `analyze:full` exits 0
83
+
84
+ - [x] **Task 3.2**: Remove unused runtime deps that are not Expo/autolink
85
+ - Delivers: example-backend / website / test / api leftovers (`clsx`, unused `lodash` in `@terreno/test`, `generaterr` / `scmp` / `@sentry/profiling-node` **only if** nothing loads them including Sentry init). If a dep is loaded via string/dynamic import, ignore it instead
86
+ - Files: affected `package.json`, source if an import must move
87
+ - Blocked by: Task 2.1, Task 3.1
88
+ - Acceptance: each removed name has no remaining import; package tests pass; `analyze:full` exits 0
89
+
90
+ ### Phase 4: Dead files
91
+
92
+ - [x] **Task 4.1**: Delete in-repo-dead example-frontend modules
93
+ - Delivers: remove unused files Knip still reports after Phase 1 (candidates from snapshot: `hooks/useLogoutUser.ts`, `useSentryUserSetup.ts`, `useUpdateProfile.ts`, `constants/Colors.ts`, and any unused store helpers). Keep files that routes, tests, or docs still import — those need an entry or a real import
94
+ - Files: `example-frontend/**` listed by live Knip `files`
95
+ - Blocked by: Task 1.3
96
+ - Docs: update example-frontend docs/README only if a named file was documented
97
+ - Skills: `update-docs`, `verify-ui-changes` if a routed screen changes
98
+ - Acceptance: those paths absent from live `files` findings; `cd example-frontend && bun test` passes; if UI was unwired, login + related screen still work with artifacts under `/opt/cursor/artifacts/`
99
+
100
+ - [x] **Task 4.2**: Delete or wire dead demo / example-backend / api example files
101
+ - Delivers: `demo/stories/PasswordField.stories.tsx` if unregistered; `demo/.eslintrc.js` if unused; `example-backend` unused scripts (`configuration-example.ts`, `seed-admin-spa-admin.ts`, `seedConsents.ts`) unless `package.json` / AdminApp should call them — then add entries; `example-backend/src/constants/index.ts` if a banned barrel leftover; `api/src/example.ts`; unused vendor `convert-yaml.js` only if nothing requires it
102
+ - Files: paths from live Knip `files` in those packages
103
+ - Blocked by: Task 1.3
104
+ - Docs: example-backend README / how-to if a seed script is removed or registered
105
+ - Skills: `update-docs`
106
+ - Acceptance: live `files` findings for those packages are 0 or only ignored globs; relevant `bun test` passes; `analyze:full` exits 0
107
+
108
+ - [x] **Task 4.3**: Delete or keep-with-entry remaining unused files (`ui/checkDeps.js`, `processCounties.js`, `compileAuthEntry.ts`, leftover demo tests already covered)
109
+ - Delivers: every remaining default `files` finding is either an entry, an ignore glob with comment, or deleted
110
+ - Files: leftover paths from live Knip
111
+ - Blocked by: Task 1.1, Task 1.4, Task 4.1, Task 4.2
112
+ - Acceptance: live default+production `files` count is 0; `analyze:full` exits 0
113
+
114
+ ### Phase 5: Exports and types
115
+
116
+ - [x] **Task 5.1**: Unexport unused **internal** symbols in `scripts/` and examples
117
+ - Delivers: after tests are in the graph, remaining unused exports/types in `scripts/`, `example-frontend/`, `example-backend/`, `demo/` that are not a public package entry become non-exported (or deleted if the whole helper is dead)
118
+ - Files: modules named by live `exports` / `types` findings in those trees
119
+ - Blocked by: Task 1.1, Task 4.1, Task 4.2
120
+ - Acceptance: those packages have no unused **internal** export/type findings; tests that imported the symbol still compile (they use the same module, not the export); `analyze:full` exits 0
121
+
122
+ - [x] **Task 5.2**: Unexport unused **internal** symbols in published packages
123
+ - Delivers: same as 5.1 for `api`, `admin-frontend`, `comms`, `syncdb`, `mcp-server`, `ai`. Do **not** remove re-exports from `src/index.ts(x)`
124
+ - Files: internal modules named by live findings
125
+ - Blocked by: Task 1.2
126
+ - Docs: none unless a documented “internal helper” was publicized in explanation/reference — then update that page
127
+ - Skills: `update-docs`
128
+ - Acceptance: each remaining unused export/type is classified public (re-exported from the package entry) or is gone; package `bun test` / `compile` passes; `analyze:full` exits 0
129
+
130
+ - [x] **Task 5.3**: Ignore leftover **public** unused exports and types
131
+ - Delivers: `ignoreIssues` (path-scoped `exports`/`types`) for public API unused inside this monorepo, with comments
132
+ - Files: `knip.jsonc`, `docs/explanation/static-analysis.md` (public API ignore rule)
133
+ - Blocked by: Task 5.1, Task 5.2
134
+ - Docs: `docs/explanation/static-analysis.md`
135
+ - Skills: `update-docs`
136
+ - Acceptance: live `exports` and `types` counts are 0; no public `index` export removed; `analyze:full` exits 0
137
+
138
+ ### Phase 6: Remove baseline
139
+
140
+ - [x] **Task 6.1**: Delete the Knip baseline and enforce zero findings directly
141
+ - Delivers: live default+production fingerprint set is `[]`; no Knip baseline exists; docs state that new findings are fixed or added to `knip.jsonc` with a reason
142
+ - Files: delete `scripts/static-analysis/knip-baseline.json`; update `docs/explanation/static-analysis.md`, `scripts/static-analysis/full.ts`, and tests
143
+ - Blocked by: Task 2.1, Task 2.2, Task 2.3, Task 3.2, Task 4.3, Task 5.3
144
+ - Docs: `docs/explanation/static-analysis.md`
145
+ - Skills: `update-docs`
146
+ - Acceptance: `test ! -e scripts/static-analysis/knip-baseline.json`; `bun run check:knip` prints no findings and exits 0; `bun run analyze:full` exits 0; static-analysis tests pass
@@ -0,0 +1,209 @@
1
+ # Tasks: Migrate built-in admin to syncdb
2
+
3
+ IP: [migrate-admin-to-syncdb.md](../implementationPlans/migrate-admin-to-syncdb.md)
4
+
5
+ **Status:** Approved. Pick–Roast execution is in progress.
6
+
7
+ Skills for Pick: `terreno-data-fetching`, `terreno-backend-api`, `mongoose-schema-safety` (only if a later task touches schema — this IP must not), `generate-sdk` (only if OpenAPI for non-admin routes changes), `verify-ui-changes`, `update-docs`, `backend-test-env`, `terreno-ui`, `update-agent-docs`.
8
+
9
+ ---
10
+
11
+ ## Phase 1 — Characterization + CI (no product behavior)
12
+
13
+ Phase 1 is a hard gate. Protocol and UI tasks stay blocked until every Phase 1 checkbox is done.
14
+
15
+ - [x] **Task 1.1**: `admin-frontend` ≥95% line+function coverage + threshold
16
+ - Delivers: existing screens/hooks covered enough that `bun test` in `admin-frontend` meets 95% lines and functions; `bunfig.toml` `coverageThreshold` set so CI fails on drop
17
+ - Files: `admin-frontend/src/**/*.test.*`, `admin-frontend/bunfig.toml`
18
+ - Blocked by: none
19
+ - Acceptance: `cd admin-frontend && bun test --coverage` reports ≥95% lines and functions; threshold is committed
20
+
21
+ - [x] **Task 1.2**: `admin-backend` coverage scope excludes `@terreno/test` dist
22
+ - Delivers: LCOV / bun coverage for the package measures `admin-backend/src` (and dist of this package only), not `../test/dist/**`; package still ≥95% on that scope
23
+ - Files: `admin-backend/bunfig.toml` (or coverage ignore), related test config
24
+ - Blocked by: none
25
+ - Acceptance: coverage report no longer attributes `@terreno/test` files; `adminApp.ts` and package source still ≥95%; `cd admin-backend && bun test --coverage` green
26
+
27
+ - [x] **Task 1.3**: CircleCI jobs for admin packages
28
+ - Delivers: `admin-backend-ci` and `admin-frontend-ci` in continue-config; root script `admin-frontend:test`; both jobs in the required workflow
29
+ - Files: `.circleci/continue-config.yml`, `package.json`
30
+ - Blocked by: 1.1, 1.2
31
+ - Acceptance: config YAML lists both jobs; `bun run admin-frontend:test` and `bun run admin-backend:test` work from repo root
32
+
33
+ - [x] **Task 1.4**: Shard existing admin Playwright specs into CI
34
+ - Delivers: `example-frontend/e2e/admin-home.spec.ts`, `admin-form.spec.ts`, `admin-table-search-filter.spec.ts`, `admin-table-bulk-actions.spec.ts`, `admin-custom-screens.spec.ts`, `admin-comms-back.spec.ts` (and siblings that exist) run in the CircleCI Playwright matrix, not only `admin.spec.ts`
35
+ - Files: `.circleci/continue-config.yml`, any e2e project config
36
+ - Blocked by: none
37
+ - Acceptance: continue-config matrix includes those spec files; a dry read of the YAML shows them next to `admin.spec.ts`
38
+
39
+ - [x] **Task 1.5**: Golden HTTP tests for admin membership + config
40
+ - Delivers: pinned assertions for `GET /admin/config` shape and list/search/bulk-patch on a synced String `_id` model (example Todo) plus an ObjectId model (User) so later protocol work cannot silently change REST
41
+ - Files: `admin-backend/src/adminApp*.test.ts` (or new focused spec)
42
+ - Blocked by: none
43
+ - Acceptance: tests fail if list query params, pagination envelope, or bulk-patch URL/body change; `bun test` in admin-backend passes
44
+
45
+ - [x] **Task 1.6**: Pin `useAdminApi` URL shapes
46
+ - Delivers: isolated tests that `list/read/create/update/delete/bulk-patch` hit `/admin/{routePath}` exactly as today
47
+ - Files: `admin-frontend/src/isolated/hooks.isolated.tsx`, `useAdminApi` tests
48
+ - Blocked by: none
49
+ - Acceptance: URL/method goldens for all six operations; isolated suite green
50
+
51
+ - [x] **Task 1.7**: CRUD smoke E2E for embedded + SPA
52
+ - Delivers: Playwright covering Todos list → create → edit → delete on `example-frontend` `/admin` and `admin-spa` `/console` (extend existing specs; do not skip login/consent)
53
+ - Files: `example-frontend/e2e/admin.spec.ts` (or `admin-form.spec.ts`), `admin-spa/e2e/integration/adminSpa.integration.spec.ts` or new `admin-spa/e2e/crud.spec.ts`
54
+ - Blocked by: none
55
+ - Acceptance: specs assert visible row after create, field change after edit, row gone after delete; they pass locally against the documented full-stack commands
56
+ - Skills: `verify-ui-changes` (record how to run; Phase 1 may land specs that CI runs)
57
+
58
+ ---
59
+
60
+ ## Phase 2 — Fetch wrapper (RPC off RTK)
61
+
62
+ - [x] **Task 2.1**: Tiny fetch client
63
+ - Delivers: `adminRequest({url, method, body, signal})` using native `fetch`, AbortController timeout, JSON + FormData, maps failures to `APIError`; unit tests with mocked `globalThis.fetch`
64
+ - Files: `admin-frontend/src/adminRequest.ts`, `admin-frontend/src/adminRequest.test.ts`
65
+ - Blocked by: 1.1
66
+ - Acceptance: tests for timeout abort, 4xx/5xx → APIError, JSON parse, FormData not JSON-stringified, credentials forwarded; no axios import
67
+ - Skills: `terreno-data-fetching`
68
+
69
+ - [x] **Task 2.2**: Host-injected auth contract
70
+ - Delivers: admin context accepts `{baseUrl, getAuthHeaders, credentials}`; SPA fixture uses `credentials: "same-origin"` and empty/cookie headers; embedded fixture uses Bearer from `getAuthHeaders`
71
+ - Files: admin-frontend provider/context (existing Admin host types), tests
72
+ - Blocked by: 2.1
73
+ - Acceptance: unit tests prove Authorization header present/absent per fixture; cookie credential mode set
74
+ - Skills: `terreno-data-fetching`
75
+
76
+ - [x] **Task 2.3**: Dual-run RPC hooks onto fetch
77
+ - Delivers: `useAdminConfig`, scripts, roles, configuration, documents, comms, AI explorer, consent, version-config, background-tasks, `AdminObjectPicker` list fetch use `adminRequest` when the client is provided; if only `api` is provided, existing `injectEndpoints` still works
78
+ - Files: `admin-frontend/src/useAdminConfig.ts`, `useAdminScripts.ts`, `useAdminRoles.ts`, `useConfigurationApi.ts`, `useDocumentStorageApi.ts`, `useAdminBackgroundTask.ts`, `useConsentHistory.ts`, `ConsentFormEditor.tsx`, `AdminVersionConfig.tsx`, `AdminObjectPicker.tsx`, `comms/useCommsDashboardApi.tsx`, `widgets/AIRequestsScreenWidget.tsx`, tests
79
+ - Blocked by: 2.2, 1.6
80
+ - Acceptance: each hook has tests for both backends; no behavior change when only `api` is passed
81
+ - Skills: `terreno-data-fetching`
82
+
83
+ ---
84
+
85
+ ## Phase 3 — Protocol (`adminBroadcast` + window subscribe)
86
+
87
+ - [x] **Task 3.1**: `adminBroadcast` on `SyncConfig`
88
+ - Delivers: optional `adminBroadcast?: boolean` on existing collection `sync` config; default false; registration stores the flag; docs comment in types
89
+ - Files: `api/src/sync/types.ts`, `api/src/api.ts` (options plumbing), `api/src/sync/*.test.ts`
90
+ - Blocked by: 1.5
91
+ - Acceptance: registering with/without the flag; existing sync tests pass; no second `registerSync` for the same model
92
+ - Skills: `terreno-backend-api`
93
+
94
+ - [x] **Task 3.2**: Emit deltas to `{collection}|admin`
95
+ - Delivers: when `adminBroadcast` is true, change-stream / mutate emit also targets `{collection}|admin` in addition to the owner/tenant/broadcast stream
96
+ - Files: emit path under `api/src/sync/` (change stream + mutate ack), tests
97
+ - Blocked by: 3.1
98
+ - Acceptance: unit/socket test: owner-scoped Todo create emits to `todos|owner:{id}` **and** `todos|admin`; flag false emits only the owner stream
99
+ - Skills: `terreno-backend-api`
100
+
101
+ - [x] **Task 3.3**: Window subscribe — no snapshot, no full reconcile
102
+ - Delivers: admin clients subscribe to `{collection}|admin` (or `sync:subscribe` with window mode) and receive **cursor/ack only**, not a full snapshot; syncdb skips `reconcile()` for that collection while in window mode
103
+ - Files: `api/src/sync/socketHandlers.ts`, `syncdb/src/client.ts`, subscribe/bootstrap/reconcile modules, tests on both sides
104
+ - Blocked by: 3.2
105
+ - Acceptance: socket test: window subscribe does not emit snapshot pages; client test: reconcile interval does not GET `/sync/snapshot` for that collection
106
+ - Skills: `terreno-backend-api`
107
+
108
+ - [x] **Task 3.4**: Hydrate known ids via REST + `GET /sync/entities`
109
+ - Delivers: helper used by admin UI (or syncdb window API) that given ids upserts entities; missing rows fetched from `/sync/entities`; RBAC: only admin-capable users may subscribe to `|admin`
110
+ - Files: `syncdb/src/sync/httpChannel.ts` (entities already), new window hydrate helper if needed, `api/src/sync/socketHandlers.ts` permission, tests
111
+ - Blocked by: 3.3, 1.5
112
+ - Acceptance: tests: hydrate 2 of 3 ids; unknown id ignored; non-admin subscribe to `|admin` nacks
113
+ - Skills: `terreno-backend-api`, `terreno-data-fetching`
114
+
115
+ - [x] **Task 3.5**: Known-id-only deltas + Refresh contract
116
+ - Delivers: delta applier in window mode updates/deletes **existing local ids only**; new server rows do not appear until membership Refresh or load-more upserts them
117
+ - Files: `syncdb/src/sync/deltaApplier.ts`, tests
118
+ - Blocked by: 3.3
119
+ - Acceptance: tests: delta for unknown id is no-op; delta for known id updates store; delete delta removes known id; documented Refresh is a REST re-query + upsert (implemented in 4.x, contract tested here at applier)
120
+
121
+ ---
122
+
123
+ ## Phase 4 — Admin UI dual-run
124
+
125
+ - [x] **Task 4.1**: `AdminModelTable` windowed path
126
+ - Delivers: when `syncDb` + fetch client present and model is String `_id` + synced + `adminBroadcast`, table membership from REST, rows from TinyBase, load more hydrates, Refresh control visible
127
+ - Files: `admin-frontend/src/AdminModelTable.tsx`, tests
128
+ - Blocked by: 3.4, 3.5, 2.2, 1.7
129
+ - Acceptance: unit tests with fake syncdb: page ids render; extra delta id does not render; Refresh adds it; RTK path still used when `api` only
130
+ - Skills: `terreno-ui`, `verify-ui-changes`
131
+
132
+ - [x] **Task 4.2**: `AdminModelForm` syncdb writes
133
+ - Delivers: create/update/delete for String `_id` synced models go through `useMutate`; ObjectId models stay fetch/RTK dual-run
134
+ - Files: `admin-frontend/src/AdminModelForm.tsx`, tests
135
+ - Blocked by: 4.1
136
+ - Acceptance: form save tests for both model classes; ObjectId never calls `useMutate`
137
+ - Skills: `terreno-ui`
138
+
139
+ - [x] **Task 4.3**: ConflictSheet in admin
140
+ - Delivers: `useConflicts` + `ConflictSheet` (`useServer` / `keepMine`) for admin-loaded ids, same as example app
141
+ - Files: admin-frontend conflict host (table or shell), tests
142
+ - Blocked by: 4.2
143
+ - Acceptance: test: conflict row shows sheet; keepMine / useServer callbacks invoked
144
+ - Skills: `terreno-ui`
145
+
146
+ - [x] **Task 4.4**: Bulk-patch stays fetch
147
+ - Delivers: existing bulk-patch still uses fetch/RTK dual-run (not sync mutate) with goldens from 1.5/1.6 still passing
148
+ - Files: table bulk actions wiring
149
+ - Blocked by: 2.3, 4.1
150
+ - Acceptance: bulk-patch tests still pass on both backends
151
+
152
+ ---
153
+
154
+ ## Phase 5 — Hosts
155
+
156
+ - [x] **Task 5.1**: example-frontend `/admin`
157
+ - Delivers: `AdminProvider` gets fetch client (Bearer) + existing `syncDb`; example `Todo` `sync` sets `adminBroadcast: true`; `/admin` Todos changelist uses windowed path
158
+ - Files: `example-frontend` admin layout/store, `example-backend/src/api/todos.ts` (`adminBroadcast: true`)
159
+ - Blocked by: 4.3, 4.4
160
+ - Acceptance: `bun run backend:dev` + `frontend:web`; Playwright from 1.7 still passes; new assertions for Refresh optional
161
+ - Skills: `verify-ui-changes`, `generate-sdk` only if OpenAPI changed (should not)
162
+
163
+ - [x] **Task 5.2**: admin-spa `/console`
164
+ - Delivers: same windowed Todos path with `credentials: "same-origin"`; SyncDbProvider in SPA; cookie session still logs in
165
+ - Files: `admin-spa` app providers, e2e
166
+ - Blocked by: 5.1
167
+ - Acceptance: SPA CRUD E2E from 1.7 passes with the new path; no Bearer required for same-origin
168
+ - Skills: `verify-ui-changes`
169
+
170
+ ---
171
+
172
+ ## Phase 6 — Docs, skills, deprecation
173
+
174
+ - [x] **Task 6.1**: Human + agent docs
175
+ - Delivers: admin collection CRUD documented as windowed syncdb; RPC as fetch wrapper; `adminBroadcast` + window subscribe in syncdb reference; migrate-rtk guide no longer says admin collection CRUD stays RTK; `api`/`injectEndpoints` deprecated; next-major removal named; changelog
176
+ - Files: `docs/reference/syncdb.md`, `docs/how-to/migrate-rtk-to-syncdb.md`, `docs/reference/admin.md` / `admin-frontend` pages if present, `.rulesync/skills/terreno-data-fetching`, `verify-ui-changes` if admin login steps change, changelog
177
+ - Blocked by: 5.2
178
+ - Acceptance: `update-docs` checklist; `bun run skills:sync` if skill text changed; no remaining “keep admin on RTK” for **model CRUD**
179
+ - Skills: `update-docs`, `update-agent-docs`
180
+
181
+ ---
182
+
183
+ ## Task graph (Pick frontier)
184
+
185
+ ```
186
+ 1.1 1.2 1.4 1.5 1.6 1.7
187
+ └─ 1.3 (needs 1.1+1.2)
188
+
189
+ 2.1 ← 1.1
190
+ 2.2 ← 2.1
191
+ 2.3 ← 2.2, 1.6
192
+
193
+ 3.1 ← 1.5
194
+ 3.2 ← 3.1
195
+ 3.3 ← 3.2
196
+ 3.4 ← 3.3, 1.5
197
+ 3.5 ← 3.3
198
+
199
+ 4.1 ← 3.4, 3.5, 2.2, 1.7
200
+ 4.2 ← 4.1
201
+ 4.3 ← 4.2
202
+ 4.4 ← 2.3, 4.1
203
+
204
+ 5.1 ← 4.3, 4.4
205
+ 5.2 ← 5.1
206
+ 6.1 ← 5.2
207
+ ```
208
+
209
+ First Pick after Approved: **Task 1.1** (and any other Phase 1 tasks with `Blocked by: none` as the frontier).
@@ -0,0 +1,107 @@
1
+ # Tasks: MongoDB migrations tooling
2
+
3
+ IP: [mongodb-migrations-tooling.md](../implementationPlans/mongodb-migrations-tooling.md)
4
+ **Closes:** https://github.com/FlourishHealth/terreno/issues/1189
5
+
6
+ **Feature profile:** false (full IP)
7
+
8
+ ## Phase 1 — Runner, lock, history
9
+
10
+ - [x] **Task 1.1**: Migration context + in-memory/programmatic runner
11
+ - Delivers: `runMigrations({migrations, dryRun})` runs pending `up` in order; dry-run calls `up({dryRun: true})` and does **not** record applied ids; wet records checksum + `appliedAt`; already-applied ids are skipped; checksum mismatch throws
12
+ - Files: `api/src/migrations/types.ts`, `api/src/migrations/runner.ts`, `api/src/migrations/runner.test.ts`
13
+ - Blocked by: none
14
+ - Skills: `terreno-backend-api`, `backend-test-env`, `mongoose-schema-safety`
15
+ - Docs: stub “Migrations” subsection in `docs/reference/api.md`
16
+ - Acceptance: bun tests — dry-run increments a counter inside `up` but history stays empty; wet applies once; second wet is a no-op; edited checksum fails
17
+
18
+ - [x] **Task 1.2**: Lock collection (wait, heartbeat, 10-minute steal)
19
+ - Delivers: `withMigrationLock` uses `terreno_migrations` `_id: "_lock"`; concurrent second waiter proceeds after steal when `expiresAt` is past; holder heartbeats; `finally` releases
20
+ - Files: `api/src/migrations/lock.ts`, `api/src/migrations/lock.test.ts`; wire lock around wet `runMigrations`
21
+ - Blocked by: 1.1
22
+ - Skills: `backend-test-env`, `mongoose-schema-safety`
23
+ - Docs: lock TTL in the api.md stub
24
+ - Acceptance: two overlapping wet runs serialize; expired lock is stolen; crash-simulated missing release still steals after TTL (test injects past `expiresAt`)
25
+
26
+ ## Phase 2 — Files, CLI, production gate
27
+
28
+ - [x] **Task 2.1**: File loader + `checkMigrationFiles`
29
+ - Delivers: load `migrations/<YYYYMMDDHHmmss>-<slug>.ts`; id must match filename; duplicate ids fail; optional `down`; `checkMigrationFiles` is the no-Mongo CI check
30
+ - Files: `api/src/migrations/load.ts`, `api/src/migrations/load.test.ts`, fixture files under `api/src/migrations/fixtures/`
31
+ - Blocked by: 1.1
32
+ - Skills: `terreno-backend-api`
33
+ - Docs: file naming in api.md
34
+ - Acceptance: tests for sort order, bad id, missing export, successful load of `up`/`down`
35
+
36
+ - [x] **Task 2.2**: Production gate + CLI `status`/`up`/`down`/`check`
37
+ - Delivers: `terreno-migrate` bin; prod wet requires `ALLOW_MIGRATIONS=true` and `--force`; `down --steps` stops with a clear error when `down` is missing; `--dry` never writes history
38
+ - Files: `api/src/migrations/cli.ts`, `api/src/migrations/cli.test.ts`, `api/package.json` `bin`, `api/src/index.ts` exports
39
+ - Blocked by: 1.2, 2.1
40
+ - Skills: `terreno-backend-api`, `backend-test-env`
41
+ - Docs: command table in `docs/how-to/run-mongodb-migrations.md` (create page); `ALLOW_MIGRATIONS` row in `docs/reference/environment-variables.md`
42
+ - Acceptance: argv tests (help, check, dry up, prod deny); integration up/down against memory Mongo; `down` without function fails
43
+
44
+ ## Phase 3 — Generate from schema snapshot
45
+
46
+ - [x] **Task 3.1**: Schema catalog + diff
47
+ - Delivers: `buildSchemaCatalog(models)` and `diffSchemaCatalog(before, after)` covering indexes, optional fields, required, unique, rename heuristic
48
+ - Files: `api/src/migrations/schemaCatalog.ts`, `api/src/migrations/schemaCatalog.test.ts`
49
+ - Blocked by: none (can parallel 1.x in theory; Pick runs after 2.2)
50
+ - Skills: `mongoose-schema-safety`
51
+ - Docs: what generate can/cannot emit (how-to)
52
+ - Acceptance: fixture schemas produce stable catalogs; required+unique+rename classified unsafe; optional field + index classified safe
53
+
54
+ - [x] **Task 3.2**: `generate` CLI writes a timestamped file
55
+ - Delivers: `terreno-migrate generate --dir --models`; uses last `schemaAfter`; no-op diff exits 0; unsafe ops emit throwing stub; generated `up` honors `dryRun` for safe index ops
56
+ - Files: `api/src/migrations/generate.ts`, `api/src/migrations/generate.test.ts`, CLI subcommand
57
+ - Blocked by: 2.2, 3.1
58
+ - Skills: `mongoose-schema-safety`, `update-docs`
59
+ - Docs: generate workflow on the how-to
60
+ - Acceptance: temp dir tests — first generate from empty snapshot; second generate no-op; required-field stub throws in dry-run and wet
61
+
62
+ ## Phase 4 — Boot hook
63
+
64
+ - [x] **Task 4.1**: `TerrenoApp` `migrations.runOnStart`
65
+ - Delivers: option default off; when true, wet `up` after DB connect before listen; prod still needs `ALLOW_MIGRATIONS`; failure prevents listen
66
+ - Files: `api/src/terrenoApp.ts`, `api/src/terrenoApp.migrations.test.ts` (or extend existing app tests)
67
+ - Blocked by: 2.2
68
+ - Skills: `terreno-backend-api`, `backend-test-env`
69
+ - Docs: option table in api.md
70
+ - Acceptance: tests — omitted option does not query `terreno_migrations`; `runOnStart: true` applies pending; prod without env throws before listen
71
+
72
+ ## Phase 5 — Admin HTTP
73
+
74
+ - [x] **Task 5.1**: Admin migrations routes + config flag
75
+ - Delivers: `GET /admin/migrations/status` and `POST /admin/migrations/run?wetRun=` as `modelRouter` collection actions; creates BackgroundTask and runs batch pending; poll/cancel via existing script task routes; prod wet 403 without `ALLOW_MIGRATIONS`; `GET /admin/config` includes `migrations.enabled`
76
+ - Files: `admin-backend/src/adminApp.ts`, `admin-backend/src/adminApp.migrations.test.ts`, AdminApp options type
77
+ - Blocked by: 1.2, 2.1
78
+ - Skills: `terreno-backend-api`, `building-admin-interfaces`, `backend-test-env`
79
+ - Docs: `docs/reference/admin-config.md` + admin-backend reference
80
+ - Acceptance: 201 + taskId; dry-run does not persist applied ids; non-admin 403; unknown when migrations not configured 404
81
+
82
+ ## Phase 6 — Admin UI
83
+
84
+ - [x] **Task 6.1**: Migrations page, nav, spa route
85
+ - Delivers: `__migrations` screen distinct from `__scripts`; status list; Dry run / Apply pending; reuse task polling (script-runner modal or equivalent); shell nav when `migrations.enabled`
86
+ - Files: `admin-frontend/src/AdminMigrations.tsx`, tests, `AdminShell.tsx`, `AdminScreenRouter.tsx`, types; `admin-spa` route
87
+ - Blocked by: 5.1
88
+ - Skills: `terreno-ui`, `building-admin-interfaces`, `verify-ui-changes`, `update-docs`
89
+ - Docs: `docs/how-to/build-admin-screens.md` nav note
90
+ - Acceptance: frontend tests for routing/nav; browser verification of dry-run vs apply on example admin (artifacts under `/opt/cursor/artifacts/`)
91
+
92
+ ## Phase 7 — Example, CI, agent docs
93
+
94
+ - [x] **Task 7.1**: example-backend wiring + reversible fixture
95
+ - Delivers: `example-backend/migrations/` with a reversible index (or no-op) migration; package scripts `migrate:check` / `migrate:up` / `migrate:status`; test `exerciseReversibleMigrations`; do not wipe `terreno_migrations` in seed reset
96
+ - Files: `example-backend/package.json`, `example-backend/src/server.ts` (pass `migrations` into AdminApp + TerrenoApp), seed reset guard, tests
97
+ - Blocked by: 2.2, 5.1
98
+ - Skills: `update-docs`, `backend-test-env`
99
+ - Docs: example commands on the how-to
100
+ - Acceptance: `bun test` in example-backend covers migrate check + up/down; seed `--reset` leaves history collection
101
+
102
+ - [x] **Task 7.2**: Diátaxis, changelog, mongoose-schema-safety
103
+ - Delivers: how-to complete; api/env/admin reference; skill tells authors to use versioned migrations for backfills; `CHANGELOG.md` Added; `bun run skills:sync` / `bun run rules` if the skill source changed
104
+ - Files: `docs/how-to/run-mongodb-migrations.md`, `docs/how-to/README.md`, `docs/reference/*`, `docs/how-to/seed-a-database.md`, `plugins/terreno-planning/skills/mongoose-schema-safety/SKILL.md` (canonical then sync), `CHANGELOG.md`
105
+ - Blocked by: 3.2, 4.1, 6.1, 7.1 (content must match shipped CLI/UI)
106
+ - Skills: `update-docs`
107
+ - Acceptance: stranger can generate → dry-run → up from the how-to; skill no longer points only at ad-hoc `ScriptRunner` backfills
@@ -0,0 +1,102 @@
1
+ # Tasks: In-app notification center
2
+
3
+ IP: [notification-center.md](../implementationPlans/notification-center.md)
4
+ **Closes:** https://github.com/FlourishHealth/terreno/issues/1179
5
+
6
+ **Feature profile:** false (full IP)
7
+
8
+ ## Phase 1 — Tracer (inbox write + sync)
9
+
10
+ - [x] **Task 1.1**: Notification model + `NotificationsApp` + `notify()` inbox write
11
+ - Delivers: `new NotificationsApp()` registers owner-scoped `/notifications` with `create: []`, `sync: {scope: {type: "owner"}}`, `isDeletedPlugin` + `syncPlugin`; `getNotificationService().notify({userId, title, body, href?, kind?})` inserts a row and change-stream/sync can see it; HTTP/sync create is 403/nack
12
+ - Files: `api/src/models/notification.ts`, `api/src/types/notification.ts`, `api/src/notifications/notificationsApp.ts`, `api/src/notifications/notificationService.ts`, `api/src/notifications/notificationsApp.test.ts`, `api/src/index.ts`
13
+ - Blocked by: none
14
+ - Skills: `terreno-backend-api`, `mongoose-schema-safety`, `backend-test-env`, `update-docs`
15
+ - Docs: stub **In-app notifications** in `docs/reference/api.md` (do not mix with Slack/Zoom notifiers)
16
+ - Acceptance: bun + supertest — `notify` creates one owner row; unauthenticated list 401; other user cannot read; POST `/notifications` 403 or disabled; every schema field has `description`
17
+
18
+ - [x] **Task 1.2**: Owner mark-read and dismiss
19
+ - Delivers: `preUpdate` allows only `readAt` (ISO/date or `null`); `delete` soft-deletes; other fields in PATCH are stripped/rejected; unread query is `readAt` unset/null
20
+ - Files: `api/src/notifications/notificationsApp.ts`, tests in `notificationsApp.test.ts`
21
+ - Blocked by: 1.1
22
+ - Skills: `terreno-backend-api`, `backend-test-env`
23
+ - Docs: one sentence on patch/delete in the api.md stub
24
+ - Acceptance: bun tests — PATCH `{readAt}` persists; PATCH `{title: "x"}` does not change title; DELETE hides from list; second user 403
25
+
26
+ ## Phase 2 — Preferences, comms fan-out, retention
27
+
28
+ - [x] **Task 2.1**: Preference model + defaults + `notificationsBeforeSend`
29
+ - Delivers: `NotificationPreference` unique `ownerId`, four booleans default true; missing row treated as all on; export duck-typed `notificationsBeforeSend({channel, userId})` that cancels when that boolean is false (`verification` channel never cancelled by this hook)
30
+ - Files: `api/src/models/notificationPreference.ts`, `api/src/types/notificationPreference.ts`, preference router on `NotificationsApp`, tests
31
+ - Blocked by: 1.1
32
+ - Skills: `terreno-backend-api`, `mongoose-schema-safety`, `backend-test-env`
33
+ - Docs: prefs table in api.md stub
34
+ - Acceptance: bun tests — no row → beforeSend does not cancel; `mail: false` → `{cancel: true}` for `channel: "mail"`; inapp false → `notify` does **not** insert a Notification
35
+
36
+ - [x] **Task 2.2**: Optional comms fan-out from `notify()`
37
+ - Delivers: `NotificationsApp({getComms})`; after inbox write, call `sendMail` / `sendSms` / `sendPushToUser` when that pref is on and destination exists (email from User, phone if present on user, push via comms); missing `getComms` or missing destination skips that channel without failing `notify`; do not import `@terreno/comms` from `@terreno/api`
38
+ - Files: `api/src/notifications/notificationService.ts`, tests with a fake `getComms`
39
+ - Blocked by: 2.1
40
+ - Skills: `terreno-backend-api`, `backend-test-env`
41
+ - Docs: fan-out order in api.md
42
+ - Acceptance: bun tests — fake mail called when pref on + email present; mail not called when pref off; `notify` resolves when `getComms` throws after inbox write (log `logger.error`, still return the notification id)
43
+
44
+ - [x] **Task 2.3**: Mark-all-read + `retainDays`
45
+ - Delivers: `POST /notifications/mark-all-read` sets `readAt` on the caller's unread rows; `retainDays` default `0` (no sweep); `retainDays > 0` tombstones (`deleted`) rows with `created` older than N days (best-effort on `notify` and/or a small `sweepExpired()`); **no** Mongo TTL index
46
+ - Files: `notificationsApp.ts`, `notificationService.ts`, tests
47
+ - Blocked by: 1.2
48
+ - Skills: `terreno-backend-api`, `backend-test-env`
49
+ - Docs: `retainDays` default 0 in api.md
50
+ - Acceptance: bun tests — mark-all-read only affects caller; retainDays 0 leaves old rows; retainDays 1 tombstones a row dated 2 days ago via Luxon; collection indexes do not include a TTL expireAfterSeconds on Notification
51
+
52
+ ## Phase 3 — UI
53
+
54
+ - [x] **Task 3.1**: `NotificationBell` + `NotificationInbox`
55
+ - Delivers: presentational components (no syncdb import); bell shows badge from `unreadCount`; inbox lists items, mark read/unread, dismiss, tap calls `onOpen`; empty and loading states; `testID`s
56
+ - Files: `ui/src/NotificationBell.tsx`, `ui/src/NotificationInbox.tsx`, tests, `ui/src/index.tsx` exports
57
+ - Blocked by: none
58
+ - Skills: `terreno-ui`, `update-docs`, `verify-ui-changes`
59
+ - Docs: stub props in `docs/reference/ui.md`
60
+ - Acceptance: bun `ui` tests with `renderWithTheme`; badge hidden at 0; `onOpen` fired with the item; dismiss/mark callbacks fired
61
+
62
+ - [x] **Task 3.2**: `NotificationPreferences`
63
+ - Delivers: four `BooleanField`s bound to `{inapp, mail, push, sms}`; `onChange` per channel
64
+ - Files: `ui/src/NotificationPreferences.tsx`, test, export
65
+ - Blocked by: none
66
+ - Skills: `terreno-ui`
67
+ - Docs: prefs props in ui.md
68
+ - Acceptance: bun tests — toggling mail calls `onChange("mail", false)`
69
+
70
+ - [x] **Task 3.3**: Demo stories
71
+ - Delivers: demoConfig entries with fixture unread/read items and prefs toggles
72
+ - Files: `demo/stories/` + `demo/demoConfig.tsx` (or current demo registration)
73
+ - Blocked by: 3.1, 3.2
74
+ - Skills: `terreno-ui`, `verify-ui-changes`
75
+ - Docs: none (4.1)
76
+ - Acceptance: demo route renders bell + inbox + prefs without a backend
77
+
78
+ ## Phase 4 — Example app + docs
79
+
80
+ - [x] **Task 4.1**: example-backend register + demo notify
81
+ - Delivers: `NotificationsApp({getComms: getCommsService})`; compose `notificationsBeforeSend` into `CommsApp` `beforeSend`; authenticated demo route (follow `commsDev`) that `notify`s the current user
82
+ - Files: `example-backend/src/server.ts`, `example-backend/src/api/` demo route + test
83
+ - Blocked by: 2.2, 2.3
84
+ - Skills: `terreno-backend-api`, `backend-test-env`
85
+ - Docs: none (4.3)
86
+ - Acceptance: bun tests — registered routes exist; demo notify 401 without auth; 200 with auth creates a row
87
+
88
+ - [x] **Task 4.2**: example-frontend syncdb + bell + prefs
89
+ - Delivers: collections `notifications` and `notification-preferences`; bell on todos header; settings preferences screen; `onOpen` uses Expo Router for in-app `href`; optional “send test” calling the demo route
90
+ - Files: `example-frontend/store/syncdb.ts` (codegen/list), todos screen, settings route, tests if present
91
+ - Blocked by: 3.1, 3.2, 4.1
92
+ - Skills: `terreno-data-fetching`, `terreno-ui`, `verify-ui-changes`, `generate-sdk` (only if a non-sync demo route needs SDK)
93
+ - Docs: none (4.3)
94
+ - Acceptance: `useQuery` lists notify rows after demo send; mark read persists; prefs toggle survives reload (syncdb); no new RTK CRUD hooks for the collection
95
+
96
+ - [x] **Task 4.3**: Diátaxis docs + rules + changelog
97
+ - Delivers: `docs/how-to/in-app-notifications.md`; finish `docs/reference/api.md` and `docs/reference/ui.md`; `docs/reference/comms.md` beforeSend composition; `docs/how-to/README.md` link; `.rulesync/rules/api` mention + `bun run rules`; `changelog/unreleased/notification-center.md`
98
+ - Files: those docs + rules
99
+ - Blocked by: 4.2
100
+ - Skills: `update-docs`
101
+ - Docs: (this task)
102
+ - Acceptance: a stranger can register the plugin and wire the bell from the how-to without reading the IP; website/how-to index lists the page