Skip to content

Commit d03ddd7

Browse files
committed
Create CLAUDE.md
1 parent 580b1ba commit d03ddd7

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed

CLAUDE.md

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
Dafthunk is a visual workflow automation platform built on Cloudflare infrastructure (Workers, D1, R2, AI). Users create workflows by connecting 50+ node types in a visual editor (React Flow).
8+
9+
**Monorepo structure** (pnpm workspaces):
10+
- `apps/api` - Backend (Hono on Cloudflare Workers)
11+
- `apps/web` - Frontend (React 19 + React Router v7 + Vite)
12+
- `packages/types` - Shared TypeScript types
13+
- `packages/utils` - Shared utilities
14+
15+
## Development Commands
16+
17+
### Common commands
18+
```bash
19+
pnpm dev # Start all services
20+
pnpm build # Build all packages and apps
21+
pnpm typecheck # Type check all workspaces
22+
pnpm lint # Lint and type check
23+
pnpm fix # Auto-fix linting + format
24+
pnpm test # Run tests
25+
26+
# Workspace-specific (use --filter)
27+
pnpm --filter '@dafthunk/api' dev # API dev server (port 3001)
28+
pnpm --filter '@dafthunk/web' dev # Web dev server (port 3000)
29+
pnpm --filter '@dafthunk/api' test:integration # Integration tests
30+
31+
# Database migrations
32+
pnpm --filter '@dafthunk/api' db:migrate # Apply migrations locally
33+
pnpm --filter '@dafthunk/api' db:generate # Generate new migrations
34+
pnpm --filter '@dafthunk/api' db:prod:migrate # Apply to production
35+
```
36+
37+
## Architecture
38+
39+
### Backend: API (`apps/api/`)
40+
41+
**Routes** (`src/routes/`)
42+
- Organized by feature (workflows, executions, objects, etc.)
43+
- Stateless: each request is self-contained
44+
- Auth in `src/auth.ts` (JWT + API Keys)
45+
- Multi-tenant: always scope by `organizationId` from context (`c.get("organizationId")`)
46+
- Validate with Zod + `@hono/zod-validator`
47+
48+
**Database** (`src/db/`)
49+
- D1 (SQLite) + Drizzle ORM
50+
- Schema: `schema/index.ts`
51+
- Queries: `queries.ts`
52+
- Migrations: `migrations/` (generate with `drizzle-kit`)
53+
- Convention: `snake_case` in SQL, `camelCase` in TypeScript
54+
55+
**Workflow Runtime** (`src/runtime/`)
56+
- `runtime.ts` - Cloudflare Workflows for durable execution
57+
- Durable Objects manage state
58+
- `object-store.ts` - Node outputs (R2 + transient storage)
59+
- Executes nodes by graph topology
60+
61+
**Node System** (`src/nodes/`)
62+
- node types in category folders: `text/`, `image/`, `audio/`, `browser/`, `logic/`, `math/`, `javascript/`, `anthropic/`, `openai/`, `gemini/`, `3d/`, `date/`, `document/`, `email/`, `geo/`, `json/`, `net/`, `parameter/`, `rag/`
63+
- Registry: `base-node-registry.ts` and `cloudflare-node-registry.ts`
64+
- All implement common interface from `packages/types`
65+
66+
### Frontend: Web (`apps/web/`)
67+
68+
**Structure**
69+
- Pages: `src/pages/` (one file per route)
70+
- Components: `src/components/` (`ui/` = shadcn/ui, `workflow/` = React Flow editor)
71+
- Routes: `src/routes.tsx` (React Router v7)
72+
- Services: `src/services/` (API clients)
73+
74+
**Patterns**
75+
- Data fetching: SWR (consolidate related calls)
76+
- Styling: Tailwind CSS only (use `cn()` utility)
77+
- State: Avoid `useEffect`, prefer derived state
78+
79+
### Shared: Types (`packages/types/`)
80+
- Single source of truth for data structures
81+
- Backend serializes, frontend deserializes/validates
82+
- Ensures type safety across stack
83+
84+
## Design Principles
85+
86+
When writing or refactoring code:
87+
88+
### Simplify Interfaces
89+
- Export only what's necessary—hide everything else
90+
- Keep public APIs small (fewer exports = less complexity)
91+
- Use barrel exports (`index.ts`) to define module boundaries
92+
- If a function/class can't be described in one sentence, split it
93+
94+
### Manage Complexity
95+
- Push complexity into lower-level modules with simple APIs
96+
- Eliminate unnecessary state, conditionals, and abstractions
97+
- Keep related logic together; separate unrelated concerns
98+
- Depend on interfaces/types, not concrete implementations
99+
100+
### Prioritize Maintainability
101+
- Write the calling code you want first, then implement to match
102+
- After code works, refactor to simplify the interface
103+
- Use comments for *why* (design decisions, trade-offs), not *what* (code explains itself)
104+
- Front-load architectural decisions (module boundaries, data flow); defer details (naming, parameters)
105+
106+
## Code Guidelines
107+
108+
### TypeScript Style
109+
- Strict mode: never use `any` or `unknown`
110+
- Prefer `interface` over `type` for object shapes
111+
- Always use `import type` for type-only imports
112+
- Use early returns to avoid deep nesting
113+
114+
### Naming Conventions
115+
```
116+
Files: kebab-case.tsx
117+
Functions: camelCase()
118+
Hooks: useCamelCase()
119+
Event handlers: handleClick()
120+
Components: PascalCase
121+
```
122+
123+
### React (apps/web)
124+
```tsx
125+
// ✓ Correct
126+
import { Link } from 'react-router' // not react-router-dom
127+
import type { User } from '@dafthunk/types'
128+
export function MyComponent() { ... } // functional component
129+
130+
// Data fetching
131+
const { data } = useSWR(['/users', '/posts'], fetchAll) // consolidate
132+
133+
// Styling
134+
<div className={cn('base-class', isActive && 'active')} />
135+
136+
// Avoid useEffect - prefer derived state or move logic outside React
137+
```
138+
139+
### Hono API (apps/api)
140+
```ts
141+
// Routes by feature
142+
const workflows = new Hono()
143+
workflows.get('/', zValidator('query', schema), (c) => {
144+
const orgId = c.get('organizationId') // always scope by org
145+
// ...
146+
})
147+
app.route('/workflows', workflows)
148+
149+
// Database
150+
const users = sqliteTable('users', {
151+
createdAt: text('created_at'), // snake_case in DB
152+
})
153+
export type User = InferModel<typeof users>
154+
```
155+
156+
### Testing
157+
```ts
158+
// Unit tests: *.test.ts
159+
import { describe, it, expect } from 'vitest'
160+
161+
// Integration tests: *.integration.ts
162+
```

0 commit comments

Comments
 (0)