Skip to content

Commit 403cae7

Browse files
committed
docs: refresh CLAUDE.md after the better-auth/CI merges and fix the Better Auth setup example
CLAUDE.md had drifted: typecheck:spec is green and CI-enforced (not a pre-existing backlog to ignore), app.config.ts no longer wires animations, the demo auth service wraps injectBetterAuth() instead of implementing ConvexAuthProvider directly, CI wasn't documented at all, and the architecture section omitted the testing/ and better-auth/ secondary entry points. Also fixes the README's Better Auth setup snippet, which didn't compile as written (duplicate authClient declaration, unimported environment, two file headers sharing one fence).
1 parent c0a36d7 commit 403cae7

3 files changed

Lines changed: 34 additions & 17 deletions

File tree

CLAUDE.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Use pnpm. Nx targets can be run either via the package.json scripts or `nx <targ
1818
- `pnpm check:duplication` — copy-paste detection over library + app sources (`jscpd`, config in `.jscpd.json`). Run it after adding or restructuring code; it exits non-zero when duplicated lines exceed the threshold (a ratchet set just above the current baseline). If your change trips it, extract a shared helper instead of raising the threshold; only raise the threshold deliberately, with justification. Spec files are excluded (mock scaffolding is intentionally repeated); the report's clone list tells you exactly which fragments to consolidate.
1919
- `pnpm check:deadcode` — unused files, exports, and dependencies (`knip`, config in `knip.ts`). The baseline is zero findings; keep it that way. Run it after adding/removing files, exports, or dependencies. If it flags your change, delete the dead code or remove the export from `index.ts` rather than suppressing; every entry in `knip.ts`'s ignore lists carries a comment justifying it — follow that pattern if a new exception is genuinely needed (e.g. a dependency used only by a builder at runtime).
2020
- `pnpm typecheck` — type-check the library sources with no emit (`tsc -p packages/convex-angular/tsconfig.lib.json`).
21-
- `pnpm typecheck:spec` — type-check `*.spec.ts` files (`tsconfig.spec.json`). The Jest runner transpiles specs with `isolatedModules` and does **not** type-check them, so a passing test suite can still hide spec type errors. This command surfaces a pre-existing backlog, so confirm your _changed_ specs are clean rather than expecting a fully green run.
21+
- `pnpm typecheck:spec` — type-check `*.spec.ts` files (`tsconfig.spec.json`). The Jest runner transpiles specs with `isolatedModules` and does **not** type-check them, so a passing test suite can still hide spec type errors. The suite is green and must stay that way — CI runs it unconditionally on every push and PR, so a regression here fails the build, not just a local nice-to-have.
2222
- `pnpm lint` — ESLint across all projects (`nx run-many -t lint`). Warnings are tolerated; errors block. `nx lint convex-angular --fix` auto-fixes.
2323
- `pnpm format` / `pnpm format:check` — Prettier write / check over the repo. Note: the pre-commit hook only formats _staged_ files, so a repo-wide `format:check` reports pre-existing drift in files untouched since the last config change — fix only the files you changed.
2424
- `pnpm verify:quick` — fast gate for localized changes: `typecheck``lint``check:duplication``check:deadcode`. Run a targeted test yourself (see below).
@@ -27,6 +27,8 @@ Use pnpm. Nx targets can be run either via the package.json scripts or `nx <targ
2727

2828
Git hooks (`lefthook`, config in `lefthook.yml`, installed via the `prepare` script): pre-commit auto-formats staged files with prettier (re-staging fixes) and runs `check:duplication` + `check:deadcode` in parallel (~2s); pre-push runs `nx run-many -t lint,test,build` (cheap when the Nx cache is warm). A hook failure means the commit/push was rejected — fix the findings and retry; never bypass with `LEFTHOOK=0` except mid-rebase on already-reviewed commits.
2929

30+
CI (`.github/workflows/ci.yml`) runs on every push to `main` and on every PR: `pnpm install --frozen-lockfile`, then `pnpm verify:full`, then `pnpm typecheck:spec` — both must pass. Node is pinned via `.nvmrc` (`setup-node` reads it); pnpm is pinned via the `packageManager` field (`pnpm/action-setup` reads it). Treat both gates as required, not advisory — there is no "changed files only" carve-out in CI.
31+
3032
Targeted operations:
3133

3234
- Single library test file: `nx test convex-angular --testFile=inject-query.spec.ts`
@@ -56,7 +58,7 @@ Rules that hold across the flow:
5658

5759
### The library (`packages/convex-angular`)
5860

