3 Commits

Author SHA1 Message Date
MechaCat02
b0f7b72dd6 fix(review): close 5 follow-up gaps from Stage 6 audit re-review
- F-T-003 actually closed: clients/typescript/src/subscribe.ts now
  bounds the 401-refresh loop at 3 consecutive refusals, surfaces an
  onError describing the loop, and resets on any successful stream
  open. New test covers the cap. The Stage 2 dashboard fix only
  addressed adminRequest in dashboard/src/lib/api.ts; the originally-
  cited TS client file was untouched.

- users/invitations subtab dropped the redundant api.apps.get fetch
  the other 5 subtabs already shed in Stage 6.

- Queue visibility-timeout validator pulled out as
  validate_queue_visibility_timeout, with two thresholds: hard-reject
  below MIN_QUEUE_VISIBILITY_TIMEOUT_SECS (30s — catches typos), warn-
  log between MIN and SAFE_VISIBILITY_VS_EXEC_BUDGET_SECS (300s) so
  operators see when their visibility is below the dispatcher's
  per-message executor budget. Stage 6 only had the hard floor; the
  reviewer caught that a 60s handler still races a 30s visibility
  even after the floor. Four new unit tests cover none/above-safe/
  between/below-min.

- pic dead-letters count subcommand: cheap headless probe for
  unresolved DL totals, parallels the dashboard's badge query.

- pic dead-letters replay now has a happy-path integration test
  (replay_against_real_dl_row_succeeds): inserts a synthetic DL row
  directly via the rust-postgres sync driver (added as dev-dep),
  drives `pic dead-letters replay`, asserts the row is resolved with
  reason=replayed and count drops back to 0. Plus a count smoke test.

All 75 CLI integration tests + 16 TS client tests + 4 new
visibility-timeout unit tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-11 17:20:34 +02:00
MechaCat02
efb644efe9 fix(clients/ts): F-T-001 + F-T-002 flat useEndpointGet / useEndpointPost hooks
useEndpoint(path) returned `{ get: () => useResource(...), post: (body)
=> useResource(...) }`. Each of `.get()` and `.post()` called useState
+ useEffect — but React's Rules of Hooks require hook calls at the top
level of a component, in the same order each render. Calling
.get() conditionally, or both .get() and .post() from the same
component, produced undefined behaviour (state leaking between them).
The test suite covered only useTopic, so this was uncaught.

Separately (F-T-002): the JSDoc said .post() was "the mutation variant
(auto-fires once per mount)" — but auto-firing a POST on mount means
typo'd code creates a user (or sends an email) on every render refresh.

Refactor:
- Remove useEndpoint entirely (public API breaking change — clients/ts
  v1.1.x has no external consumers yet per CLAUDE.md).
- Add useEndpointGet<Res>(path): QueryState<Res> — flat hook, auto-fires.
- Add useEndpointPost<Req, Res>(path): { mutate, data, loading, error }
  — flat hook, event-driven (NOT auto-firing); call `mutate(body)` from
  the submit handler.

README updated to demonstrate both shapes side-by-side.

Existing 15 unit tests pass (useTopic unaffected; useEndpoint tests
never existed). Adding a useEndpointGet/Post test pass is finding
F-T-001 follow-up.

AUDIT.md anchor: F-T-001 (+ F-T-002 folded in).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-07 20:30:26 +02:00
MechaCat02
b1dddb9cb9 feat(v1.1.6-client): @picloud/client TypeScript package
First frontend library (v1.0.0), co-shipped with realtime. Hybrid
model — no direct service access from the browser.

- endpoint<Req,Res>(path).get()/.post() — typed HTTP, auth-token
  injection, structured errors, optional zod/valibot validate adapter.
- subscribe(topic, cb, {token, onTokenExpired}) — streaming-fetch SSE
  with exponential-backoff reconnect, 401 token refresh, Last-Event-ID
  resume.
- auth.login/logout/token over dev-defined endpoints.
- React (useTopic/useEndpoint + PicloudProvider) and Svelte
  (topicStore/endpointStore) subpath exports.

Build: tsup (ESM+CJS+.d.ts); tests: vitest (15); lint: tsc --noEmit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 20:19:07 +02:00