docs: split CLAUDE.md into focused reference files
Move Common Commands to docs/COMMANDS.md and add docs/CONVENTIONS.md for frontend patterns (SWR, filters, Mantine, routing, API URLs). CLAUDE.md now only contains runtime rules and pointers.
This commit is contained in:
30
CLAUDE.md
30
CLAUDE.md
@@ -13,31 +13,9 @@ Default to Bun instead of Node.js everywhere:
|
||||
- `bunx <pkg>` not `npx`
|
||||
- Bun auto-loads `.env` — never use dotenv.
|
||||
|
||||
## Common Commands
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
bun run dev # dev server with hot reload (bun --watch src/serve.ts)
|
||||
bun run build # Vite production build
|
||||
bun run start # production server (NODE_ENV=production)
|
||||
bun run typecheck # tsc --noEmit
|
||||
bun run lint # biome check src/
|
||||
bun run lint:fix # biome check --write src/
|
||||
|
||||
# Database
|
||||
bun run db:migrate # prisma migrate dev
|
||||
bun run db:seed # seed demo data
|
||||
bun run db:generate # regenerate prisma client
|
||||
bun run db:studio # Prisma Studio GUI
|
||||
bun run db:push # push schema without migration
|
||||
|
||||
# Tests
|
||||
bun run test # all tests
|
||||
bun run test:unit # tests/unit/
|
||||
bun run test:integration # tests/integration/ — no server needed
|
||||
bun run test:e2e # tests/e2e/ — requires Lightpanda Docker
|
||||
```
|
||||
|
||||
Run a single test file: `bun test tests/integration/auth.test.ts`
|
||||
See @docs/COMMANDS.md
|
||||
|
||||
## Architecture
|
||||
|
||||
@@ -50,3 +28,7 @@ See @docs/TESTING.md
|
||||
## Dev Tools
|
||||
|
||||
See @docs/DEV_TOOLS.md
|
||||
|
||||
## Frontend Conventions
|
||||
|
||||
See @docs/CONVENTIONS.md
|
||||
|
||||
25
docs/COMMANDS.md
Normal file
25
docs/COMMANDS.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Commands
|
||||
|
||||
```bash
|
||||
bun run dev # dev server with hot reload (bun --watch src/serve.ts)
|
||||
bun run build # Vite production build
|
||||
bun run start # production server (NODE_ENV=production)
|
||||
bun run typecheck # tsc --noEmit
|
||||
bun run lint # biome check src/
|
||||
bun run lint:fix # biome check --write src/
|
||||
|
||||
# Database
|
||||
bun run db:migrate # prisma migrate dev
|
||||
bun run db:seed # seed demo data
|
||||
bun run db:generate # regenerate prisma client
|
||||
bun run db:studio # Prisma Studio GUI
|
||||
bun run db:push # push schema without migration
|
||||
|
||||
# Tests
|
||||
bun run test # all tests
|
||||
bun run test:unit # tests/unit/
|
||||
bun run test:integration # tests/integration/ — no server needed
|
||||
bun run test:e2e # tests/e2e/ — requires Lightpanda Docker
|
||||
```
|
||||
|
||||
Run a single test file: `bun test tests/integration/auth.test.ts`
|
||||
66
docs/CONVENTIONS.md
Normal file
66
docs/CONVENTIONS.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# Frontend Conventions
|
||||
|
||||
## Data Fetching
|
||||
|
||||
- **SWR** for read-only data in route components (tables, lists, charts).
|
||||
- **TanStack Query** (`useQuery`, `useMutation`) for auth state — see `src/frontend/hooks/useAuth.ts`.
|
||||
- Never mix both in the same component/page.
|
||||
- Debounce search inputs: `useDebouncedValue(search, 400)` + `useEffect` that only triggers when length >= 3 or === 0.
|
||||
|
||||
## API URL Builder
|
||||
|
||||
All URLs go through `src/frontend/config/api.ts` → `API_URLS`. Add new entries there, never inline URLs in components.
|
||||
|
||||
Desa+ endpoints are proxied via `/api/proxy/desa-plus` → `DESA_PLUS_PROXY` constant. The actual API source is at:
|
||||
`/Users/wibu04/Documents/Projects/sistem-desa-mandiri/src/app/api/monitoring/[[...slug]]/route.ts`
|
||||
|
||||
## Filters & Pagination Pattern
|
||||
|
||||
Server-side filtering — always pass filter params to the API, never filter client-side on paginated data.
|
||||
|
||||
State pattern for a filtered table page:
|
||||
```ts
|
||||
const [page, setPage] = useState(1)
|
||||
const [search, setSearch] = useState('') // raw input
|
||||
const [searchQuery, setSearchQuery] = useState('') // debounced, sent to API
|
||||
const [debouncedSearch] = useDebouncedValue(search, 400)
|
||||
|
||||
useEffect(() => {
|
||||
if (debouncedSearch.length >= 3 || debouncedSearch.length === 0) {
|
||||
setSearchQuery(debouncedSearch)
|
||||
setPage(1)
|
||||
}
|
||||
}, [debouncedSearch])
|
||||
|
||||
useEffect(() => { setPage(1) }, [filterA, filterB]) // reset page on filter change
|
||||
```
|
||||
|
||||
## Mantine Components
|
||||
|
||||
- Dark theme forced (`#242424`). Never add light-mode conditionals.
|
||||
- `radius="md"` on inputs, `radius="2xl"` on container `Paper`.
|
||||
- `className="glass"` on `Paper` cards for the frosted glass effect.
|
||||
- `size="sm"` on table inputs and selects.
|
||||
- Icons from `react-icons/tb` only — no other icon libraries.
|
||||
- `DatePickerInput` from `@mantine/dates` with `type="range"` returns `[string | null, string | null]`, not Date objects.
|
||||
|
||||
## Route Files
|
||||
|
||||
File-based routing via TanStack Router Vite plugin. Files in `src/frontend/routes/`:
|
||||
|
||||
| Pattern | Route |
|
||||
|---|---|
|
||||
| `apps.$appId.tsx` | Layout wrapper for per-app pages |
|
||||
| `apps.$appId.index.tsx` | Overview/dashboard for an app |
|
||||
| `apps.$appId.users.index.tsx` | User management |
|
||||
| `apps.$appId.logs.tsx` | Activity logs |
|
||||
| `apps.$appId.villages.tsx` | Villages layout |
|
||||
| `apps.$appId.villages.index.tsx` | Village list |
|
||||
| `apps.$appId.villages.$villageId.tsx` | Village detail |
|
||||
|
||||
`routeTree.gen.ts` is auto-generated — never edit it manually.
|
||||
|
||||
## App Registration
|
||||
|
||||
App configs (ID, menu items) live in `src/frontend/config/appMenus.ts`. Add new apps there to register them.
|
||||
Currently active app: `desa-plus`.
|
||||
Reference in New Issue
Block a user