- Add test:unit, test:cov, test:unit:cov to README scripts table - Add Running Tests section to CLAUDE.md recommending test:cov Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
86 lines
3.1 KiB
Markdown
86 lines
3.1 KiB
Markdown
# Claude Code Notes
|
|
|
|
## Running Tests
|
|
|
|
Use `bun run test:cov` to run all tests with coverage. This runs both unit tests and e2e tests that require a database connection.
|
|
|
|
- `bun run test:cov` - Run all tests with coverage (preferred)
|
|
- `bun run test:unit:cov` - Run only unit tests with coverage (no database required)
|
|
|
|
## Database Scripts
|
|
|
|
Use the wrapper scripts instead of running dbmate directly:
|
|
- `./scripts/db-dump` - Dump schema without random `\restrict` tokens
|
|
- `./scripts/db-migrate` - Run migrations and dump clean schema
|
|
|
|
PostgreSQL 17.6+ adds random `\restrict`/`\unrestrict` lines to pg_dump output (CVE-2025-8714 fix), causing schema.sql to show as changed on every dump. These scripts strip those lines.
|
|
|
|
## Development Server
|
|
|
|
Before starting the dev server, check if it's already running:
|
|
- Use `lsof -i :6827` or check for existing background tasks
|
|
- The dev server runs on port 6827 (may fall back to 6828 if port is in use)
|
|
- Start with `bun run --cwd apps/publisher-dashboard dev` or `devenv up`
|
|
|
|
## Pull Requests
|
|
|
|
This repo uses Gitea (git.rev.iq) with the `tea` CLI for pull requests:
|
|
- Use the `/gitea` skill when creating PRs
|
|
- tea 0.10.1 is pinned in `nix/tea.nix` (0.11.x has TTY bugs)
|
|
- Always specify `-r igm/publisher-dashboard` flag (SSH remote auto-detection doesn't work)
|
|
|
|
## macOS sed Syntax
|
|
|
|
macOS uses BSD sed which differs from GNU sed:
|
|
- In-place edit requires empty string for backup: `sed -i '' 's/old/new/g' file`
|
|
- GNU sed (Linux): `sed -i 's/old/new/g' file`
|
|
- Use `|` as delimiter when patterns contain `/`: `sed -i '' 's|old/path|new/path|g' file`
|
|
- For multiple files: `for f in *.txt; do sed -i '' 's/old/new/g' "$f"; done`
|
|
|
|
## SvelteKit resolve() Usage
|
|
|
|
Use `resolve()` from `$app/paths` for type-safe navigation. The patterns are:
|
|
|
|
### Static routes - use resolve() directly
|
|
```svelte
|
|
href={resolve("/auth/login")}
|
|
href={resolve("/dashboard")}
|
|
```
|
|
|
|
### Dynamic routes - use two-argument form
|
|
```svelte
|
|
href={resolve("/dashboard/[slug]", { slug: orgSlug })}
|
|
href={resolve("/account/org-invites/[inviteId]", { inviteId: String(invite.id) })}
|
|
```
|
|
|
|
### Login redirects - use gotoLogin helper
|
|
For redirecting to login with a return URL, use the helper from `$lib/utils/navigation`:
|
|
```typescript
|
|
import { gotoLogin } from "$lib/utils/navigation";
|
|
|
|
gotoLogin(page.url.pathname);
|
|
```
|
|
This helper uses resolve() internally and handles the query string correctly.
|
|
|
|
### Navigation arrays - use `as const` with route patterns
|
|
For type-safe navigation arrays, define routes as literal strings with `as const`:
|
|
```typescript
|
|
const navItems = [
|
|
{ route: "/dashboard/[slug]/settings", icon: Settings, label: "General" },
|
|
{ route: "/dashboard/[slug]/settings/members", icon: Users, label: "Members" },
|
|
] as const;
|
|
```
|
|
Then use resolve with params:
|
|
```svelte
|
|
{#each navItems as item (item.route)}
|
|
<a href={resolve(item.route, { slug })}>
|
|
{/each}
|
|
```
|
|
|
|
### Runtime strings - skip resolve, use eslint-disable
|
|
When paths are fully dynamic (e.g., server-provided redirects), skip resolve:
|
|
```typescript
|
|
// eslint-disable-next-line svelte/no-navigation-without-resolve
|
|
goto(redirectUrl);
|
|
```
|