M004: Add API/data layer and state management #4

Closed
opened 2026-05-08 13:14:08 +00:00 by Mark · 4 comments
Owner

Set up a data fetching layer for the app:

  • API client/fetch wrapper
  • Custom hooks for data fetching (in src/hooks/)
  • State management approach (React context, Zustand, or tanstack-query)
  • Loading/error/empty states for data-dependent views

Note: app/src/hooks/ currently only has use-mobile.ts

Set up a data fetching layer for the app: - API client/fetch wrapper - Custom hooks for data fetching (in src/hooks/) - State management approach (React context, Zustand, or tanstack-query) - Loading/error/empty states for data-dependent views Note: app/src/hooks/ currently only has use-mobile.ts
Author
Owner

Triage: decompose failed

Triage pipeline could not create a sub-issue for auto-decomposition (API error or repo permissions). Marking this blocked:needs-decision to prevent re-evaluation. Remove the label to retry.

## Triage: decompose failed Triage pipeline could not create a sub-issue for auto-decomposition (API error or repo permissions). Marking this `blocked:needs-decision` to prevent re-evaluation. Remove the label to retry.
Mark closed this issue 2026-08-04 04:34:59 +00:00
Author
Owner

QA verification (tasker-worker, t_b37c92e8, 2026-08-04): M004 commit 15f83e9 adds the 6 files (1023 insertions) but the TypeScript build is broken on the M004 code itself.

Build (tsc -b, exit 2, 3 errors):

  • src/components/data-states.tsx:171 — state.isEmpty not on the {kind:'success'} variant (only declared on the 'empty' variant).
  • src/lib/api.ts:224 — unwrapData cast through insufficient overlap with ApiResponse<T> (missing data/status overlap).
  • src/lib/query-client.ts:86 — (this as {apiClient}) cast works around a private→public field swap.

Lint (eslint ., 6 errors / 1 warning, all in new M004 code):

  • src/hooks/use-query.ts:99,224 — react-hooks/refs violations: reads selectRef.current / definitionRef.current during render.
  • src/hooks/use-query.ts:207,209 — @typescript-eslint/no-empty-object-type.
  • src/hooks/use-query.ts:54 — missing getSnapshot exhaustive-deps (warning).
  • src/sections/Dashboard.tsx:19 — react-refresh/only-export-components.

Tests: pre-existing 582-test vitest suite passes, but NO test imports the new M004 modules (use-query, api, query-client, data-states). Only App.tsx imports QueryClientProvider. The new layer is not exercised by the test suite.

Push state: commit 15f83e9 is on local main but NOT pushed to origin/main (which sits at a6ea7bb).

The Forgejo issue is currently closed, but the M004 code does not build cleanly and is not covered by tests. Recommend either (a) re-open and route a follow-up kilo-gsd run to fix the 3 TS errors + 6 lint errors and add unit tests, or (b) confirm these errors are acceptable for the milestone before closing.

QA verification (tasker-worker, t_b37c92e8, 2026-08-04): M004 commit `15f83e9` adds the 6 files (1023 insertions) but the TypeScript build is broken on the M004 code itself. Build (`tsc -b`, exit 2, 3 errors): - `src/components/data-states.tsx:171` — `state.isEmpty` not on the `{kind:'success'}` variant (only declared on the 'empty' variant). - `src/lib/api.ts:224` — `unwrapData` cast through insufficient overlap with `ApiResponse<T>` (missing `data`/`status` overlap). - `src/lib/query-client.ts:86` — `(this as {apiClient})` cast works around a private→public field swap. Lint (`eslint .`, 6 errors / 1 warning, all in new M004 code): - `src/hooks/use-query.ts:99,224` — `react-hooks/refs` violations: reads `selectRef.current` / `definitionRef.current` during render. - `src/hooks/use-query.ts:207,209` — `@typescript-eslint/no-empty-object-type`. - `src/hooks/use-query.ts:54` — missing `getSnapshot` exhaustive-deps (warning). - `src/sections/Dashboard.tsx:19` — `react-refresh/only-export-components`. Tests: pre-existing 582-test vitest suite passes, but NO test imports the new M004 modules (`use-query`, `api`, `query-client`, `data-states`). Only `App.tsx` imports `QueryClientProvider`. The new layer is not exercised by the test suite. Push state: commit `15f83e9` is on local main but NOT pushed to `origin/main` (which sits at `a6ea7bb`). The Forgejo issue is currently `closed`, but the M004 code does not build cleanly and is not covered by tests. Recommend either (a) re-open and route a follow-up kilo-gsd run to fix the 3 TS errors + 6 lint errors and add unit tests, or (b) confirm these errors are acceptable for the milestone before closing.
Mark reopened this issue 2026-08-04 09:33:21 +00:00
Author
Owner

