@checkstack/announcement-backend 0.3.12 → 0.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/CHANGELOG.md +64 -0
- package/package.json +8 -8
- package/src/router.test.ts +37 -0
- package/src/router.ts +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,69 @@
|
|
|
1
1
|
# @checkstack/announcement-backend
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9dcc848: Align workspace dependency versions and migrate React Router to v7.
|
|
8
|
+
|
|
9
|
+
BREAKING CHANGES (React Router v7): All frontend packages now depend on `react-router-dom@^7.16.0`. Previously the workspace declared four divergent ranges (`^6.20.0`, `^6.22.0`, `^7.1.1`, `^7.14.2`), which resolved both `react-router@6` and `react-router@7` into a single bundle. Everything is now unified on v7. The public imports the app uses (`BrowserRouter`, `Routes`, `Route`, `Link`, `NavLink`, `MemoryRouter`, `useNavigate`, `useParams`, `useSearchParams`, `useLocation`) are unchanged between v6 and v7, so no source rewrites were required - but any out-of-tree plugin still on react-router v6 should upgrade to v7 (see the React Router v6 -> v7 upgrade guide) to share the host's single router instance via the import map.
|
|
10
|
+
|
|
11
|
+
Other unified ranges (no API change): `react` -> `^18.3.1`, the `@orpc/*` family (`contract`, `server`, `client`, `tanstack-query`, `openapi`, `zod`) -> `^1.14.4`, and `better-auth` -> `^1.6.13`.
|
|
12
|
+
|
|
13
|
+
Removed the pre-rename `@orpc/react-query` leftover from `@checkstack/frontend-api`; its `createRouterUtils` / `RouterUtils` / `ProcedureUtils` now come from `@orpc/tanstack-query` (the package already in use).
|
|
14
|
+
|
|
15
|
+
Stale in-range runtime deps pulled up to current published versions: `hono` `^4.12.23`, `@tanstack/react-query` (+devtools) `^5.100.14`, `date-fns` `^4.4.0`, `jose` `^6.2.3`, `tar` `^7.5.16`, `semver` `^7.8.1`, `@xyflow/react` `^12.11.0`.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 9dcc848: Assorted bug fixes and small hardening across the platform.
|
|
20
|
+
|
|
21
|
+
- announcement-backend: `updateAnnouncement` now invalidates the active-announcements and admin-list caches (it was missing the `invalidateAllActive` / `invalidateListAll` calls), so an edited announcement no longer stays stale up to the 45s TTL.
|
|
22
|
+
- anomaly-backend: anomaly/drift state transitions (confirmations, recoveries, self-resolutions) now log at `debug` instead of info/warn - they are already surfaced via the `ANOMALY_STATE_CHANGED` signal, so logging them louder just added noise; genuine failure paths stay `warn`.
|
|
23
|
+
- backend: the `/api/:pluginId/*` dispatcher now populates `requestHeaders` on the per-request RPC context, so a handler that re-enters the router as the originating user (e.g. an AI tool's user-scoped client) can forward the caller's session cookie / bearer - previously the loopback failed with "Authentication required". Guarded by a real end-to-end integration test. The HTTP server idle timeout is also raised (default 255s, configurable via `CHECKSTACK_SERVER_IDLE_TIMEOUT_SECONDS`, clamped 0-255, reset on each streamed chunk) so long AI chat SSE turns are not severed mid-stream.
|
|
24
|
+
- backend: a request for an unknown plugin id (`/api/<unknown>/...`) now returns `404 Not Found` instead of `500` (and logs at warn, not error, since it is a client request) - an unknown _procedure_ on a known plugin already 404'd. The in-app docs namespace `/checkstack/*` now serves Starlight's own `404.html` with a real 404 status for a missing doc, instead of falling through to the SPA catch-all and 200-ing the app shell. Both guarded by tests.
|
|
25
|
+
- automation-common: remove polynomial-time backtracking from `toShellEnvKey`'s underscore-trim (CodeQL `js/polynomial-redos`); a negative look-behind anchors the trailing run, keeping the trim linear.
|
|
26
|
+
- common + script-packages-common: the pure transport-safe sandbox-policy schema (`sandboxPolicySchema` and its sub-schemas + inferred types) moved to `@checkstack/common` (the neutral base), removing two inverted deps that existed only to reach the shape; `@checkstack/backend-api` continues to re-export it. The schema is no longer exported from `@checkstack/script-packages-common`. Pure refactor, no behavior change.
|
|
27
|
+
- catalog-backend: reject duplicate system names (a `CONFLICT` on create/rename, enforced by a pre-write check AND a new DB unique index on `systems.name`, migration 0004 which first resolves pre-existing duplicates by suffixing).
|
|
28
|
+
- catalog-frontend: detail-page cleanups (use `<NotFound />` not `<AccessDenied />` on the not-found branch, a readable key/value metadata list via `normalizeMetadata`, runtime locale via `formatDate`); and stop the browse view re-rendering on every health report (adopt a new statuses report only when a value actually changed, via `healthStatusesEqual`, so rows stay stable and interactive).
|
|
29
|
+
- healthcheck-backend: fix the daily-rollup retention step failing with an `ON CONFLICT` mismatch (SQLSTATE 42P10) after `environmentId` joined the `health_check_aggregates` unique constraint - the rollup now groups by (day, environmentId, sourceId) and uses a single exported conflict-target constant (`DAILY_AGGREGATE_CONFLICT_TARGET`) kept in lock-step with the schema by a unit test.
|
|
30
|
+
- automation-frontend: the service-account picker's "Learn more" links are now absolute URLs to the deployed Astro docs site (they 404ed as in-app relative paths). The Monaco script editor double-init crash is fixed (serialized cold init, a guarded `monacoGuard` accessor, theme/type effects gated on `apiReady`).
|
|
31
|
+
- auth-frontend: bound the desktop user-menu popover height (`max-h-[var(--radix-popover-content-available-height)]` + `overflow-y-auto`) so it no longer clips on short viewports, and fold the standalone `Account > Profile` item into a focusable name/email header (`profileHref` on `UserMenu`); the now-empty `Account` group no longer renders.
|
|
32
|
+
- satellite-frontend: picked up via the sidebar-nav migration (account-only user menu).
|
|
33
|
+
|
|
34
|
+
(Related UI fixes - the Monaco editor following the app theme, the `DynamicOptionsField` no-flash fix, the shared `Spinner`, GFM tables, and the user-menu popover bound - land their `@checkstack/ui` bump in the UI/perf changesets where `@checkstack/ui` is already minored.)
|
|
35
|
+
|
|
36
|
+
This is a beta patch.
|
|
37
|
+
|
|
38
|
+
- Updated dependencies [9dcc848]
|
|
39
|
+
- Updated dependencies [9dcc848]
|
|
40
|
+
- Updated dependencies [9dcc848]
|
|
41
|
+
- Updated dependencies [9dcc848]
|
|
42
|
+
- Updated dependencies [9dcc848]
|
|
43
|
+
- Updated dependencies [9dcc848]
|
|
44
|
+
- Updated dependencies [9dcc848]
|
|
45
|
+
- Updated dependencies [9dcc848]
|
|
46
|
+
- Updated dependencies [9dcc848]
|
|
47
|
+
- @checkstack/auth-backend@0.5.0
|
|
48
|
+
- @checkstack/backend-api@0.21.0
|
|
49
|
+
- @checkstack/common@0.13.0
|
|
50
|
+
- @checkstack/announcement-common@0.5.0
|
|
51
|
+
- @checkstack/command-backend@0.2.0
|
|
52
|
+
- @checkstack/cache-api@0.3.9
|
|
53
|
+
- @checkstack/signal-common@0.2.6
|
|
54
|
+
- @checkstack/cache-utils@0.2.14
|
|
55
|
+
|
|
56
|
+
## 0.3.13
|
|
57
|
+
|
|
58
|
+
### Patch Changes
|
|
59
|
+
|
|
60
|
+
- Updated dependencies [a57f7db]
|
|
61
|
+
- @checkstack/backend-api@0.20.0
|
|
62
|
+
- @checkstack/auth-backend@0.4.33
|
|
63
|
+
- @checkstack/cache-api@0.3.8
|
|
64
|
+
- @checkstack/command-backend@0.1.33
|
|
65
|
+
- @checkstack/cache-utils@0.2.13
|
|
66
|
+
|
|
3
67
|
## 0.3.12
|
|
4
68
|
|
|
5
69
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checkstack/announcement-backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"license": "Elastic-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -14,22 +14,22 @@
|
|
|
14
14
|
"lint:code": "eslint . --max-warnings 0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@checkstack/backend-api": "0.
|
|
18
|
-
"@checkstack/cache-api": "0.3.
|
|
19
|
-
"@checkstack/cache-utils": "0.2.
|
|
17
|
+
"@checkstack/backend-api": "0.20.0",
|
|
18
|
+
"@checkstack/cache-api": "0.3.8",
|
|
19
|
+
"@checkstack/cache-utils": "0.2.13",
|
|
20
20
|
"@checkstack/announcement-common": "0.4.2",
|
|
21
|
-
"@checkstack/auth-backend": "0.4.
|
|
22
|
-
"@checkstack/command-backend": "0.1.
|
|
21
|
+
"@checkstack/auth-backend": "0.4.33",
|
|
22
|
+
"@checkstack/command-backend": "0.1.33",
|
|
23
23
|
"@checkstack/common": "0.12.0",
|
|
24
24
|
"@checkstack/signal-common": "0.2.5",
|
|
25
25
|
"drizzle-orm": "^0.45.0",
|
|
26
26
|
"zod": "^4.2.1",
|
|
27
|
-
"@orpc/server": "^1.
|
|
27
|
+
"@orpc/server": "^1.14.4"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@checkstack/drizzle-helper": "0.0.5",
|
|
31
31
|
"@checkstack/scripts": "0.3.4",
|
|
32
|
-
"@checkstack/test-utils-backend": "0.1.
|
|
32
|
+
"@checkstack/test-utils-backend": "0.1.33",
|
|
33
33
|
"@checkstack/tsconfig": "0.0.7",
|
|
34
34
|
"@types/bun": "^1.0.0",
|
|
35
35
|
"drizzle-kit": "^0.31.10",
|
package/src/router.test.ts
CHANGED
|
@@ -345,6 +345,43 @@ describe("Announcement Router", () => {
|
|
|
345
345
|
);
|
|
346
346
|
});
|
|
347
347
|
|
|
348
|
+
it("invalidates both active and list-all caches after a successful update", async () => {
|
|
349
|
+
const context = createMockRpcContext({ user: adminUser });
|
|
350
|
+
|
|
351
|
+
const invalidateAllActiveSpy = mock(() => Promise.resolve(0));
|
|
352
|
+
const invalidateListAllSpy = mock(() => Promise.resolve());
|
|
353
|
+
|
|
354
|
+
const spyCache: AnnouncementCache = {
|
|
355
|
+
...passthroughCache,
|
|
356
|
+
invalidateAllActive: invalidateAllActiveSpy,
|
|
357
|
+
invalidateListAll: invalidateListAllSpy,
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
const routerWithSpyCache = createAnnouncementRouter(
|
|
361
|
+
mockDb as never,
|
|
362
|
+
mockSignalService,
|
|
363
|
+
spyCache,
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
const updatedRow = { ...sampleAnnouncement, active: false };
|
|
367
|
+
mockDb.update.mockReturnValueOnce({
|
|
368
|
+
set: mock(() => ({
|
|
369
|
+
where: mock(() => ({
|
|
370
|
+
returning: mock(() => Promise.resolve([updatedRow])),
|
|
371
|
+
})),
|
|
372
|
+
})),
|
|
373
|
+
} as never);
|
|
374
|
+
|
|
375
|
+
await call(
|
|
376
|
+
routerWithSpyCache.updateAnnouncement,
|
|
377
|
+
{ id: "ann-1", active: false },
|
|
378
|
+
{ context },
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
expect(invalidateAllActiveSpy).toHaveBeenCalledTimes(1);
|
|
382
|
+
expect(invalidateListAllSpy).toHaveBeenCalledTimes(1);
|
|
383
|
+
});
|
|
384
|
+
|
|
348
385
|
it("throws NOT_FOUND for non-existent announcement", async () => {
|
|
349
386
|
const context = createMockRpcContext({ user: adminUser });
|
|
350
387
|
|
package/src/router.ts
CHANGED
|
@@ -245,6 +245,11 @@ export function createAnnouncementRouter(
|
|
|
245
245
|
|
|
246
246
|
const announcement = toAnnouncement(row);
|
|
247
247
|
|
|
248
|
+
await Promise.all([
|
|
249
|
+
cache.invalidateAllActive(),
|
|
250
|
+
cache.invalidateListAll(),
|
|
251
|
+
]);
|
|
252
|
+
|
|
248
253
|
await signalService.broadcast(ANNOUNCEMENT_UPDATED, {
|
|
249
254
|
announcementId: announcement.id,
|
|
250
255
|
action: "updated",
|