Getting started
Can I work on this without access to the backend?
Can I work on this without access to the backend?
.env, no database, no Docker, no OAuth app. See the Mock API
guide.Do I need to copy .env.example?
Do I need to copy .env.example?
pnpm dev:mock. It sets every variable it needs inline. You only need a .env
for the optional feature-request webhook or S3 metadata assets.How do I test signed-in and signed-out states?
How do I test signed-in and signed-out states?
A request returned 501. Is something broken?
A request returned 501. Is something broken?
501 for routes it doesn’t handle yet, and logs
[mock-api] UNHANDLED <method> <path>. Adding the missing handler is a welcome
contribution: see adding a handler.My data disappeared after restarting
My data disappeared after restarting
Architecture
Why feature-based rather than layer-based?
Why feature-based rather than layer-based?
Where do I put an API call?
Where do I put an API call?
services/*.service.ts: the function that talks to the APIhooks/*.keys.ts: the query keyhooks/*.queries.tsor*.mutations.ts: the hook components use
fetch or a service directly. There’s a full walkthrough in the
development guide.When do I use Zustand instead of TanStack Query?
When do I use Zustand instead of TanStack Query?
- TanStack Query: anything that came from the API. Nearly everything.
- Zustand: state the server doesn’t own. Today that’s exactly one store: the multi-step project-creation wizard.
useState is right, and for derived values use useMemo.Why don't I see prefetchQuery or HydrationBoundary anywhere?
Why don't I see prefetchQuery or HydrationBoundary anywhere?
ReactQueryStreamedHydration. Server components
render client views that call useQuery, and results stream to the browser. There is no
prefetchQuery, no HydrationBoundary, and no useSuspenseQuery in the codebase. Follow
the existing pattern rather than introducing a second one.Can I write a query key inline?
Can I write a query key inline?
*.keys.ts. An inline key like
["projects", id] won’t match projectKeys.detail(id), so mutations won’t invalidate it
and you’ll ship a stale-cache bug.Conventions
What are the file naming conventions?
What are the file naming conventions?
.component.tsx, .view.tsx,
.form.tsx, .service.ts, .keys.ts, .queries.ts, .mutations.ts, .hook.ts,
.store.ts, .schema.ts, .type.ts, .mock.ts.The codebase isn’t perfectly uniform. Shadcn-generated files in
src/shared/components/ui/ are mostly bare kebab-case, some feature hooks skip .hook.ts,
and one file is PascalCase. Follow the convention for new files; don’t rename existing ones
as a drive-by.How are imports organized?
How are imports organized?
organizeImports assist sorts them, pnpm lint fails if
they drift, and pnpm lint:write fixes it. Don’t reorder imports by hand.Why did my commit contain changes I didn't make?
Why did my commit contain changes I didn't make?
pre-commit hook runs Biome with --write on staged files and restages the
result. Formatting fixes therefore land in your commit automatically. The commit only fails
if Biome finds something it can’t fix.Why does lint reject my enum?
Why does lint reject my enum?
noEnum is on. Use a union type (type AuthProvider = "github" | "gitlab") or a const
object with as const when you need the values at runtime.Where do I change a colour or spacing token?
Where do I change a colour or spacing token?
src/app/globals.css. Tailwind v4 is configured in CSS. There is no
tailwind.config.js, and creating one has no effect.Testing and quality
How do I run the tests?
How do I run the tests?
src/mocks/handlers.mock.test.ts, covering mock API
behaviour and fixture invariants.Is there component or end-to-end testing?
Is there component or end-to-end testing?
What exactly does CI check?
What exactly does CI check?
--frozen-lockfile means a stale pnpm-lock.yaml fails the build. Commit the lockfile
when you change dependencies.Other questions
Is there dark mode?
Is there dark mode?
next-themes is installed, but no theme provider is mounted and the
stylesheet defines no dark token set. A few dark: utilities exist but aren’t reachable.
Don’t rely on them when styling.Which branch do I target?
Which branch do I target?
develop. It’s the default branch; main is the release branch.Why does /projects 404?
Why does /projects 404?
/projects index route. Project discovery lives on /. Individual projects
are at /projects/<projectId>.Where is the better-auth server configuration?
Where is the better-auth server configuration?
src/shared/lib/auth-client.ts). Route protection is done by cookie presence in
src/middleware.ts, and GET /users/me is the app’s real session source of truth.