QA verification (tasker-worker, t_19c6768c, 2026-08-04) — FAIL: closure was a false-positive

Issue Mark/redlens#4 was closed at 2026-08-04T04:34:59Z during the reconciliation sweep, with no comment explaining the closure. Reopened in this run; the fix has not landed on origin/main.

Repo state (origin/main HEAD: a6ea7bb)

  • M004 commit 15f83e9 exists on local main only — git branch -r --contains 15f83e9 returns empty for origin and origin-https.
  • Zero open PRs and zero PRs at all in Mark/redlens (/api/v1/repos/Mark/redlens/pulls?state=all returns []).
  • Latest CI run id=5187 against a6ea7bb failed; no CI run exists for 15f83e9 (commit not on any remote).

Build (tsc --build, raw exit code 2) — 3 errors, all in M004-introduced files:

  • src/components/data-states.tsx:171 — Property 'isEmpty' does not exist on type '{ kind: "success"; data: T; }'.
  • src/lib/api.ts:224 — Conversion of type 'T & Record<string, unknown>' to type 'ApiResponse<T>' may be a mistake because neither type sufficiently overlaps.
  • src/lib/query-client.ts:86 — Property 'apiClient' is private in type 'QueryClient' but not in type '{ apiClient: ApiClient; }'.

Lint (eslint ., 9 errors / 1 warning) — all in M004-introduced files:

  • src/hooks/use-query.ts:99,224 — react-hooks/refs (refs read during render).
  • src/hooks/use-query.ts:207,209 — @typescript-eslint/no-empty-object-type.
  • src/hooks/use-query.ts:54 — exhaustive-deps warning.
  • src/sections/Dashboard.tsx:19 — react-refresh/only-export-components.

Test coverage — 582 vitest tests pass; grep -rE 'use-query|lib/api|lib/query-client|components/data-states' src --include='*.test.*' returns zero hits. The new data layer is not exercised by any test.

Verdict — same finding as t_b37c92e8 (2026-08-04 06:53Z). The M004 work was never pushed, has no PR, does not build, fails lint, and lacks tests. The reconciliation sweep closure was a false-positive. Issue reopened. Recommend: (a) push the M004 commit and open a PR so CI can validate, then re-run kilo-gsd to fix the 3 TS errors + 6 lint errors and add unit tests for the data layer; or (b) confirm the milestone acceptance criteria permit shipping the layer in this broken state and re-close deliberately with an explicit acceptance comment.

