@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.
- package/README.md +7 -1
- package/dist/bootstrap.d.ts +0 -18
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +10 -2428
- package/dist/bootstrap.js.map +1 -1
- package/dist/docs/guidelines/admin-frontend/guidelines/core.md +5 -1
- package/dist/docs/guidelines/api/skills/mongoose-schema-safety/SKILL.md +23 -10
- package/dist/docs/resources/syncdb.md +4 -1
- package/dist/docs/upgrades/57.4.0.md +140 -0
- package/dist/docs/versioned/next/README.md +3 -0
- package/dist/docs/versioned/next/explanation/README.md +4 -1
- package/dist/docs/versioned/next/explanation/admin-interface.md +20 -13
- package/dist/docs/versioned/next/explanation/charts.md +29 -0
- package/dist/docs/versioned/next/explanation/deployment-architecture-gcp.md +32 -0
- package/dist/docs/versioned/next/explanation/deployment-baseline.md +1 -1
- package/dist/docs/versioned/next/explanation/example-coverage.md +43 -0
- package/dist/docs/versioned/next/explanation/local-first-data.md +5 -2
- package/dist/docs/versioned/next/explanation/loop-engineering.md +9 -6
- package/dist/docs/versioned/next/explanation/model-router-actions.md +19 -2
- package/dist/docs/versioned/next/explanation/organizations.md +88 -0
- package/dist/docs/versioned/next/explanation/planning-plugins.md +114 -0
- package/dist/docs/versioned/next/explanation/positioning.md +3 -3
- package/dist/docs/versioned/next/explanation/repository-settings.md +6 -5
- package/dist/docs/versioned/next/explanation/roadmap-seed-issues.md +44 -34
- package/dist/docs/versioned/next/explanation/source-rules.md +1 -1
- package/dist/docs/versioned/next/explanation/static-analysis.md +76 -16
- package/dist/docs/versioned/next/how-to/README.md +10 -0
- package/dist/docs/versioned/next/how-to/add-gpt-chat-mascot.md +92 -0
- package/dist/docs/versioned/next/how-to/add-organizations.md +204 -0
- package/dist/docs/versioned/next/how-to/admin-add-model.md +9 -1
- package/dist/docs/versioned/next/how-to/admin-import-prebuilt.md +7 -1
- package/dist/docs/versioned/next/how-to/audit-log.md +85 -0
- package/dist/docs/versioned/next/how-to/background-jobs.md +296 -0
- package/dist/docs/versioned/next/how-to/build-admin-screens.md +42 -13
- package/dist/docs/versioned/next/how-to/charts-and-dashboards.md +37 -0
- package/dist/docs/versioned/next/how-to/circleci.md +136 -27
- package/dist/docs/versioned/next/how-to/compare-chart-rendered-snapshots.md +36 -0
- package/dist/docs/versioned/next/how-to/configure-better-auth.md +4 -0
- package/dist/docs/versioned/next/how-to/create-a-terreno-app.md +154 -0
- package/dist/docs/versioned/next/how-to/deploy-backend-to-cloud-run.md +2 -0
- package/dist/docs/versioned/next/how-to/github-actions-ci.md +4 -3
- package/dist/docs/versioned/next/how-to/github-issue-lifecycle.md +12 -8
- package/dist/docs/versioned/next/how-to/in-app-notifications.md +147 -0
- package/dist/docs/versioned/next/how-to/install-agent-skills.md +24 -12
- package/dist/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +19 -3
- package/dist/docs/versioned/next/how-to/product-announcements.md +155 -0
- package/dist/docs/versioned/next/how-to/run-mongodb-migrations.md +127 -0
- package/dist/docs/versioned/next/how-to/run-tests-locally.md +102 -0
- package/dist/docs/versioned/next/how-to/seed-a-database.md +7 -2
- package/dist/docs/versioned/next/implementationPlans/README.md +8 -5
- package/dist/docs/versioned/next/implementationPlans/admin-scripts-durable-jobs.md +44 -0
- package/dist/docs/versioned/next/implementationPlans/agent-ui-blocks.md +386 -0
- package/dist/docs/versioned/next/implementationPlans/agentic-sdlc-plugin.md +11 -8
- package/dist/docs/versioned/next/implementationPlans/announcements-surfaces.md +231 -0
- package/dist/docs/versioned/next/implementationPlans/announcements.md +289 -0
- package/dist/docs/versioned/next/implementationPlans/b2b-platform-program.md +3 -1
- package/dist/docs/versioned/next/implementationPlans/charts-and-dashboards.md +246 -0
- package/dist/docs/versioned/next/implementationPlans/comms-admin-dashboard.md +4 -3
- package/dist/docs/versioned/next/implementationPlans/create-terreno-app.md +177 -0
- package/dist/docs/versioned/next/implementationPlans/datatable-server-side-filtering.md +219 -0
- package/dist/docs/versioned/next/implementationPlans/examples-demo-coverage.md +17 -17
- package/dist/docs/versioned/next/implementationPlans/framework-audit-log.md +247 -0
- package/dist/docs/versioned/next/implementationPlans/gpt-chat-mascot.md +40 -0
- package/dist/docs/versioned/next/implementationPlans/job-queues.md +330 -0
- package/dist/docs/versioned/next/implementationPlans/knip-cleanup.md +136 -0
- package/dist/docs/versioned/next/implementationPlans/migrate-admin-to-syncdb.md +210 -0
- package/dist/docs/versioned/next/implementationPlans/mongodb-migrations-tooling.md +254 -0
- package/dist/docs/versioned/next/implementationPlans/notification-center.md +185 -0
- package/dist/docs/versioned/next/implementationPlans/org-management-ui.md +8 -3
- package/dist/docs/versioned/next/implementationPlans/positioning-django-rails-universal.md +1 -1
- package/dist/docs/versioned/next/reference/README.md +4 -0
- package/dist/docs/versioned/next/reference/admin-backend.md +83 -5
- package/dist/docs/versioned/next/reference/admin-config.md +7 -0
- package/dist/docs/versioned/next/reference/admin-frontend.md +178 -5
- package/dist/docs/versioned/next/reference/admin-spa.md +18 -1
- package/dist/docs/versioned/next/reference/ai.md +2 -0
- package/dist/docs/versioned/next/reference/announcements.md +179 -0
- package/dist/docs/versioned/next/reference/api.md +343 -4
- package/dist/docs/versioned/next/reference/comms.md +33 -0
- package/dist/docs/versioned/next/reference/create-terreno-app.md +44 -0
- package/dist/docs/versioned/next/reference/environment-variables.md +29 -0
- package/dist/docs/versioned/next/reference/jobs.md +319 -0
- package/dist/docs/versioned/next/reference/legacy/rtk.md +5 -1
- package/dist/docs/versioned/next/reference/lifecycle-plugin.md +29 -11
- package/dist/docs/versioned/next/reference/mcp-server.md +2 -43
- package/dist/docs/versioned/next/reference/scan-plugin.md +169 -0
- package/dist/docs/versioned/next/reference/syncdb.md +38 -12
- package/dist/docs/versioned/next/reference/test.md +57 -6
- package/dist/docs/versioned/next/reference/ui-performance.md +2 -1
- package/dist/docs/versioned/next/reference/ui.md +257 -3
- package/dist/docs/versioned/next/tasks/admin-scripts-durable-jobs.md +10 -0
- package/dist/docs/versioned/next/tasks/agent-ui-blocks.md +114 -0
- package/dist/docs/versioned/next/tasks/announcements-surfaces.md +101 -0
- package/dist/docs/versioned/next/tasks/announcements.md +173 -0
- package/dist/docs/versioned/next/tasks/charts-and-dashboards.md +120 -0
- package/dist/docs/versioned/next/tasks/create-terreno-app.md +82 -0
- package/dist/docs/versioned/next/tasks/datatable-server-side-filtering.md +87 -0
- package/dist/docs/versioned/next/tasks/examples-demo-coverage.md +123 -17
- package/dist/docs/versioned/next/tasks/framework-audit-log.md +86 -0
- package/dist/docs/versioned/next/tasks/gpt-chat-mascot.md +13 -0
- package/dist/docs/versioned/next/tasks/job-queues.md +144 -0
- package/dist/docs/versioned/next/tasks/knip-cleanup.md +146 -0
- package/dist/docs/versioned/next/tasks/migrate-admin-to-syncdb.md +209 -0
- package/dist/docs/versioned/next/tasks/mongodb-migrations-tooling.md +107 -0
- package/dist/docs/versioned/next/tasks/notification-center.md +102 -0
- package/dist/docs/versioned/next/tasks/org-management-ui.md +14 -14
- package/dist/docs/versioned/next/tutorials/README.md +1 -1
- package/dist/docs/versioned/next/tutorials/getting-started.md +62 -22
- package/dist/help/excerpt.d.ts +2 -0
- package/dist/help/excerpt.d.ts.map +1 -0
- package/dist/help/excerpt.js +8 -0
- package/dist/help/excerpt.js.map +1 -0
- package/dist/help/updateNotes.d.ts +42 -0
- package/dist/help/updateNotes.d.ts.map +1 -0
- package/dist/help/updateNotes.js +235 -0
- package/dist/help/updateNotes.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/local/tools/databaseQuery.d.ts +1 -0
- package/dist/local/tools/databaseQuery.d.ts.map +1 -1
- package/dist/local/tools/databaseQuery.js +1 -0
- package/dist/local/tools/databaseQuery.js.map +1 -1
- package/dist/packageGuidelines.d.ts +2 -2
- package/dist/packageGuidelines.d.ts.map +1 -1
- package/dist/packageGuidelines.js +2 -8
- package/dist/packageGuidelines.js.map +1 -1
- package/dist/resources.d.ts +3 -0
- package/dist/resources.d.ts.map +1 -1
- package/dist/resources.js +3 -0
- package/dist/resources.js.map +1 -1
- package/dist/search/chunker.d.ts +1 -0
- package/dist/search/chunker.d.ts.map +1 -1
- package/dist/search/chunker.js +1 -0
- package/dist/search/chunker.js.map +1 -1
- package/dist/search/docIndex.d.ts +1 -5
- package/dist/search/docIndex.d.ts.map +1 -1
- package/dist/search/docIndex.js +1 -0
- package/dist/search/docIndex.js.map +1 -1
- package/dist/search/docVersion.d.ts +2 -1
- package/dist/search/docVersion.d.ts.map +1 -1
- package/dist/search/docVersion.js +3 -1
- package/dist/search/docVersion.js.map +1 -1
- package/dist/tools.d.ts +2 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +113 -2
- package/dist/tools.js.map +1 -1
- package/package.json +28 -27
- package/src/docs/guidelines/admin-frontend/guidelines/core.md +5 -1
- package/src/docs/guidelines/api/skills/mongoose-schema-safety/SKILL.md +23 -10
- package/src/docs/resources/syncdb.md +4 -1
- package/src/docs/upgrades/57.4.0.md +140 -0
- package/src/docs/versioned/next/README.md +3 -0
- package/src/docs/versioned/next/explanation/README.md +4 -1
- package/src/docs/versioned/next/explanation/admin-interface.md +20 -13
- package/src/docs/versioned/next/explanation/charts.md +29 -0
- package/src/docs/versioned/next/explanation/deployment-architecture-gcp.md +32 -0
- package/src/docs/versioned/next/explanation/deployment-baseline.md +1 -1
- package/src/docs/versioned/next/explanation/example-coverage.md +43 -0
- package/src/docs/versioned/next/explanation/local-first-data.md +5 -2
- package/src/docs/versioned/next/explanation/loop-engineering.md +9 -6
- package/src/docs/versioned/next/explanation/model-router-actions.md +19 -2
- package/src/docs/versioned/next/explanation/organizations.md +88 -0
- package/src/docs/versioned/next/explanation/planning-plugins.md +114 -0
- package/src/docs/versioned/next/explanation/positioning.md +3 -3
- package/src/docs/versioned/next/explanation/repository-settings.md +6 -5
- package/src/docs/versioned/next/explanation/roadmap-seed-issues.md +44 -34
- package/src/docs/versioned/next/explanation/source-rules.md +1 -1
- package/src/docs/versioned/next/explanation/static-analysis.md +76 -16
- package/src/docs/versioned/next/how-to/README.md +10 -0
- package/src/docs/versioned/next/how-to/add-gpt-chat-mascot.md +92 -0
- package/src/docs/versioned/next/how-to/add-organizations.md +204 -0
- package/src/docs/versioned/next/how-to/admin-add-model.md +9 -1
- package/src/docs/versioned/next/how-to/admin-import-prebuilt.md +7 -1
- package/src/docs/versioned/next/how-to/audit-log.md +85 -0
- package/src/docs/versioned/next/how-to/background-jobs.md +296 -0
- package/src/docs/versioned/next/how-to/build-admin-screens.md +42 -13
- package/src/docs/versioned/next/how-to/charts-and-dashboards.md +37 -0
- package/src/docs/versioned/next/how-to/circleci.md +136 -27
- package/src/docs/versioned/next/how-to/compare-chart-rendered-snapshots.md +36 -0
- package/src/docs/versioned/next/how-to/configure-better-auth.md +4 -0
- package/src/docs/versioned/next/how-to/create-a-terreno-app.md +154 -0
- package/src/docs/versioned/next/how-to/deploy-backend-to-cloud-run.md +2 -0
- package/src/docs/versioned/next/how-to/github-actions-ci.md +4 -3
- package/src/docs/versioned/next/how-to/github-issue-lifecycle.md +12 -8
- package/src/docs/versioned/next/how-to/in-app-notifications.md +147 -0
- package/src/docs/versioned/next/how-to/install-agent-skills.md +24 -12
- package/src/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +19 -3
- package/src/docs/versioned/next/how-to/product-announcements.md +155 -0
- package/src/docs/versioned/next/how-to/run-mongodb-migrations.md +127 -0
- package/src/docs/versioned/next/how-to/run-tests-locally.md +102 -0
- package/src/docs/versioned/next/how-to/seed-a-database.md +7 -2
- package/src/docs/versioned/next/implementationPlans/README.md +8 -5
- package/src/docs/versioned/next/implementationPlans/admin-scripts-durable-jobs.md +44 -0
- package/src/docs/versioned/next/implementationPlans/agent-ui-blocks.md +386 -0
- package/src/docs/versioned/next/implementationPlans/agentic-sdlc-plugin.md +11 -8
- package/src/docs/versioned/next/implementationPlans/announcements-surfaces.md +231 -0
- package/src/docs/versioned/next/implementationPlans/announcements.md +289 -0
- package/src/docs/versioned/next/implementationPlans/b2b-platform-program.md +3 -1
- package/src/docs/versioned/next/implementationPlans/charts-and-dashboards.md +246 -0
- package/src/docs/versioned/next/implementationPlans/comms-admin-dashboard.md +4 -3
- package/src/docs/versioned/next/implementationPlans/create-terreno-app.md +177 -0
- package/src/docs/versioned/next/implementationPlans/datatable-server-side-filtering.md +219 -0
- package/src/docs/versioned/next/implementationPlans/examples-demo-coverage.md +17 -17
- package/src/docs/versioned/next/implementationPlans/framework-audit-log.md +247 -0
- package/src/docs/versioned/next/implementationPlans/gpt-chat-mascot.md +40 -0
- package/src/docs/versioned/next/implementationPlans/job-queues.md +330 -0
- package/src/docs/versioned/next/implementationPlans/knip-cleanup.md +136 -0
- package/src/docs/versioned/next/implementationPlans/migrate-admin-to-syncdb.md +210 -0
- package/src/docs/versioned/next/implementationPlans/mongodb-migrations-tooling.md +254 -0
- package/src/docs/versioned/next/implementationPlans/notification-center.md +185 -0
- package/src/docs/versioned/next/implementationPlans/org-management-ui.md +8 -3
- package/src/docs/versioned/next/implementationPlans/positioning-django-rails-universal.md +1 -1
- package/src/docs/versioned/next/reference/README.md +4 -0
- package/src/docs/versioned/next/reference/admin-backend.md +83 -5
- package/src/docs/versioned/next/reference/admin-config.md +7 -0
- package/src/docs/versioned/next/reference/admin-frontend.md +178 -5
- package/src/docs/versioned/next/reference/admin-spa.md +18 -1
- package/src/docs/versioned/next/reference/ai.md +2 -0
- package/src/docs/versioned/next/reference/announcements.md +179 -0
- package/src/docs/versioned/next/reference/api.md +343 -4
- package/src/docs/versioned/next/reference/comms.md +33 -0
- package/src/docs/versioned/next/reference/create-terreno-app.md +44 -0
- package/src/docs/versioned/next/reference/environment-variables.md +29 -0
- package/src/docs/versioned/next/reference/jobs.md +319 -0
- package/src/docs/versioned/next/reference/legacy/rtk.md +5 -1
- package/src/docs/versioned/next/reference/lifecycle-plugin.md +29 -11
- package/src/docs/versioned/next/reference/mcp-server.md +2 -43
- package/src/docs/versioned/next/reference/scan-plugin.md +169 -0
- package/src/docs/versioned/next/reference/syncdb.md +38 -12
- package/src/docs/versioned/next/reference/test.md +57 -6
- package/src/docs/versioned/next/reference/ui-performance.md +2 -1
- package/src/docs/versioned/next/reference/ui.md +257 -3
- package/src/docs/versioned/next/tasks/admin-scripts-durable-jobs.md +10 -0
- package/src/docs/versioned/next/tasks/agent-ui-blocks.md +114 -0
- package/src/docs/versioned/next/tasks/announcements-surfaces.md +101 -0
- package/src/docs/versioned/next/tasks/announcements.md +173 -0
- package/src/docs/versioned/next/tasks/charts-and-dashboards.md +120 -0
- package/src/docs/versioned/next/tasks/create-terreno-app.md +82 -0
- package/src/docs/versioned/next/tasks/datatable-server-side-filtering.md +87 -0
- package/src/docs/versioned/next/tasks/examples-demo-coverage.md +123 -17
- package/src/docs/versioned/next/tasks/framework-audit-log.md +86 -0
- package/src/docs/versioned/next/tasks/gpt-chat-mascot.md +13 -0
- package/src/docs/versioned/next/tasks/job-queues.md +144 -0
- package/src/docs/versioned/next/tasks/knip-cleanup.md +146 -0
- package/src/docs/versioned/next/tasks/migrate-admin-to-syncdb.md +209 -0
- package/src/docs/versioned/next/tasks/mongodb-migrations-tooling.md +107 -0
- package/src/docs/versioned/next/tasks/notification-center.md +102 -0
- package/src/docs/versioned/next/tasks/org-management-ui.md +14 -14
- package/src/docs/versioned/next/tutorials/README.md +1 -1
- package/src/docs/versioned/next/tutorials/getting-started.md +62 -22
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Tasks: DataTable server-side filtering and search
|
|
2
|
+
|
|
3
|
+
Plan: [`docs/implementationPlans/datatable-server-side-filtering.md`](../implementationPlans/datatable-server-side-filtering.md)
|
|
4
|
+
**Status:** Pick complete — tasks 1.1–4.1 implemented
|
|
5
|
+
**Closes:** https://github.com/FlourishHealth/terreno/issues/1177
|
|
6
|
+
|
|
7
|
+
**Feature profile:** false (full IP)
|
|
8
|
+
|
|
9
|
+
## Instructions for the implementing agent
|
|
10
|
+
|
|
11
|
+
- Load `terreno-ui`, `update-docs`, `verify-ui-changes`. Admin tasks also load `building-admin-interfaces`.
|
|
12
|
+
- TDD: failing test first per task.
|
|
13
|
+
- Run `bun test` in touched packages (`ui`, `admin-frontend`, `admin-backend`).
|
|
14
|
+
- Do not import RTK, axios, or admin packages from `@terreno/ui`.
|
|
15
|
+
- Do not change modelRouter list behavior or admin `q` ObjectId search.
|
|
16
|
+
- Frontend slices: `verify-ui-changes` (demo on 8085; admin list when AdminModelTable changes).
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
### Phase 1 — Tracer (query object, no chrome)
|
|
21
|
+
|
|
22
|
+
- [x] **Task 1.1**: `buildDataTableListQuery` + regex escape
|
|
23
|
+
- Delivers: Pure helper from filter/search state → modelRouter-shaped object per the IP contract table; empty values omitted; user text escaped; choice always `$in` (including one value)
|
|
24
|
+
- Files: `ui/src/dataTableListQuery.ts`, `ui/src/dataTableListQuery.test.ts`, export from `ui/src/index.tsx` only if other UI modules need it (prefer importing the file, no new barrel)
|
|
25
|
+
- Blocked by: none
|
|
26
|
+
- Skills: `terreno-ui`, `update-docs`
|
|
27
|
+
- Docs: stub the query table in `docs/reference/ui.md` so the helper is named when it lands
|
|
28
|
+
- Acceptance: `bun test ui/src/dataTableListQuery.test.ts` — search `$or` regex; `.*` in input is literal; boolean omit/true; date `_gte`/`_lte`; number nested `$gte`; choice `$in`; no `page`/`sort` keys
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
### Phase 2 — DataTable chrome
|
|
33
|
+
|
|
34
|
+
- [x] **Task 2.1**: Types + controlled props
|
|
35
|
+
- Delivers: `DataTableColumn.filter` and search/filter/`onQueryChange` props; omitted props preserve today’s UI
|
|
36
|
+
- Files: `ui/src/Common.ts`, `ui/src/DataTable.tsx`, `ui/src/DataTable.test.tsx`
|
|
37
|
+
- Blocked by: 1.1
|
|
38
|
+
- Skills: `terreno-ui`
|
|
39
|
+
- Docs: none beyond types (generated props in 4.1)
|
|
40
|
+
- Acceptance: tests — no filter prop → no filter controls; `onQueryChange` not required; existing sort cycle and pagination tests still pass
|
|
41
|
+
|
|
42
|
+
- [x] **Task 2.2**: Web per-column `Filter` + search box
|
|
43
|
+
- Delivers: Toolbar search (debounced) and header `Filter` popovers; text / boolean / numberRange / dateRange / choice (`MultiselectField`); `renderFilter` slot; Apply/Clear call `onFilterValuesChange` and `onQueryChange`
|
|
44
|
+
- Files: `ui/src/DataTable.tsx`, `ui/src/DataTable.test.tsx`, `demo/stories/DataTable.stories.tsx`
|
|
45
|
+
- Blocked by: 2.1
|
|
46
|
+
- Skills: `terreno-ui`, `verify-ui-changes`, `update-docs`
|
|
47
|
+
- Docs: demo story is the tutorial surface; reference example in `docs/reference/ui.md`
|
|
48
|
+
- Acceptance: tests fire `onQueryChange` for each kind; demo story renders search + four kinds; `verify-ui-changes` on demo DataTable story
|
|
49
|
+
|
|
50
|
+
- [x] **Task 2.3**: Native Filters sheet
|
|
51
|
+
- Delivers: On non-web, one Filters control + `Modal` sheet containing the same fields and search; same query object as web
|
|
52
|
+
- Files: `ui/src/DataTable.tsx`, `ui/src/DataTable.test.tsx`
|
|
53
|
+
- Blocked by: 2.2
|
|
54
|
+
- Skills: `terreno-ui`
|
|
55
|
+
- Docs: one row in the platform table in `docs/reference/ui.md`
|
|
56
|
+
- Acceptance: test with `Platform.OS` mock (or testIDs) — sheet apply emits the same params as web Apply; no `Filter` portal on native
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
### Phase 3 — Admin
|
|
61
|
+
|
|
62
|
+
- [x] **Task 3.1**: `parseAdminListFilters` choice `$in` and text `$regex`
|
|
63
|
+
- Delivers: Declared `choice` accepts `{ $in: string[] }` (subset of `choices`); `text` accepts `{ $regex, $options: "i" }`; scalar choice/text still work; top-level `$or` still errors; values outside `choices` error
|
|
64
|
+
- Files: `admin-backend/src/filterParser.ts`, `admin-backend/src/filterParser.test.ts`
|
|
65
|
+
- Blocked by: none (can parallel 2.x)
|
|
66
|
+
- Skills: `building-admin-interfaces`
|
|
67
|
+
- Docs: note in `docs/how-to/admin-add-model.md` that choice filters may be multi-value `$in`
|
|
68
|
+
- Acceptance: `bun test admin-backend/src/filterParser.test.ts` covers happy `$in`, invalid choice, text regex, rejected `$or`
|
|
69
|
+
|
|
70
|
+
- [x] **Task 3.2**: AdminModelTable adopts DataTable filters
|
|
71
|
+
- Delivers: Map `filters` → column `filter` / `renderFilter` for `ref`; search → `q`; drop `AdminFilterDrawer` from the table; `buildAdminListQueryParams` forwards `$in` and omits `$or`
|
|
72
|
+
- Files: `admin-frontend/src/AdminModelTable.tsx`, `admin-frontend/src/adminModelListQueryParams.ts`, `admin-frontend/src/adminModelListQueryParams.test.ts`, `admin-frontend/src/AdminModelTable.test.tsx`, `admin-frontend/src/AdminFilterDrawer.tsx` / `index.tsx` if unused
|
|
73
|
+
- Blocked by: 2.2, 3.1
|
|
74
|
+
- Skills: `building-admin-interfaces`, `terreno-ui`, `verify-ui-changes`, `update-docs`
|
|
75
|
+
- Docs: `docs/reference/admin-frontend.md`, `docs/explanation/admin-interface.md`, `docs/how-to/admin-add-model.md` (filters on columns, not a drawer)
|
|
76
|
+
- Acceptance: tests — search param is `q` not `$or`; choice multi → `$in`; drawer not in table output; admin list verification in admin-spa or example admin
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### Phase 4 — Docs and seed
|
|
81
|
+
|
|
82
|
+
- [x] **Task 4.1**: Diátaxis + generated props + changelog
|
|
83
|
+
- Delivers: Query contract and platform table in `docs/reference/ui.md`; admin how-to/reference/explanation; regenerate UI component reference; CHANGELOG Added; seed IP/task links already in Grow stay accurate
|
|
84
|
+
- Files: `docs/reference/ui.md`, `docs/how-to/admin-add-model.md`, `docs/reference/admin-frontend.md`, `docs/explanation/admin-interface.md`, `docs/explanation/roadmap-seed-issues.md`, `CHANGELOG.md`; `ui` types + `bun run website:generate` as required by `update-docs`
|
|
85
|
+
- Blocked by: 2.3, 3.2
|
|
86
|
+
- Skills: `update-docs`
|
|
87
|
+
- Acceptance: a stranger can wire `onQueryChange` to a modelRouter list from docs; admin text contains + choice `$in` are explicit; `bun run website:build` if the site is in the slice
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
See: [`docs/implementationPlans/examples-demo-coverage.md`](../implementationPlans/examples-demo-coverage.md)
|
|
4
4
|
|
|
5
|
-
**RTK deprecation flag:** **Partial.** Tasks
|
|
5
|
+
**RTK deprecation flag:** **Partial.** Tasks 5.1–5.3 originally waited on PR #869. `@terreno/syncdb` is in the example apps on this branch; those tasks are unblocked.
|
|
6
6
|
|
|
7
7
|
## Instructions for the implementing agent
|
|
8
8
|
|
|
@@ -14,25 +14,107 @@ See: [`docs/implementationPlans/examples-demo-coverage.md`](../implementationPla
|
|
|
14
14
|
|
|
15
15
|
## Phase 1: Demo coverage — audit and P0
|
|
16
16
|
|
|
17
|
-
- [
|
|
17
|
+
- [x] **Task 1.1**: Audit demo story coverage
|
|
18
18
|
- Description: Extract the list of components exported from `ui/src/index.tsx`. Extract the list of components registered in `demo/demoConfig.tsx`. Produce the difference. Classify each missing component as P0 (demonstrates a pillar: AI, auth, responsive layout), P1 (common in real apps), P2 (uncommon), or "cannot be demoed in isolation" with a reason. Report the full table in the PR body.
|
|
19
19
|
- Files: none (findings in the PR body)
|
|
20
20
|
- Depends on: none
|
|
21
21
|
- Acceptance: the table is derived from the two actual source files; every missing component has a classification; every "cannot be demoed" entry has a stated reason.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
### Task 1.1 audit (2026-09-10, `ui/src/index.tsx` + `demo/demoConfig.tsx`)
|
|
24
|
+
|
|
25
|
+
Registered stories (65 configs, including OpenAPI Context): Accordion, AddressField, AiSuggestionBox, Avatar, Badge, Banner, BooleanField, Box, Button, Card, CheckBox, ConsentFormScreen, CustomSelectField, DataTable, DateTimeField, EditableCard, EmailField, EmojiSelector, Field, Filter, Heading, HeightField, Icon, IconButton, Link, LoginScreen, MarkdownEditorField, MarkdownView, Modal, MultiselectField, NumberField, OpenAPIContext, Page, Pagination, PasswordField, PhoneNumberField, Popover, RadioField, SectionDivider, SegmentedControl, SelectBadge, SelectField, SidebarNavigation (+ Panel), SideDrawer, SignatureCaptureField, SignatureField, Slider, Spinner, Table (+ Badge/Boolean/Date/IconButton/Number/Text/Title), TapToEdit, Text, TextArea, TextField, Theme, ThumbsUpDownFeedback, Toast, Tooltip, TypedSignatureField, UserInactivity.
|
|
26
|
+
|
|
27
|
+
`ModalSheet.tsx` does not export a `ModalSheet` identifier; the public component is `SimpleContent`. Matching uses `component:` in `demo/story-config/*.config.tsx` plus `OpenAPIContext` in `demoConfig.tsx`.
|
|
28
|
+
|
|
29
|
+
| Export | Class | Reason |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| `GPTChat` | P0 | AI pillar |
|
|
32
|
+
| `SocialLoginButton` | P0 | Auth pillar |
|
|
33
|
+
| `SplitPage` | P0 | Responsive layout pillar |
|
|
34
|
+
| `ActionSheet` | P1 | Common overlay |
|
|
35
|
+
| `SimpleContent` | P1 | ModalSheet public export; bottom sheet |
|
|
36
|
+
| `FilePickerButton` | P1 | Common file input |
|
|
37
|
+
| `Image` | P1 | Common media |
|
|
38
|
+
| `SignUpScreen` | P1 | Auth screen (LoginScreen already demos) |
|
|
39
|
+
| `OAuthButtons` | P1 | Grouped social login |
|
|
40
|
+
| `ErrorPage` | P1 | Common error UI |
|
|
41
|
+
| `ErrorBoundary` | P1 | Common error UI |
|
|
42
|
+
| `DismissButton` | P1 | Common chrome |
|
|
43
|
+
| `ImageBackground` | P1 | Common layout |
|
|
44
|
+
| `MarkdownEditor` | P1 | Editor (field already demos) |
|
|
45
|
+
| `InfoTooltipButton` | P1 | Common help affordance |
|
|
46
|
+
| `InfoModalIcon` | P1 | Common help affordance |
|
|
47
|
+
| `OfflineBanner` | P1 | Sync/offline status |
|
|
48
|
+
| `SyncStatusBanner` | P1 | Sync status |
|
|
49
|
+
| `AttachmentPreview` | P1 | Chat/file UX |
|
|
50
|
+
| `ConflictSheet` | P1 | Sync conflict UX |
|
|
51
|
+
| `AIRequestExplorer` | P1 | AI admin surface |
|
|
52
|
+
| `Body` | P1 | Layout primitive |
|
|
53
|
+
| `PasswordRequirements` | P1 | Auth helper |
|
|
54
|
+
| `UnifiedAddressAutoCompleteField` | P1 | Address (AddressField demos a wrapper) |
|
|
55
|
+
| `WebAddressAutocomplete` | P1 | Web address |
|
|
56
|
+
| `MobileAddressAutocomplete` | P1 | Native address |
|
|
57
|
+
| `Radio` | P2 | Primitive under RadioField |
|
|
58
|
+
| `DraggableList` | P2 | Uncommon |
|
|
59
|
+
| `UpgradeRequiredScreen` | P2 | Uncommon |
|
|
60
|
+
| `GPTMemoryModal` | P2 | GPTChat sub-surface |
|
|
61
|
+
| `ConsentNavigator` | P2 | ConsentFormScreen already demos |
|
|
62
|
+
| `DateTimeActionSheet` | P2 | DateTimeField already demos |
|
|
63
|
+
| `HeightActionSheet` | P2 | HeightField already demos |
|
|
64
|
+
| `DecimalRangeActionSheet` | P2 | Uncommon picker |
|
|
65
|
+
| `NumberPickerActionSheet` | P2 | Uncommon picker |
|
|
66
|
+
| `FilterAccordion` | P2 | Filter already demos |
|
|
67
|
+
| `FilterBoolean` | P2 | Filter already demos |
|
|
68
|
+
| `FilterChangesBadge` | P2 | Filter already demos |
|
|
69
|
+
| `FilterSelectMenu` | P2 | Filter already demos |
|
|
70
|
+
| `TableHeader` | P2 | Table already demos |
|
|
71
|
+
| `TableHeaderCell` | P2 | Table already demos |
|
|
72
|
+
| `TableRow` | P2 | Table already demos |
|
|
73
|
+
| `Signature` | P2 | SignatureField already demos |
|
|
74
|
+
| `Swiper` | P2 | Onboarding helper |
|
|
75
|
+
| `BarsFilterIcon` | P2 | Icon primitive |
|
|
76
|
+
| `ScrollView` | P2 | RN wrapper |
|
|
77
|
+
| `FlatList` | P2 | RN wrapper |
|
|
78
|
+
| `TerrenoProvider` | cannot | Demo root already wraps the app |
|
|
79
|
+
| `ThemeProvider` | cannot | Theme story already exercises theme; provider is shell |
|
|
80
|
+
| `OpenAPIProvider` | cannot | OpenAPI Context story already wraps usage |
|
|
81
|
+
| `IconRegistryProvider` | cannot | Registry is app shell, not a visual component |
|
|
82
|
+
| `TableContextProvider` | cannot | Table stories already wrap table context |
|
|
83
|
+
| `Host` | cannot | Portal host is app shell |
|
|
84
|
+
| `Portal` | cannot | Portal is a host primitive, not a visual story |
|
|
85
|
+
| `PortalContext` | cannot | React context object |
|
|
86
|
+
| `ThemeContext` | cannot | React context object |
|
|
87
|
+
| `Unifier` | cannot | Platform utility singleton, not a component |
|
|
88
|
+
| `SPACING_MAP` | cannot | Constant, not a component |
|
|
89
|
+
| `USSTATESLIST` | cannot | Constant, not a component |
|
|
90
|
+
| `COUNTY_AND_COUNTY_EQUIVALENT_ENTITIES` | cannot | Constant, not a component |
|
|
91
|
+
| `GOOGLE_PLACES_API_RESTRICTIONS` | cannot | Constant, not a component |
|
|
92
|
+
| `SIDEBAR_BADGE_STATUS_MAP` | cannot | Constant, not a component |
|
|
93
|
+
| `SUPPORTED_ORIENTATIONS` | cannot | Constant, not a component |
|
|
94
|
+
| `NATIVE_BREAKPOINT_MIN_WIDTH` | cannot | Constant, not a component |
|
|
95
|
+
| `WEB_BREAKPOINT_MIN_WIDTH` | cannot | Constant, not a component |
|
|
96
|
+
| `DEFAULT_SIGNATURE_FONTS` | cannot | Constant, not a component |
|
|
97
|
+
| `CONFLICT_METADATA_FIELDS` | cannot | Constant, not a component |
|
|
98
|
+
| `NO_CONFLICT_DIFF_FIELDS` | cannot | Constant, not a component |
|
|
99
|
+
| `StyleProp` | cannot | Type re-export |
|
|
100
|
+
| `ViewStyle` | cannot | Type re-export |
|
|
101
|
+
| `OAuthProvider` | cannot | Type, not a component |
|
|
102
|
+
| `OnboardingPage` | cannot | Type, not a component |
|
|
103
|
+
| `PasswordRequirement` | cannot | Type, not a component |
|
|
104
|
+
|
|
105
|
+
- [x] **Task 1.2**: Add P0 stories
|
|
24
106
|
- Description: Write stories for every P0 component from Task 1.1 (expected to include `GPTChat`, `SocialLoginButton`, and `SplitPage` — confirm against the audit). Each story shows multiple states where the component supports them: default, loading, error, disabled, and any variant enumerations. `GPTChat` needs a story that works without a live backend — use a static message list rather than wiring a real AI call. `SocialLoginButton` needs all three providers and both variants. `SplitPage` needs a story demonstrating the responsive breakpoint behavior. Register each in `demoConfig.tsx`.
|
|
25
107
|
- Files: `demo/stories/*.stories.tsx` (new), `demo/demoConfig.tsx`
|
|
26
108
|
- Depends on: Task 1.1
|
|
27
109
|
- Acceptance: every P0 component has a story reachable in the running demo (`bun run demo:start`, port 8085); each shows at least two states; `GPTChat`'s story renders with no backend running; `bun run demo:compile` passes.
|
|
28
110
|
|
|
29
|
-
- [
|
|
111
|
+
- [x] **Task 1.3**: Add the demo coverage check
|
|
30
112
|
- Description: Create `scripts/check-demo-coverage.ts` (Bun, TypeScript, `const` arrow functions with explicit return types). It parses the export list from `ui/src/index.tsx` and the registered components from `demo/demoConfig.tsx`, then fails with a list of unstoried components. Support an allowlist file or an in-script allowlist where each entry requires a comment explaining why the component cannot be demoed. Add a `check:demo-coverage` script to the root `package.json` and wire it into `.github/workflows/ui-demo-ci.yml`.
|
|
31
113
|
- Files: `scripts/check-demo-coverage.ts` (new), `package.json`, `.github/workflows/ui-demo-ci.yml`
|
|
32
114
|
- Depends on: Task 1.2
|
|
33
115
|
- Acceptance: the check passes with the current allowlist; adding a new export to `ui/src/index.tsx` without a story makes it fail and name the component; the CI job runs it.
|
|
34
116
|
|
|
35
|
-
- [
|
|
117
|
+
- [x] **Task 1.4**: Make the demo's `test:ci` real
|
|
36
118
|
- Description: `demo/package.json`'s `test:ci` is currently `echo 'No tests'`. Replace it with something meaningful: at minimum a smoke test that every registered story renders without throwing, using the `renderWithTheme` helper from `@terreno/ui`'s test utilities. This catches the most common demo breakage — a story that crashes after a component's props change.
|
|
37
119
|
- Files: `demo/package.json`, `demo/**` test files (new)
|
|
38
120
|
- Depends on: Task 1.2
|
|
@@ -40,13 +122,13 @@ See: [`docs/implementationPlans/examples-demo-coverage.md`](../implementationPla
|
|
|
40
122
|
|
|
41
123
|
## Phase 2: Remaining demo stories
|
|
42
124
|
|
|
43
|
-
- [
|
|
125
|
+
- [x] **Task 2.1**: Add P1 stories
|
|
44
126
|
- Description: Write stories for every P1 component from the Task 1.1 audit (expected to include `ActionSheet`, `ModalSheet`, `FilePickerButton`, and `Image`). Interactive components need a story that can actually be triggered from the demo UI, not just a static render. Register each in `demoConfig.tsx`.
|
|
45
127
|
- Files: `demo/stories/*.stories.tsx` (new), `demo/demoConfig.tsx`
|
|
46
128
|
- Depends on: Task 1.3
|
|
47
129
|
- Acceptance: every P1 component has a story; interactive components can be opened and dismissed in the running demo; `bun run demo:compile` passes.
|
|
48
130
|
|
|
49
|
-
- [
|
|
131
|
+
- [x] **Task 2.2**: Add P2 stories and close the allowlist
|
|
50
132
|
- Description: Write stories for the remaining P2 components. For any component that genuinely cannot be demoed in isolation, add it to the allowlist with a specific reason (not "hard to demo"). The goal is an empty or near-empty gap list with a justified allowlist.
|
|
51
133
|
- Files: `demo/stories/*.stories.tsx` (new), `demo/demoConfig.tsx`, the allowlist
|
|
52
134
|
- Depends on: Task 2.1
|
|
@@ -54,25 +136,47 @@ See: [`docs/implementationPlans/examples-demo-coverage.md`](../implementationPla
|
|
|
54
136
|
|
|
55
137
|
## Phase 3: Coverage enforcement
|
|
56
138
|
|
|
57
|
-
- [
|
|
139
|
+
- [x] **Task 3.1**: Measure current coverage per package
|
|
58
140
|
- Description: Run every published package's `test:coverage` on a clean `master` and record the actual coverage. Report which packages are below the 95% threshold in the PR body. This is a planning step — do not lower the threshold or add exemptions.
|
|
59
141
|
- Files: none (findings in the PR body)
|
|
60
142
|
- Depends on: none
|
|
61
143
|
- Acceptance: every published package has a measured coverage value; packages below 95% are listed with their gap.
|
|
62
144
|
|
|
63
|
-
|
|
145
|
+
### Task 3.1 coverage (2026-09-10)
|
|
146
|
+
|
|
147
|
+
Measured with `bun run ../scripts/check-coverage.ts --threshold=0` from each package directory after compile. Figures are the script's `Coverage summary` when present (isolated-test merge); otherwise the Bun `All files` row. Threshold is **95% functions and 95% lines** — not lowered.
|
|
148
|
+
|
|
149
|
+
| Package | Functions % | Lines % | Below 95%? | Gap |
|
|
150
|
+
| --- | --- | --- | --- | --- |
|
|
151
|
+
| `@terreno/api` | 98.84 | 99.06 | no | — |
|
|
152
|
+
| `@terreno/ui` | 99.78 | 99.65 | no | — |
|
|
153
|
+
| `@terreno/rtk` | 99.67 | 98.98 | no | — |
|
|
154
|
+
| `@terreno/syncdb` | 97.81 | 96.84 | no | — |
|
|
155
|
+
| `@terreno/ai` | 99.21 | 99.63 | no | — |
|
|
156
|
+
| `@terreno/comms` | 96.76 | 98.22 | no | — |
|
|
157
|
+
| `@terreno/mcp` | 99.68 | 97.44 | no | — |
|
|
158
|
+
| `@terreno/feature-flags` | 100.00 | 99.55 | no | — |
|
|
159
|
+
| `@terreno/api-health` | 100.00 | 100.00 | no | — |
|
|
160
|
+
| `@terreno/admin-backend` | 97.25 | 96.65 | no | — |
|
|
161
|
+
| `@terreno/admin-frontend` | 95.11 | 95.55 | no | — |
|
|
162
|
+
| `@terreno/admin-spa` | 100.00 | 100.00 | no | — |
|
|
163
|
+
| `@terreno/test` | 96.34 | 95.32 | no | — |
|
|
164
|
+
|
|
165
|
+
Packages below 95%: none (all published packages meet the 95% function and line thresholds as of the latest local `test:coverage` runs).
|
|
166
|
+
|
|
167
|
+
- [x] **Task 3.2**: Wire the threshold into every package CI
|
|
64
168
|
- Description: Add `scripts/check-coverage.ts` (default 95% threshold) to every published package's CI — either the existing dedicated workflow or the new matrix job from Task 3.3. Packages below threshold when this lands will fail CI until catch-up work merges; track that in the implementation PR.
|
|
65
169
|
- Files: `.github/workflows/ui-ci.yml`, `ai-ci.yml`, `admin-spa-ci.yml`, `.github/workflows/packages-ci.yml`, package `package.json` files as needed
|
|
66
170
|
- Depends on: Task 3.1
|
|
67
171
|
- Acceptance: every published package's CI runs the coverage check at 95%; no package has a permanent exemption.
|
|
68
172
|
|
|
69
|
-
- [
|
|
173
|
+
- [x] **Task 3.3**: Add the matrix CI job for uncovered packages
|
|
70
174
|
- Description: Per IP question E3, create `.github/workflows/packages-ci.yml` with a matrix over the published packages that lack a dedicated workflow (`admin-backend`, `feature-flags`, `api-health`, `test` — verify the current set against `.github/workflows/`). Each matrix entry runs compile, lint, tests, and the coverage check. Use path filters so the job only runs for the affected package where practical. Follow the repo's required-input validation convention.
|
|
71
175
|
- Files: `.github/workflows/packages-ci.yml` (new)
|
|
72
176
|
- Depends on: Task 3.2
|
|
73
177
|
- Acceptance: the workflow parses as valid YAML; the matrix covers exactly the published packages without their own workflow; each entry runs compile, lint, test, and coverage at 95%.
|
|
74
178
|
|
|
75
|
-
- [
|
|
179
|
+
- [x] **Task 3.4**: Catch up packages below threshold
|
|
76
180
|
- Description: For each package measured below 95% in Task 3.1, add tests until `scripts/check-coverage.ts` passes. This may be a separate PR if the gap is large; do not merge the CI wiring until every package passes or the IP owner explicitly defers a package with a linked issue.
|
|
77
181
|
- Files: package test files as needed
|
|
78
182
|
- Depends on: Task 3.2
|
|
@@ -80,13 +184,13 @@ See: [`docs/implementationPlans/examples-demo-coverage.md`](../implementationPla
|
|
|
80
184
|
|
|
81
185
|
## Phase 4: Codecov
|
|
82
186
|
|
|
83
|
-
- [
|
|
187
|
+
- [x] **Task 4.1**: Configure Codecov
|
|
84
188
|
- Description: Add `codecov.yml` configuring per-package flags so each package's coverage is reported separately, a target of "auto" with a small allowed threshold so trivial deltas do not fail PRs, and comment settings that post the delta on pull requests. Add the upload step to every package CI workflow. Note in the file where the `CODECOV_TOKEN` secret must be configured (a maintainer action for a public repo, though public repos often need no token — verify current Codecov requirements before documenting).
|
|
85
189
|
- Files: `codecov.yml` (new), every package CI workflow
|
|
86
190
|
- Depends on: Task 3.4
|
|
87
191
|
- Acceptance: `codecov.yml` is valid; every package workflow uploads with a distinct flag; the token requirement is documented accurately for a public repo.
|
|
88
192
|
|
|
89
|
-
- [
|
|
193
|
+
- [x] **Task 4.2**: Add the coverage badge
|
|
90
194
|
- Description: Add a Codecov badge to `README.md` next to the existing npm and license badges. Add a "Testing and coverage" section to `CONTRIBUTING.md` explaining: the 95% coverage expectation for new code, that coverage must not drop in a PR, and how to run coverage locally per package.
|
|
91
195
|
- Files: `README.md`, `CONTRIBUTING.md`
|
|
92
196
|
- Depends on: Task 4.1
|
|
@@ -94,19 +198,21 @@ See: [`docs/implementationPlans/examples-demo-coverage.md`](../implementationPla
|
|
|
94
198
|
|
|
95
199
|
## Phase 5: Example feature matrix
|
|
96
200
|
|
|
97
|
-
- [
|
|
201
|
+
- [x] **Task 5.1**: `[RTK]` Audit example app feature coverage
|
|
98
202
|
- Description: Build the capability matrix from the IP by reading `example-backend/src/` and `example-frontend/app/`. Resolve every `?`: does an example actually exercise AI structured output, Better Auth, and (after #869) syncdb local-first behavior? For each capability, cite the file that exercises it or record it as a gap. Include capabilities that are not shipped (RBAC, background jobs) marked as such with links to their IPs.
|
|
99
203
|
- Files: `docs/explanation/example-coverage.md` (new)
|
|
100
|
-
- Depends on: PR #869
|
|
204
|
+
- Depends on: none (`@terreno/syncdb` is in-tree; PR #869 closed)
|
|
101
205
|
- Acceptance: no `?` remains; every "yes" cites a file path; every gap is explicit; unshipped capabilities link their IPs.
|
|
102
206
|
|
|
103
|
-
- [
|
|
207
|
+
- [x] **Task 5.2**: `[RTK]` Fill the highest-value example gaps
|
|
104
208
|
- Description: For each gap found in Task 5.1, either add the example or record it as a known gap with an issue. Prioritize capabilities the launch documentation depends on — if a tutorial or reference page describes something with no working example, that is the highest priority because the docs claim will be tested by readers. Do not add examples for unshipped features.
|
|
105
209
|
- Files: `example-backend/src/**`, `example-frontend/app/**`, `docs/explanation/example-coverage.md`
|
|
106
210
|
- Depends on: Task 5.1
|
|
107
211
|
- Acceptance: every gap that a launch document depends on is filled with a working example; remaining gaps are recorded with issue links; both example apps still pass their CI.
|
|
108
212
|
|
|
109
|
-
- [
|
|
213
|
+
Recorded gaps (2026-09-11): AI structured output → [#1010](https://github.com/FlourishHealth/terreno/issues/1010); generic background jobs → [#1188](https://github.com/FlourishHealth/terreno/issues/1188). No launch tutorial currently depends on either.
|
|
214
|
+
|
|
215
|
+
- [x] **Task 5.3**: Link the matrix into the contribution process
|
|
110
216
|
- Description: Add a note to `CONTRIBUTING.md` and the PR template: when adding a framework capability, add or update the example that exercises it and update `docs/explanation/example-coverage.md`. This is what keeps the matrix true. Link the matrix from `docs/explanation/README.md`.
|
|
111
217
|
- Files: `CONTRIBUTING.md`, `.github/PULL_REQUEST_TEMPLATE.md`, `docs/explanation/README.md`
|
|
112
218
|
- Depends on: Task 5.1
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Tasks: Framework-level audit log
|
|
2
|
+
|
|
3
|
+
IP: [framework-audit-log.md](../implementationPlans/framework-audit-log.md)
|
|
4
|
+
**Closes:** https://github.com/FlourishHealth/terreno/issues/1186
|
|
5
|
+
|
|
6
|
+
**Feature profile:** false (full IP)
|
|
7
|
+
|
|
8
|
+
## Phase 1 — Tracer (model, plugin, CRUD diffs)
|
|
9
|
+
|
|
10
|
+
- [x] **Task 1.1**: `AuditEvent` model + `AuditApp` list/read router
|
|
11
|
+
- Delivers: `createAuditEventModel(connection)` (no default-connection singleton); `new AuditApp()` registers GET list/read at `/audit-events` with `Permissions.IsAdmin`; create/update/delete permission arrays empty; default no TTL; field `description`s; append-only (no `isDeletedPlugin`)
|
|
12
|
+
- Files: `api/src/audit/auditEventModel.ts`, `api/src/audit/auditApp.ts`, `api/src/audit/auditApp.test.ts`, `api/src/index.ts`
|
|
13
|
+
- Blocked by: none
|
|
14
|
+
- Skills: `terreno-backend-api`, `mongoose-schema-safety`, `backend-test-env`
|
|
15
|
+
- Docs: stub `AuditApp` in `docs/reference/api.md` so the tracer is documented when it lands
|
|
16
|
+
- Acceptance: bun + supertest — import `@terreno/api` does not register `AuditEvent` on `mongoose.connection`; with plugin, admin GET list 200 empty; POST/PATCH/DELETE not available; non-admin list 405 (modelRouter `permissionMiddleware` for failed list perms)
|
|
17
|
+
|
|
18
|
+
- [x] **Task 1.2**: `modelRouter` `audit` + recorder + redacted diffs
|
|
19
|
+
- Delivers: `audit: true | {redact?: string[]}` after successful create/update/delete writes one `AuditEvent` (`source: "modelRouter"`, `verb` created/updated/deleted); changed-fields only; default redact `password`/`hash`/`salt`/`token`/`secret`/`refreshToken`; extra `redact` merged; best-effort (`logger.error`, CRUD still 2xx); never audit `AuditEvent`; without `AuditApp`, skip write and log error once per process
|
|
20
|
+
- Files: `api/src/audit/record.ts`, `api/src/audit/diff.ts`, `api/src/api.ts`, `api/src/audit/auditRouter.test.ts` (or extend 1.1 tests)
|
|
21
|
+
- Blocked by: 1.1
|
|
22
|
+
- Skills: `terreno-backend-api`
|
|
23
|
+
- Docs: one-line `audit` option on the api.md stub
|
|
24
|
+
- Acceptance: bun tests — PATCH `title` yields one event with `before.title`/`after.title`; secret fields absent; `redact: ["ssn"]` strips `ssn`; create has `after` only; delete has `before` only; thrown recorder still returns 200/201; plugin omitted: CRUD 201 and zero events
|
|
25
|
+
|
|
26
|
+
## Phase 2 — Array ops + org field
|
|
27
|
+
|
|
28
|
+
- [x] **Task 2.1**: Array mutations
|
|
29
|
+
- Delivers: modelRouter array push/update/remove with `audit: true` write `verb: "updated"` and `operation` `arrayPush` / `arrayUpdate` / `arrayRemove`; `recordId` set
|
|
30
|
+
- Files: `api/src/api.ts`, `api/src/audit/*.test.ts`
|
|
31
|
+
- Blocked by: 1.2
|
|
32
|
+
- Skills: `terreno-backend-api`
|
|
33
|
+
- Docs: operation table in `docs/how-to/audit-log.md` (create page if 5.1 not started)
|
|
34
|
+
- Acceptance: bun + supertest for each array verb; one event each; product array tests still pass
|
|
35
|
+
|
|
36
|
+
- [x] **Task 2.2**: Optional `organizationId`
|
|
37
|
+
- Delivers: copy `req.organization` id when set, else string `doc.organizationId`; omit when neither exists; list `queryFields` includes `organizationId`
|
|
38
|
+
- Files: `api/src/audit/record.ts`, tests
|
|
39
|
+
- Blocked by: 1.2
|
|
40
|
+
- Skills: `terreno-backend-api`
|
|
41
|
+
- Docs: org field note on the how-to (org-admin filter is future)
|
|
42
|
+
- Acceptance: two tests — document field vs `req.organization`; neither → field absent
|
|
43
|
+
|
|
44
|
+
## Phase 3 — Admin, example, RBAC
|
|
45
|
+
|
|
46
|
+
- [x] **Task 3.1**: AdminApp auto-write
|
|
47
|
+
- Delivers: when recorder is present, successful admin POST/PATCH/DELETE persist `AuditEvent` with `source: "admin"` even if `onAdminAudit` is omitted; still invoke `onAdminAudit` when set; skip `AuditEvent` model; mutation succeeds if the framework write throws
|
|
48
|
+
- Files: `admin-backend/src/adminApp.ts`, `admin-backend/src/adminApp.models.test.ts`
|
|
49
|
+
- Blocked by: 1.2
|
|
50
|
+
- Skills: `building-admin-interfaces`, `terreno-backend-api`
|
|
51
|
+
- Docs: `docs/reference/admin-backend.md` — `onAdminAudit` is extra
|
|
52
|
+
- Acceptance: existing `onAdminAudit` tests still pass; new tests — plugin present, no `onAdminAudit`, POST creates an `AuditEvent`; both configured → both run; throw in recorder → still 201
|
|
53
|
+
|
|
54
|
+
- [x] **Task 3.2**: example-backend + RBAC helper + Platform shell
|
|
55
|
+
- Delivers: `persistRbacAuditToAuditEvent` exported from `@terreno/api`; example registers `AuditApp`, `audit: true` on Todo, removes `AdminAuditLog` model/`onAdminAudit` persistence, points admin config + scripts + `access.ts` sink at `AuditEvent`; `isAuditLogModel` matches `AuditEvent` (keep old name/path); Recent Activity uses it
|
|
56
|
+
- Files: `api/src/audit/rbacSink.ts`, `example-backend/src/server.ts`, `example-backend/src/access.ts`, `example-backend/src/models/adminAuditLog.ts` (delete), `example-backend/src/modelInterfaces.ts`, `example-backend/src/adminScripts.ts`, `admin-frontend/src/AdminShell.tsx`, `admin-frontend/src/AdminHome.tsx`, matching tests
|
|
57
|
+
- Blocked by: 3.1
|
|
58
|
+
- Skills: `building-admin-interfaces`, `verify-ui-changes`, `generate-sdk` if OpenAPI admin SDK must list `/audit-events`
|
|
59
|
+
- Docs: example README admin paragraph
|
|
60
|
+
- Acceptance: bun tests for shell matcher + RBAC sink mapping; example compile; UI: admin login → mutate a Todo or admin model → Platform Audit Log / Recent Activity shows the row (`verify-ui-changes`, artifacts under `/opt/cursor/artifacts/`)
|
|
61
|
+
|
|
62
|
+
## Phase 4 — Retention
|
|
63
|
+
|
|
64
|
+
- [x] **Task 4.1**: Optional TTL
|
|
65
|
+
- Delivers: `AuditApp({retentionDays: n})` for `n > 0` creates TTL index on `created` (`expireAfterSeconds = n * 86400`); omit or `0` → no TTL index
|
|
66
|
+
- Files: `api/src/audit/auditEventModel.ts`, `api/src/audit/auditApp.ts`, tests
|
|
67
|
+
- Blocked by: 1.1
|
|
68
|
+
- Skills: `mongoose-schema-safety`
|
|
69
|
+
- Docs: TTL + index-drop note on the how-to
|
|
70
|
+
- Acceptance: index spec assertions; default plugin has no TTL index
|
|
71
|
+
|
|
72
|
+
## Phase 5 — Docs and roadmap
|
|
73
|
+
|
|
74
|
+
- [x] **Task 5.1**: Diátaxis + changelog + rules
|
|
75
|
+
- Delivers: operator how-to, api reference (full, not stub), admin-interface Platform row, admin-backend `onAdminAudit` note, rulesync api rule, `CHANGELOG.md` Added, `bun run rules` / `skills:sync` if rulesync changed
|
|
76
|
+
- Files: `docs/how-to/audit-log.md`, `docs/reference/api.md`, `docs/explanation/admin-interface.md`, `docs/reference/admin-backend.md`, `.rulesync/rules/api/00-api.mdc`, `CHANGELOG.md`
|
|
77
|
+
- Blocked by: 1.2 (content can land with 2.x–4.x; must match shipped options)
|
|
78
|
+
- Skills: `update-docs`
|
|
79
|
+
- Acceptance: a stranger can enable `AuditApp` + `audit: true` from the how-to; append-only and forever-default are explicit; `bun run website:build` if the docs site is in the slice
|
|
80
|
+
|
|
81
|
+
- [x] **Task 5.2**: Roadmap seed + B2B table
|
|
82
|
+
- Delivers: `docs/explanation/roadmap-seed-issues.md` `framework-audit-log` points at IP/task GitHub URLs, `IP=framework-audit-log`, depends line is soft-org; `b2b-platform-program.md` lists this IP as Draft/Approved matching the IP header
|
|
83
|
+
- Files: `docs/explanation/roadmap-seed-issues.md`, `docs/implementationPlans/b2b-platform-program.md`
|
|
84
|
+
- Blocked by: 5.1
|
|
85
|
+
- Skills: `update-docs`
|
|
86
|
+
- Acceptance: seed `Implementation plan` / `Tasks` links are not `*(not yet written)*`
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# GPTChat optional mascot
|
|
2
|
+
|
|
3
|
+
**Plan:** [gpt-chat-mascot.md](../implementationPlans/gpt-chat-mascot.md)
|
|
4
|
+
|
|
5
|
+
- [x] **Task 1**: Optional `mascot` slot on `GPTChat`
|
|
6
|
+
- Files: `ui/src/GPTChat.tsx`, `ui/src/GPTChat.test.tsx`
|
|
7
|
+
- Acceptance: empty chat renders consumer node; omitted prop hides `gpt-mascot`; messages hide it
|
|
8
|
+
- Docs: `docs/reference/ui.md`, `docs/how-to/add-gpt-chat-mascot.md`
|
|
9
|
+
- Skills: `terreno-ui`, `update-docs`, `verify-ui-changes`
|
|
10
|
+
|
|
11
|
+
- [x] **Task 2**: Demo + example consumer
|
|
12
|
+
- Files: `demo/stories/GPTChat.stories.tsx`, `demo/story-config/GPTChat.config.tsx`, `example-frontend/app/(tabs)/ai.tsx`
|
|
13
|
+
- Acceptance: Mascot story and example AI tab pass a node; example coverage notes optional branding
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Tasks: Durable background jobs
|
|
2
|
+
|
|
3
|
+
IP: [job-queues.md](../implementationPlans/job-queues.md)
|
|
4
|
+
**Closes:** https://github.com/FlourishHealth/terreno/issues/1188
|
|
5
|
+
|
|
6
|
+
**Feature profile:** false (full IP)
|
|
7
|
+
|
|
8
|
+
## Phase 1 — Tracer (package, enqueue, Mongo worker)
|
|
9
|
+
|
|
10
|
+
- [x] **Task 1.1**: Scaffold `@terreno/jobs`
|
|
11
|
+
- Delivers: workspace package compiles and lints; root `jobs:compile` / `jobs:test` / `jobs:lint` scripts; empty `JobsApp` registers as `TerrenoPlugin` without starting a worker
|
|
12
|
+
- Files: `jobs/package.json`, `jobs/tsconfig.json`, `jobs/src/index.ts`, `jobs/src/jobsApp.ts`, root `package.json`
|
|
13
|
+
- Blocked by: none
|
|
14
|
+
- Skills: `terreno-backend-api`
|
|
15
|
+
- Docs: none (Phase 5)
|
|
16
|
+
- Acceptance: `bun run jobs:compile` and `bun run jobs:lint` pass; `new TerrenoApp().register(new JobsApp())` boots in a bun test
|
|
17
|
+
|
|
18
|
+
- [x] **Task 1.2**: `Job` model + `define` / `enqueue` + Mongo claim
|
|
19
|
+
- Delivers: five-type `Job` model; `jobs.define(name, {handler})`; `getJobsService().enqueue({name, payload})` inserts `pending`; `MongoJobRunner` claims with `findOneAndUpdate`; handler runs inside `runWithRequestContext({jobId})`; unknown `name` throws `APIError` 400
|
|
20
|
+
- Files: `jobs/src/models/job.ts`, `jobs/src/modelTypes.ts`, `jobs/src/jobsService.ts`, `jobs/src/runners/mongoRunner.ts`, tests
|
|
21
|
+
- Blocked by: 1.1
|
|
22
|
+
- Skills: `mongoose-schema-safety`, `backend-test-env`, `terreno-backend-api`
|
|
23
|
+
- Docs: stub one sentence in `docs/reference/jobs.md` if the file exists; else wait for 5.1
|
|
24
|
+
- Acceptance: bun test — enqueue then `startWorker` completes the job; missing handler fails loud; every schema field has `description`
|
|
25
|
+
|
|
26
|
+
- [x] **Task 1.3**: Explicit `startWorker` in-process and lock reclaim
|
|
27
|
+
- Delivers: `JobsApp.register` does **not** poll; `startWorker()` starts the runner; `stopWorker()` aborts; expired `lockedAt` reclaims `running`; two workers claim one job once
|
|
28
|
+
- Files: `jobs/src/jobsApp.ts`, `jobs/src/runners/mongoRunner.ts`, tests
|
|
29
|
+
- Blocked by: 1.2
|
|
30
|
+
- Skills: `terreno-backend-api`
|
|
31
|
+
- Docs: none (5.1)
|
|
32
|
+
- Acceptance: bun test — no worker until `startWorker`; kill-the-process simulation: leave `pending`, new worker runs it; dual-worker claim uniqueness
|
|
33
|
+
|
|
34
|
+
## Phase 2 — Retries, DLQ, delay, cron
|
|
35
|
+
|
|
36
|
+
- [x] **Task 2.1**: Attempts, backoff, `dead`
|
|
37
|
+
- Delivers: throw → `attemptCount++`, `attempts[]`, `runAt` backoff with jitter; at `maxAttempts` → `status: "dead"`; success → `completed`; `ctx.signal` abort on cancel
|
|
38
|
+
- Files: `jobs/src/jobsService.ts`, retry helper, tests
|
|
39
|
+
- Blocked by: 1.3
|
|
40
|
+
- Skills: `terreno-backend-api`
|
|
41
|
+
- Docs: none (5.1)
|
|
42
|
+
- Acceptance: bun test — three failures with `maxAttempts: 3` land `dead`; between attempts status is `pending` with future `runAt`; Luxon used for delay math
|
|
43
|
+
|
|
44
|
+
- [x] **Task 2.2**: Delayed `runAt` + `idempotencyKey`
|
|
45
|
+
- Delivers: `enqueue({runAt})` not claimed before `runAt`; duplicate `(name, idempotencyKey)` returns the existing job and does not insert a second row
|
|
46
|
+
- Files: `jobs/src/jobsService.ts`, Job indexes, tests
|
|
47
|
+
- Blocked by: 1.2
|
|
48
|
+
- Skills: `mongoose-schema-safety`
|
|
49
|
+
- Docs: none (5.1)
|
|
50
|
+
- Acceptance: bun test — frozen clock (Luxon); unique index violation path covered
|
|
51
|
+
|
|
52
|
+
- [x] **Task 2.3**: `JobSchedule` + recurring cron + IANA timezone
|
|
53
|
+
- Delivers: `define(..., {schedule: {cron, timezone}})`; upsert `JobSchedule`; tick enqueues a child `Job`; skip tick if a child is still `running`/`pending` for that schedule; invalid cron fails at define/start
|
|
54
|
+
- Files: `jobs/src/models/jobSchedule.ts`, scheduler, tests
|
|
55
|
+
- Blocked by: 1.3
|
|
56
|
+
- Skills: `mongoose-schema-safety`, `terreno-backend-api`
|
|
57
|
+
- Docs: none (5.1)
|
|
58
|
+
- Acceptance: bun test — `America/New_York` vs `UTC` next-run; overlap skip; default timezone `UTC`
|
|
59
|
+
|
|
60
|
+
## Phase 3 — Runners and execute HTTP
|
|
61
|
+
|
|
62
|
+
- [x] **Task 3.1**: `JobRunner` interface + custom runner
|
|
63
|
+
- Delivers: injected `runner` used on enqueue/start; test fake runner records `enqueue` calls; Mongo remains default
|
|
64
|
+
- Files: `jobs/src/types.ts`, `jobs/src/runners/custom.ts` (or types-only), tests
|
|
65
|
+
- Blocked by: 1.2
|
|
66
|
+
- Skills: `terreno-backend-api`
|
|
67
|
+
- Docs: none (5.1)
|
|
68
|
+
- Acceptance: bun test — custom runner `enqueue` called once per job; Mongo runner tests still pass
|
|
69
|
+
|
|
70
|
+
- [x] **Task 3.2**: `POST /jobs/execute` auth gate
|
|
71
|
+
- Delivers: route mounted when `mountExecuteRoute` or cloud runner; body `{jobId}`; loads/claims/runs; unsigned 401; terminal completed → 200 no-op; live lock → 409
|
|
72
|
+
- Files: `jobs/src/routes/jobsExecute.ts`, tests
|
|
73
|
+
- Blocked by: 1.3
|
|
74
|
+
- Skills: `terreno-backend-api`, `backend-test-env`
|
|
75
|
+
- Docs: none (5.1)
|
|
76
|
+
- Acceptance: bun + supertest; path can be omitted from SDK codegen (internal tag); rate-limit not skipped
|
|
77
|
+
|
|
78
|
+
- [x] **Task 3.3**: GCP Cloud Tasks adapter (mocked)
|
|
79
|
+
- Delivers: `@terreno/jobs/runners/gcpCloudTasks` optional peer `@google-cloud/tasks`; `enqueue` creates HTTP task to `{publicUrl}/jobs/execute` with OIDC audience; no live GCP
|
|
80
|
+
- Files: `jobs/src/runners/gcpCloudTasks.ts`, tests with fake client, `jobs/package.json` exports/peers
|
|
81
|
+
- Blocked by: 3.1, 3.2
|
|
82
|
+
- Skills: `terreno-backend-api`
|
|
83
|
+
- Docs: env names listed in 5.1
|
|
84
|
+
- Acceptance: bun test — fake client receives queue/url/oidc; missing config fails startup loud
|
|
85
|
+
|
|
86
|
+
- [x] **Task 3.4**: Vercel Queues adapter (mocked)
|
|
87
|
+
- Delivers: `@terreno/jobs/runners/vercelQueues` optional peer; `send(topic,{jobId})` with retention/delay coupling; private `handleCallback` consumer → `executeJobById`; no Workflows API; no live Vercel
|
|
88
|
+
- Files: `jobs/src/runners/vercelQueues.ts`, tests
|
|
89
|
+
- Blocked by: 3.1, 3.2
|
|
90
|
+
- Skills: `terreno-backend-api`
|
|
91
|
+
- Docs: 5.1
|
|
92
|
+
- Acceptance: bun test — fake queue publish/send options, consumer retry directives, >7d dispatch compensation; platform auth delegated to vendor `handleCallback`
|
|
93
|
+
|
|
94
|
+
## Phase 4 — Admin API and UI
|
|
95
|
+
|
|
96
|
+
- [x] **Task 4.1**: Admin HTTP + `admin:jobs`
|
|
97
|
+
- Delivers: list/detail/retry/requeue/cancel + schedule pause/resume; `terrenoStatements.admin` includes `jobs`; 403 without permission; retry creates linked row; requeue from `dead`
|
|
98
|
+
- Files: `jobs/src/routes/jobsAdmin.ts`, `api/src/rbac/statements.ts`, RBAC tests in jobs package, example-backend OpenAPI if needed
|
|
99
|
+
- Blocked by: 2.1, 2.3
|
|
100
|
+
- Skills: `terreno-backend-api`
|
|
101
|
+
- Docs: none (5.1)
|
|
102
|
+
- Acceptance: bun + supertest for 200/403/401; retry vs requeue semantics per IP
|
|
103
|
+
|
|
104
|
+
- [x] **Task 4.2**: Admin frontend Jobs screens
|
|
105
|
+
- Delivers: `JOBS_ADMIN_WIDGETS`, `JobsDashboardScreen`, `JobsJobDetail`, home widget `jobs`; built-in registry (no host remap)
|
|
106
|
+
- Files: `admin-frontend/src/jobs/*`, widget registry, tests + isolated specs
|
|
107
|
+
- Blocked by: 4.1
|
|
108
|
+
- Skills: `building-admin-interfaces`, `terreno-ui`, `terreno-data-fetching`
|
|
109
|
+
- Docs: `docs/how-to/admin-import-prebuilt.md` in 5.1
|
|
110
|
+
- Acceptance: bun tests for render/filter/actions; no `fetch`/`axios`; no syncdb
|
|
111
|
+
|
|
112
|
+
- [x] **Task 4.3**: example-backend + example-frontend + admin-spa + UI verify
|
|
113
|
+
- Delivers: example registers `JobsApp` + Mongo runner; demo job; optional `jobs:worker` script; routes `/admin/jobs`; admin-spa `/jobs`; SDK regen if OpenAPI changed; `JOBS_START_WORKER` gates API-process worker (default true)
|
|
114
|
+
- Files: `example-backend/src/server.ts`, worker entry, `example-frontend/app/admin/**`, `admin-spa/app/**`, `store/openApiSdk.ts` (generated)
|
|
115
|
+
- Blocked by: 4.2, 1.3
|
|
116
|
+
- Skills: `building-admin-interfaces`, `verify-ui-changes`, `generate-sdk`
|
|
117
|
+
- Docs: none (5.1)
|
|
118
|
+
- Acceptance: `verify-ui-changes` — `/opt/cursor/artifacts/jobs_admin_dlq_workflow.mp4` (script→dead attempts→requeue execution→retry linked row); `/opt/cursor/artifacts/jobs_admin_cancel_scheduled_job.mp4` (scheduled cancel confirmation, refresh persistence, no attempts); worker script documented
|
|
119
|
+
|
|
120
|
+
## Phase 5 — Docs, CI, publish
|
|
121
|
+
|
|
122
|
+
- [x] **Task 5.1**: Diátaxis + agent docs + changelog + seed
|
|
123
|
+
- Delivers: how-to, reference, api.md cron contrast, env table, import-prebuilt, seed IP/task URLs, jobs rule, backend-api skill mention, unreleased changelog, `bun run rules` / `skills:sync`
|
|
124
|
+
- Files: `docs/how-to/background-jobs.md`, `docs/reference/jobs.md`, `docs/how-to/README.md`, `docs/reference/api.md`, `docs/reference/environment-variables.md`, `docs/how-to/admin-import-prebuilt.md`, `docs/explanation/roadmap-seed-issues.md`, `.rulesync/rules/jobs/00-jobs.md`, `plugins/terreno-planning/skills/terreno-backend-api/SKILL.md`, `changelog/unreleased/job-queues.md`
|
|
125
|
+
- Blocked by: 3.4, 4.3
|
|
126
|
+
- Skills: `update-docs`, `update-agent-docs`
|
|
127
|
+
- Docs: (this task)
|
|
128
|
+
- Acceptance: stranger can define, enqueue, run a worker, and choose Mongo vs GCP vs Vercel from the how-to; `bun run website:build`; `cronjob()` still documented as process-local
|
|
129
|
+
|
|
130
|
+
- [x] **Task 5.2**: CI + publish wiring
|
|
131
|
+
- Delivers: `jobs-ci.yml`; `publish-on-tag` for `@terreno/jobs`; `cd.yml` path filter includes `jobs/**`
|
|
132
|
+
- Files: `.github/workflows/*`
|
|
133
|
+
- Blocked by: 1.1
|
|
134
|
+
- Skills: none
|
|
135
|
+
- Docs: none
|
|
136
|
+
- Acceptance: workflow validates required secrets if any; package listed in publish job graph
|
|
137
|
+
|
|
138
|
+
- [x] **Task 5.3**: Positioning row (when Complete)
|
|
139
|
+
- Delivers: `docs/explanation/positioning.md` Celery/ActiveJob cell updated only when IP header is **Complete**
|
|
140
|
+
- Files: `docs/explanation/positioning.md`
|
|
141
|
+
- Blocked by: 5.1 and all prior acceptance criteria
|
|
142
|
+
- Skills: `update-docs`
|
|
143
|
+
- Docs: positioning
|
|
144
|
+
- Acceptance: row no longer says Not shipped
|