docs(plan): the browser token comes from the pocketbase auth store, not useAuth

This commit is contained in:
Dave 2026-11-06 15:15:17 +02:00
parent 20ef99264d
commit c581823990

View file

@ -24,6 +24,38 @@
- Commit per task with the exact message given. Stage by explicit path — never `git add -A`.
- Follow this repo's existing conventions. Read `src/app/(rep)/rep/layout.tsx` and `public/manifest-rep.json` before you start — you are copying that pattern, not inventing one.
## How the browser token is obtained — read this before writing any fetch
The browser session token is NOT on the auth context. §useAuth()§ from
§@/components/auth-provider§ exposes §user§, §loading§ and the auth actions,
and **no §token§**. Reading §useAuth().token§ gives §undefined§, which makes
§authHeaders()§ silently send NO session and every route answers 401.
The token lives in the PocketBase client auth store. This is the house
pattern — copy it exactly:
§§§ts
import { getPocketBase } from "@/lib/pocketbase";
const token = getPocketBase().authStore.token;
const headers = token ? { Authorization: "Bearer " + token } : {};
§§§
§src/app/(app)/delivery-pool/page.tsx§ and §src/app/(app)/search/page.tsx§
both do this. The Task 1 implementer confirmed it against the real
§auth-provider.tsx§, and every repairs fetch in the office screens now
uses it.
**In tests**, mock the pocketbase module, not the auth provider:
§§§ts
vi.mock("@/lib/pocketbase", () => ({
getPocketBase: () => ({ authStore: { token: "t" } }),
}));
§§§
---
## What is already in place (do not re-create it)
- `@/lib/repair-status` — `REPAIR_STATUS`, `REPAIR_STATUS_LABEL`, `REPAIR_STATUS_VARIANT`, `REPAIR_TRANSITIONS`, `nextStepFor(status)` returning `{ label, action, to }` or `null`, `type RepairStatus`, `type RepairAction`, `interface RepairNextStep`.
@ -163,7 +195,7 @@ In `src/app/(app)/repairs/page.tsx` and `src/app/(app)/repairs/[id]/page.tsx`, e
Read the token from `useAuth()` — the same hook `MobileAuthGate` uses. Add a small helper in each page, matching the repo's existing shape:
```ts
const { token } = useAuth();
const token = getPocketBase().authStore.token;
const authHeaders = () => (token ? { Authorization: "Bearer " + token } : {});
```
@ -508,8 +540,8 @@ import { describe, it, expect, beforeEach, vi } from "vitest";
import { render, screen, waitFor } from "@testing-library/react";
import { RepairBoard } from "./repair-board";
vi.mock("@/components/auth-provider", () => ({
useAuth: () => ({ token: "t", user: { id: "u1" }, loading: false }),
vi.mock("@/lib/pocketbase", () => ({
getPocketBase: () => ({ authStore: { token: "t" } }),
}));
const REPAIRS = [
@ -628,7 +660,7 @@ Create `src/app/(repairs-app)/repairs-app/repair-board.tsx`:
import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { Badge } from "@/components/ui/badge";
import { useAuth } from "@/components/auth-provider";
import { getPocketBase } from "@/lib/pocketbase";
import {
REPAIR_STATUS,
REPAIR_STATUS_LABEL,
@ -661,7 +693,7 @@ const EMPTY_COUNTS: Counts = {
* must not invent one.
*/
export function RepairBoard() {
const { token } = useAuth();
const token = getPocketBase().authStore.token;
const [repairs, setRepairs] = useState<Repair[]>([]);
const [counts, setCounts] = useState<Counts>(EMPTY_COUNTS);
const [status, setStatus] = useState<RepairStatus | "">("");
@ -882,8 +914,8 @@ vi.mock("next/navigation", () => ({
useRouter: () => ({ push: vi.fn(), replace: vi.fn() }),
}));
vi.mock("@/components/auth-provider", () => ({
useAuth: () => ({ token: "t", user: { id: "u1" }, loading: false }),
vi.mock("@/lib/pocketbase", () => ({
getPocketBase: () => ({ authStore: { token: "t" } }),
}));
vi.mock("@/components/ui/customer-search", () => ({
@ -965,7 +997,7 @@ import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { CustomerSearch } from "@/components/ui/customer-search";
import { SupplierSearch } from "@/components/ui/supplier-search";
import { useAuth } from "@/components/auth-provider";
import { getPocketBase } from "@/lib/pocketbase";
const MAX_PHOTOS = 10;
@ -979,7 +1011,7 @@ const MAX_PHOTOS = 10;
*/
export function BookInForm() {
const router = useRouter();
const { token } = useAuth();
const token = getPocketBase().authStore.token;
const fileRef = useRef<HTMLInputElement>(null);
const [customerId, setCustomerId] = useState<string | null>(null);
@ -1231,8 +1263,8 @@ import { describe, it, expect, beforeEach, vi } from "vitest";
import { render, screen, waitFor } from "@testing-library/react";
import { RepairDetail } from "./repair-detail";
vi.mock("@/components/auth-provider", () => ({
useAuth: () => ({ token: "t", user: { id: "u1" }, loading: false }),
vi.mock("@/lib/pocketbase", () => ({
getPocketBase: () => ({ authStore: { token: "t" } }),
}));
const REPAIR = {
@ -1322,7 +1354,7 @@ Create `src/app/(repairs-app)/repairs-app/[id]/repair-detail.tsx`:
import { useCallback, useEffect, useRef, useState } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { useAuth } from "@/components/auth-provider";
import { getPocketBase } from "@/lib/pocketbase";
import {
REPAIR_STATUS,
REPAIR_STATUS_LABEL,
@ -1340,7 +1372,7 @@ import type { Repair } from "@/lib/types";
* rather than a dead one.
*/
export function RepairDetail({ repairId }: { repairId: string }) {
const { token } = useAuth();
const token = getPocketBase().authStore.token;
const fileRef = useRef<HTMLInputElement>(null);
const [repair, setRepair] = useState<Repair | null>(null);
const [error, setError] = useState<string | null>(null);