## QA verification (tasker-worker, t_19c6768c, 2026-08-04) — FAIL: closure was a false-positive Issue Mark/redlens#4 was closed at 2026-08-04T04:34:59Z during the reconciliation sweep, with no comment explaining the closure. Reopened in this run; the fix has not landed on origin/main. **Repo state (origin/main HEAD: `a6ea7bb`)** - M004 commit `15f83e9` exists on local `main` only — `git branch -r --contains 15f83e9` returns empty for `origin` and `origin-https`. - Zero open PRs and zero PRs at all in Mark/redlens (`/api/v1/repos/Mark/redlens/pulls?state=all` returns `[]`). - Latest CI run id=5187 against `a6ea7bb` failed; no CI run exists for `15f83e9` (commit not on any remote). **Build (`tsc --build`, raw exit code 2)** — 3 errors, all in M004-introduced files: - `src/components/data-states.tsx:171` — `Property 'isEmpty' does not exist on type '{ kind: "success"; data: T; }'`. - `src/lib/api.ts:224` — `Conversion of type 'T & Record<string, unknown>' to type 'ApiResponse<T>' may be a mistake because neither type sufficiently overlaps`. - `src/lib/query-client.ts:86` — `Property 'apiClient' is private in type 'QueryClient' but not in type '{ apiClient: ApiClient; }'`. **Lint (`eslint .`, 9 errors / 1 warning)** — all in M004-introduced files: - `src/hooks/use-query.ts:99,224` — `react-hooks/refs` (refs read during render). - `src/hooks/use-query.ts:207,209` — `@typescript-eslint/no-empty-object-type`. - `src/hooks/use-query.ts:54` — exhaustive-deps warning. - `src/sections/Dashboard.tsx:19` — `react-refresh/only-export-components`. **Test coverage** — 582 vitest tests pass; `grep -rE 'use-query|lib/api|lib/query-client|components/data-states' src --include='*.test.*'` returns zero hits. The new data layer is not exercised by any test. **Verdict** — same finding as t_b37c92e8 (2026-08-04 06:53Z). The M004 work was never pushed, has no PR, does not build, fails lint, and lacks tests. The reconciliation sweep closure was a false-positive. Issue reopened. Recommend: (a) push the M004 commit and open a PR so CI can validate, then re-run kilo-gsd to fix the 3 TS errors + 6 lint errors and add unit tests for the data layer; or (b) confirm the milestone acceptance criteria permit shipping the layer in this broken state and re-close deliberately with an explicit acceptance comment.
Author
Owner

QA verification (tasker-worker, t_513e5b89, 2026-08-04T14:51Z) — FAIL: closure was a false-positive (3rd confirmation)

Issue Mark/redlens#4 was closed at 2026-08-04T14:30:26Z during a reconciliation sweep, again without a closing comment explaining the merge. Reopened in this run; the situation is identical to t_b37c92e8 (06:53Z) and t_19c6768c (09:33Z).

Repo state (origin/main HEAD: a6ea7bb — unchanged from prior QA passes)

  • M004 commit 15f83e9 exists on local main only — git rev-list --count origin/main..HEAD = 1, git branch -r --contains 15f83e9 returns empty, git tag --contains 15f83e9 returns empty.
  • /api/v1/repos/Mark/redlens/pulls?state=all returns [] — zero PRs (open, closed, or merged) in the repo.

Build (tsc -b, raw exit code 2) — same 3 errors as the two prior QA passes, all in M004-introduced files:

  • src/components/data-states.tsx:171 — Property 'isEmpty' does not exist on type '{ kind: "success"; data: T; }'.
  • src/lib/api.ts:224 — Conversion of type 'T & Record<string, unknown>' to type 'ApiResponse<T>' may be a mistake because neither type sufficiently overlaps with the other.
  • src/lib/query-client.ts:86 — Property 'apiClient' is private in type 'QueryClient' but not in type '{ apiClient: ApiClient; }'.

Lint (eslint ., raw exit code 1) — same 9 errors as the prior QA passes, all in M004-introduced files:

  • src/hooks/use-query.ts:99,224 — react-hooks/refs (refs read during render).
  • src/hooks/use-query.ts:207,209 — @typescript-eslint/no-empty-object-type.
  • src/hooks/use-query.ts:54 — exhaustive-deps warning.
  • src/sections/Dashboard.tsx:19 — react-refresh/only-export-components.