59-
Everything is exported through `src/index.ts`. The public API is a set of standalone `inject*` functions plus `provide*` environment providers — there are no NgModules. Source prefix is `cva`.
61+
Three entry points ship: the primary `convex-angular` (`src/index.ts`), and two secondary entry points, `convex-angular/testing` and `convex-angular/better-auth`. The public API is a set of standalone `inject*` functions plus `provide*` environment providers — there are no NgModules. Source prefix is `cva`.
6062

6163
Key layers under `src/lib/`:
6264

@@ -67,6 +69,11 @@ Key layers under `src/lib/`:
6769
- `directives/auth-helpers.ts` — structural directives `*cvaAuthenticated`, `*cvaUnauthenticated`, `*cvaAuthLoading`.
6870
- `skip-token.ts``skipToken` sentinel for conditionally skipping queries.
6971

72+
Secondary entry points (separate `package.json` sub-paths, published alongside the primary entry point):
73+
74+
- `convex-angular/testing``MockConvexClient` and `provideConvexTesting()` for testing app code that depends on the library without a real Convex backend.
75+
- `convex-angular/better-auth``provideBetterAuth()` / `injectBetterAuth()` for the Better Auth integration; types the client structurally via `BetterAuthClientLike` (no dependency on `better-auth` packages); browser-only, SSR-inert (see Auth flow below).
76+
7077
Patterns that repeat across the codebase and should be preserved when adding helpers:
7178

7279
1. **Injection-context resolution.** Every public `inject*` helper runs through `runInResolvedInjectionContext(fn, options?.injectRef, ...)` (`providers/injection-context.ts`). This lets helpers be created either ambiently (inside a component/service injection context) or later from plain code by passing an `EnvironmentInjector` as `injectRef`. New helpers must follow this same wrapper so the `injectRef` escape hatch keeps working.
@@ -80,15 +87,15 @@ Patterns that repeat across the codebase and should be preserved when adding hel
8087
`provideConvexAuth()` wires any `ConvexAuthProvider` into Convex's auth sync. `inject-auth.ts` runs an effect that watches the provider's `isLoading`/`isAuthenticated`/optional `reauthVersion`, and calls `convex.setAuth(fetchToken, onChange)` or `convex.client.clearAuth()` accordingly. `injectAuth().isAuthenticated()` is true only when **both** the provider reports authenticated **and** Convex confirms the token (`backendAuthenticated`). `fetchAccessToken` returning `null` is a normal signed-out outcome, not an error; errors are surfaced through the combined `error()` signal (provider vs internal errors are sequence-ordered).
8188

8289
- `provideConvexAuthFromExisting(Type)` is the default custom path: registers `CONVEX_AUTH` with `useExisting` (not `useClass` — avoids duplicate instances) and includes `provideConvexAuth()`.
83-
- `provideClerkAuth()` / `provideAuth0Auth()` already include `provideConvexAuth()`; never register both.
90+
- `provideClerkAuth()` / `provideAuth0Auth()` / `provideBetterAuth()` (from `convex-angular/better-auth`) already include `provideConvexAuth()`; never register it separately.
8491

8592
### The demo app (`apps/frontend`)
8693

87-
Standalone-component Angular app. `app.config.ts` sets up router and animations; `app.ts` configures the Material icon registry (Material Symbols as the default font set, plus an inline GitHub SVG icon). Routes live in `app.routes.ts` and `app/routes/*.routes.ts`; demo pages under `app/pages/`.
94+
Standalone-component Angular app. `app.config.ts` sets up the router, zone change detection, and browser global error listeners; `app.ts` configures the Material icon registry (Material Symbols as the default font set, plus an inline GitHub SVG icon). Routes live in `app.routes.ts` and `app/routes/*.routes.ts`; demo pages under `app/pages/`.
8895

8996
UI uses Angular Material 3 + SCSS. The theme lives in `src/styles.scss` (`mat.theme` with the azure palette); dark mode follows the OS preference via `color-scheme: light dark` — there is no manual toggle. Shared styling lives in `src/styles/`: `_layout.scss` (mixins like `page-container`, `panel`, `panel-tone`, `eyebrow`, `code-block` — import with `@use 'layout' as *;`, resolved via `stylePreprocessorOptions.includePaths`) and `_tokens.scss` (`--app-success/warn/info-*` status colors, `light-dark()`-aware). The `demo-page-scaffold` mixin emits a standard class vocabulary (`.eyebrow`, `.error-panel`, `.warn-panel`, `.try-panel`, …) once globally from `styles.scss`; page stylesheets re-declare a class only where they diverge, and their component-scoped rules always win. Custom colors must use `var(--mat-sys-*)` or `--app-*` tokens, never hard-coded hex outside `_tokens.scss`. Each page has its own `.scss` with semantic class names (no utility classes). Shared UI components live in `app/pages/shared/` (`cva-page-header`, `cva-todo-item`, `cva-message`). Fonts (`@fontsource/roboto`, `material-symbols`) are self-hosted and wired through the `styles` array in `project.json`, hence their `ignoreDependencies` entries in `knip.ts`.
9097

