Skip to content

Latest commit

 

History

History
177 lines (140 loc) · 6.31 KB

File metadata and controls

177 lines (140 loc) · 6.31 KB

CLAUDE.md

Project Overview

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).

Monorepo structure (pnpm workspaces):

  • apps/api - Backend (Hono on Cloudflare Workers)
  • apps/web - Frontend (React 19 + React Router v7 + Vite)
  • packages/types - Shared TypeScript types
  • packages/utils - Shared utilities

Development Commands

Common commands

pnpm dev                                       # Start all services
pnpm build                                     # Build all packages and apps
pnpm typecheck                                 # Type check all workspaces
pnpm lint                                      # Lint and type check
pnpm check                                     # Auto-fix linting + format
pnpm test                                      # Run tests

# Workspace-specific (use --filter)
pnpm --filter '@dafthunk/api' dev              # API dev server (port 3001)
pnpm --filter '@dafthunk/web' dev              # Web dev server (port 3000)
pnpm --filter '@dafthunk/api' test:integration # Integration tests

# Database migrations
pnpm --filter '@dafthunk/api' db:migrate       # Apply migrations locally
pnpm --filter '@dafthunk/api' db:generate      # Generate new migrations
pnpm --filter '@dafthunk/api' db:prod:migrate  # Apply to production

Architecture

Backend: API (apps/api/)

Routes (src/routes/)

  • Organized by feature (workflows, executions, objects, etc.)
  • Stateless: each request is self-contained
  • Auth in src/auth.ts (JWT + API Keys)
  • Multi-tenant: always scope by organizationId from context (c.get("organizationId"))
  • Validate with Zod + @hono/zod-validator

Database (src/db/)

  • D1 (SQLite) + Drizzle ORM
  • Schema: schema/index.ts
  • Queries: queries.ts
  • Migrations: migrations/ (generate with drizzle-kit)
  • Convention: snake_case in SQL, camelCase in TypeScript

Workflow Runtime (src/runtime/)

  • runtime.ts - Cloudflare Workflows for durable execution
  • Durable Objects manage state
  • object-store.ts - Node outputs (R2 + transient storage)
  • Executes nodes by graph topology

Node System (packages/runtime/src/nodes/)

  • node types in category folders: text/, image/, audio/, browser/, logic/, math/, javascript/, anthropic/, openai/, gemini/, 3d/, date/, document/, email/, geo/, json/, net/, parameter/, rag/
  • Base registry: packages/runtime/src/base-node-registry.ts
  • Cloudflare registry: apps/api/src/runtime/cloudflare-node-registry.ts
  • All implement common interface from packages/types

Frontend: Web (apps/web/)

Structure

  • Pages: src/pages/ (one file per route)
  • Components: src/components/ (ui/ = shadcn/ui, workflow/ = React Flow editor)
  • Routes: src/routes.tsx (React Router v7)
  • Services: src/services/ (API clients)

Patterns

  • Data fetching: SWR (consolidate related calls)
  • Styling: Tailwind CSS only (use cn() utility)
  • State: Avoid useEffect, prefer derived state

Shared: Types (packages/types/)

  • Single source of truth for data structures
  • Backend serializes, frontend deserializes/validates
  • Ensures type safety across stack

Design Principles

When writing or refactoring code:

Simplify Interfaces

  • Export only what's necessary—hide everything else
  • Keep public APIs small (fewer exports = less complexity)
  • Use barrel exports (index.ts) to define module boundaries
  • If a function/class can't be described in one sentence, split it

Manage Complexity

  • Push complexity into lower-level modules with simple APIs
  • Eliminate unnecessary state, conditionals, and abstractions
  • Keep related logic together; separate unrelated concerns
  • Depend on interfaces/types, not concrete implementations

Prioritize Maintainability

  • Write the calling code you want first, then implement to match
  • After code works, refactor to simplify the interface
  • Use comments for why (design decisions, trade-offs), not what (code explains itself)
  • Front-load architectural decisions (module boundaries, data flow); defer details (naming, parameters)

Code Guidelines

TypeScript Style

  • Strict mode: never use any or unknown
  • Prefer interface over type for object shapes
  • Always use import type for type-only imports
  • Use early returns to avoid deep nesting

Naming Conventions

Files:          kebab-case.tsx
Functions:      camelCase()
Hooks:          useCamelCase()
Event handlers: handleClick()
Components:     PascalCase

React (apps/web)

// ✓ Correct
import { Link } from 'react-router'           // not react-router-dom
import type { User } from '@dafthunk/types'
export function MyComponent() { ... }         // functional component

// Data fetching
const { data } = useSWR(['/users', '/posts'], fetchAll)  // consolidate

// Styling
<div className={cn('base-class', isActive && 'active')} />

// Direct imports preferred - no barrel exports needed for components
// Avoid useEffect - prefer derived state or move logic outside React

Hono API (apps/api)

// Routes by feature
const workflows = new Hono()
workflows.get('/', zValidator('query', schema), (c) => {
  const orgId = c.get('organizationId')  // always scope by org
  // ...
})
app.route('/workflows', workflows)

// Database
const users = sqliteTable('users', {
  createdAt: text('created_at'),  // snake_case in DB
})
export type User = InferModel<typeof users>

// Module organization (API & packages only, not React components)
// Use barrel exports (index.ts) to control public API surface
// Export from module files, only re-export public functions in index.ts
// Keeps internal utilities accessible via direct paths but hidden from main entry

Testing

// Unit tests: *.test.ts
import { describe, it, expect } from 'vitest'

// Integration tests: *.integration.ts

Skills

Custom skills are available in .claude/skills/. Read the SKILL.md file before using.

Skill Use For
node-generator Generate new workflow nodes with implementation, tests, and registry registration
integration-generator Generate OAuth integration providers (backend, types, frontend, nodes)
template-generator Generate workflow templates with coherent node graphs and integration tests