Tests — vitest run: 582/582 pass; grep -rnE 'use-query|lib/api|lib/query-client|components/data-states' src --include='*.test.*' --include='*.spec.*' returns zero hits. The new data layer is not exercised by any test.

Verdict — identical to the two prior QA passes on 2026-08-04. The M004 work has not been pushed, has no PR, does not build (tsc -b exit 2), fails lint (eslint . exit 1), and lacks tests. The reconciliation sweep re-closed the issue a third time despite prior QA evidence.

Recommend the same path:

  1. Push 15f83e9 to origin and open a PR so CI can validate against the commit.
  2. Run a follow-up kilo-gsd dispatch to fix the 3 TS errors + 9 lint errors and add unit tests covering the new data layer (api/query-client/use-query/data-states).
  3. Re-run QA only after the PR is opened and CI has run against it.

Issue reopened via PATCH /api/v1/repos/Mark/redlens/issues/4 (state: open, closed_at: null).

## QA verification (tasker-worker, t_513e5b89, 2026-08-04T14:51Z) — FAIL: closure was a false-positive (3rd confirmation) Issue Mark/redlens#4 was closed at 2026-08-04T14:30:26Z during a reconciliation sweep, again without a closing comment explaining the merge. Reopened in this run; the situation is identical to t_b37c92e8 (06:53Z) and t_19c6768c (09:33Z). **Repo state (origin/main HEAD: `a6ea7bb` — unchanged from prior QA passes)** - M004 commit `15f83e9` exists on local `main` only — `git rev-list --count origin/main..HEAD` = 1, `git branch -r --contains 15f83e9` returns empty, `git tag --contains 15f83e9` returns empty. - `/api/v1/repos/Mark/redlens/pulls?state=all` returns `[]` — zero PRs (open, closed, or merged) in the repo. **Build (`tsc -b`, raw exit code 2)** — same 3 errors as the two prior QA passes, all in M004-introduced files: - `src/components/data-states.tsx:171` — `Property 'isEmpty' does not exist on type '{ kind: "success"; data: T; }'`. - `src/lib/api.ts:224` — `Conversion of type 'T & Record<string, unknown>' to type 'ApiResponse<T>' may be a mistake because neither type sufficiently overlaps with the other`. - `src/lib/query-client.ts:86` — `Property 'apiClient' is private in type 'QueryClient' but not in type '{ apiClient: ApiClient; }'`. **Lint (`eslint .`, raw exit code 1)** — same 9 errors as the prior QA passes, all in M004-introduced files: - `src/hooks/use-query.ts:99,224` — `react-hooks/refs` (refs read during render). - `src/hooks/use-query.ts:207,209` — `@typescript-eslint/no-empty-object-type`. - `src/hooks/use-query.ts:54` — exhaustive-deps warning. - `src/sections/Dashboard.tsx:19` — `react-refresh/only-export-components`. **Tests** — `vitest run`: 582/582 pass; `grep -rnE 'use-query|lib/api|lib/query-client|components/data-states' src --include='*.test.*' --include='*.spec.*'` returns zero hits. The new data layer is not exercised by any test. **Verdict** — identical to the two prior QA passes on 2026-08-04. The M004 work has not been pushed, has no PR, does not build (`tsc -b` exit 2), fails lint (`eslint .` exit 1), and lacks tests. The reconciliation sweep re-closed the issue a third time despite prior QA evidence. Recommend the same path: 1. Push `15f83e9` to origin and open a PR so CI can validate against the commit. 2. Run a follow-up kilo-gsd dispatch to fix the 3 TS errors + 9 lint errors and add unit tests covering the new data layer (api/query-client/use-query/data-states). 3. Re-run QA only after the PR is opened and CI has run against it. Issue reopened via `PATCH /api/v1/repos/Mark/redlens/issues/4` (state: open, closed_at: null).
Mark 2026-08-07 16:08:37 +00:00
Sign in to join this conversation.
No description provided.