91-
The demo's auth provider is `app/auth/demo-auth.service.ts`, a `ConvexAuthProvider` backed by `@convex-dev/better-auth`. The Convex backend registers the better-auth component in `src/convex/convex.config.ts`.
98+
`app/auth/demo-auth.service.ts` (`DemoAuthService`) wraps the app-level Better Auth flows — sign-in/up/out on the shared client from `app/auth/auth-client.ts`, form-error surfacing, success-URL handling — and delegates session/token state to `injectBetterAuth()` from `convex-angular/better-auth`. Auth is registered via `provideBetterAuth(demoAuthClientFactory)` in `app/routes/auth.routes.ts` (`login` and `success` routes). The Convex backend registers the better-auth component in `src/convex/convex.config.ts`.
9299

93100
**Environment variables**: the build injects `NG_APP_*` vars (see `apps/frontend/plugins/env-var-plugin.js`) into `environment.ts` at build time. Copy `.env.sample` to `.env.local` and set `CONVEX_DEPLOYMENT`, `NG_APP_CONVEX_URL`, `NG_APP_CONVEX_SITE_URL`, `NG_APP_SITE_URL`, `BETTER_AUTH_SECRET`, `SITE_URL`. The auth demo requires `NG_APP_CONVEX_SITE_URL` (the Convex `.site` origin).
94101

README.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -741,20 +741,25 @@ integration.
741741

742742
```typescript
743743
// auth-client.ts — one shared client instance for flows and the library
744-
745-
// app.config.ts
746-
import { ApplicationConfig } from '@angular/core';
747744
import { convexClient, crossDomainClient } from '@convex-dev/better-auth/client/plugins';
748745
import { createAuthClient } from 'better-auth/client';
749-
import { provideConvex } from 'convex-angular';
750-
import { provideBetterAuth } from 'convex-angular/better-auth';
751746

752-
import { authClient } from './auth-client';
747+
import { environment } from './environments/environment';
753748

754749
export const authClient = createAuthClient({
755750
baseURL: environment.convexSiteUrl,
756751
plugins: [convexClient(), crossDomainClient()],
757752
});
753+
```
754+
755+
```typescript
756+
// app.config.ts
757+
import { ApplicationConfig } from '@angular/core';
758+
import { provideConvex } from 'convex-angular';
759+
import { provideBetterAuth } from 'convex-angular/better-auth';
760+
761+
import { authClient } from './auth-client';
762+
import { environment } from './environments/environment';
758763

759764
export const appConfig: ApplicationConfig = {
760765
providers: [provideConvex(environment.convexUrl), provideBetterAuth(() => authClient)],

packages/convex-angular/README.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -741,20 +741,25 @@ integration.
741741

742742
```typescript
743743
// auth-client.ts — one shared client instance for flows and the library
744-
745-
// app.config.ts
746-
import { ApplicationConfig } from '@angular/core';
747744
import { convexClient, crossDomainClient } from '@convex-dev/better-auth/client/plugins';
748745
import { createAuthClient } from 'better-auth/client';
749-
import { provideConvex } from 'convex-angular';
750-
import { provideBetterAuth } from 'convex-angular/better-auth';
751746

752-
import { authClient } from './auth-client';
747+
import { environment } from './environments/environment';
753748

754749
export const authClient = createAuthClient({
755750
baseURL: environment.convexSiteUrl,
756751
plugins: [convexClient(), crossDomainClient()],
757752
});
753+
```
754+
755+
```typescript
756+
// app.config.ts
757+
import { ApplicationConfig } from '@angular/core';
758+
import { provideConvex } from 'convex-angular';
759+
import { provideBetterAuth } from 'convex-angular/better-auth';
760+
761+
import { authClient } from './auth-client';
762+
import { environment } from './environments/environment';
758763

759764
export const appConfig: ApplicationConfig = {
760765
providers: [provideConvex(environment.convexUrl), provideBetterAuth(() => authClient)],

0 commit comments

Comments
 (0)