RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Diff/weirdfingers-boards-cursor-rules-node-pnpm ↔ weirdfingers-boards-claude

Comparison

A · Cursor rules · weirdfingers/boardsB · CLAUDE.md · weirdfingers/boards
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections04380%
Commands05390%
Section tags311318%

What each file covers

Sections

0 shared · 4 only in A · 38 only in B
  • − Node Package Management (pnpm)
  • − Install deps
  • − Add dependencies
  • − Run scripts (workspace-aware)
  • + CLAUDE.md
  • + Project Overview
  • + Architecture
  • + Essential Commands
  • + Initial setup
  • + Development
  • + Documentation
  • + Testing
  • + Code Quality
  • + Building
  • + Docker Services
  • + Cleanup
  • + Other
  • + Development Workflow
  • + Key Design Principles
  • + Code Placement Guidelines
  • + Published Packages
  • + Package Decision Tree
  • + packages/backend (Python - Published to PyPI)
  • + ✅ Good - Generic board creation logic
  • + ❌ Bad - Application-specific business rule
  • + packages/frontend (React/TypeScript - Published to npm)
  • + apps/baseboards (Next.js - Published via Docker)
  • + packages/cli-launcher (Node.js - Published to npm)
  • + Auth Packages (Published to npm)
  • + Database Configuration
  • + Code Quality Rules
  • + Type Checking and Testing
  • + Logging
  • + SQLAlchemy Object Creation
  • + Database Migrations: `updated_at` Triggers
  • + GraphQL Schema Changes
  • + 1. Remove from backend GraphQL type
  • + 2. Search frontend for references
  • + 3. Update all found references
  • + 4. Run typecheck to catch any missed TypeScript references
  • + Git Commit Policy
  • + Task Management

Commands

0 shared · 5 only in A · 39 only in B
  • − pnpm install
  • − pnpm add <pkg>
  • − pnpm add -D <pkg>
  • − pnpm run <script>
  • − pnpm turbo <task>
  • + make install
  • + make docker-up
  • + make dev
  • + make dev-backend
  • + make dev-worker
  • + make dev-worker-watch
  • + make dev-frontend
  • + pnpm turbo dev
  • + make docs
  • + make dev-docs
  • + make build-docs
  • + make serve-docs
  • + make test
  • + make test-backend
  • + make test-frontend
  • + pnpm turbo test
  • + uv run pytest tests/
  • + make lint
  • + make lint-backend
  • + make lint-frontend
  • + make typecheck
  • + make typecheck-backend
  • + make typecheck-frontend
  • + pnpm turbo lint
  • + pnpm turbo typecheck
  • + make build
  • + make build-backend
  • + make build-frontend
  • + pnpm turbo build
  • + make docker-down
  • + make docker-logs
  • + make clean
  • + make clean-backend
  • + make clean-frontend
  • + make help
  • + turbo.json
  • + git add
  • + git commit
  • + git push

Section tags

3 shared · 1 only in A · 13 only in B
  • − code-style
  • + build
  • + test
  • + lint-format
  • + architecture
  • + types
  • + git-pr
  • + security
  • + database
  • + api
  • + ui
  • + do-not
  • + agent-behaviour
  • + docs
  •   setup
  •   dependencies
  •   monorepo

Line diff

+452 added−19 removed11 unchanged2.4% identical
weirdfingers/boards · .cursor/rules/node-pnpm.mdc
@@ −1 @@
1---
2description: Use pnpm to manage Node dependencies across the monorepo
3globs: package.json,packages/**/package.json,apps/**/package.json,*.js,*.ts,*.tsx
4---
5 
6# Node Package Management (pnpm)
7 
8Always use pnpm for Node dependency management in this repository.
9 
10- Do not use npm or yarn
11- Monorepo commands run from the repo root unless a package-specific script is needed
12- Workspace is defined via [pnpm-workspace.yaml](mdc:pnpm-workspace.yaml)
13 
14Common commands:
15 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16```bash
17# Install deps
18pnpm install
 
19 
20# Add dependencies
21pnpm add <pkg>
22pnpm add -D <pkg>
 
 
 
 
23 
24# Run scripts (workspace-aware)
25pnpm run <script>
26pnpm turbo <task>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27```
28 
29Make targets integrate pnpm where appropriate; prefer Makefile for unified flows when available.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30 
weirdfingers/boards · CLAUDE.md
@@ +1 @@
1# CLAUDE.md
 
 
 
2 
3This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4 
5## Project Overview
6 
7Boards is an open-source creative toolkit for AI-generated content (images, video, audio, text) built as a monorepo with both Python and TypeScript/JavaScript components.
 
 
8 
9## Architecture
10 
11**Monorepo Structure:**
12 
13- `/packages/` - Shared libraries (Python backend, React frontend)
14- `/apps/` - Applications (Next.js example app, Docusaurus docs)
15- `/design/` - Architecture and design documents
16 
17**Tech Stack:**
18 
19- **Backend**: Python 3.12 with SQLAlchemy + Supabase (storage and optional auth)
20- **Frontend**: React + Next.js with TypeScript
21- **Job System**: Framework-agnostic queue (RQ or Dramatiq) with workers
22- **API**: GraphQL (Strawberry) with urql client; SSE for job progress
23- **Infrastructure**: PostgreSQL, Redis (via Docker Compose)
24- **Package Management**: pnpm (Node) and uv (Python)
25- **Build System**: Turborepo for orchestrating builds
26 
27## Essential Commands
28 
29```bash
30# Initial setup
31make install # Install all dependencies (Python and Node)
32make docker-up # Start PostgreSQL and Redis
33 
34# Development
35make dev # Start all development servers (backend + frontend)
36make dev-backend # Start backend development server only
37make dev-worker # Start background worker (development)
38make dev-worker-watch # Start background worker with auto-reload (requires entr)
39make dev-frontend # Start frontend development servers only
40pnpm turbo dev # Alternative: start dev servers via Turbo
41 
42# Documentation
43make docs # Start documentation development server
44make dev-docs # Start documentation development server (same as above)
45make build-docs # Build documentation for production
46make serve-docs # Serve built documentation
47 
48# Testing
49make test # Run all tests (Python pytest + Node tests)
50make test-backend # Run backend (Python) tests only
51make test-frontend # Run frontend (Node) tests only
52pnpm turbo test # Run Node tests only via Turbo
53uv run pytest tests/ # Run Python tests in a specific package
54 
55# Code Quality
56make lint # Run all linters (ruff, pyright for Python; ESLint for JS)
57make lint-backend # Lint backend (Python) only
58make lint-frontend # Lint frontend (Node) only
59make typecheck # Run all type checking (Python and TypeScript)
60make typecheck-backend # Typecheck backend (Python) only
61make typecheck-frontend # Typecheck frontend (TypeScript) only
62pnpm turbo lint # Run Node linters only via Turbo
63pnpm turbo typecheck # Run TypeScript checking only via Turbo
64 
65# Building
66make build # Build all packages (Python and Node)
67make build-backend # Build backend (Python) only
68make build-frontend # Build frontend (Node) only
69pnpm turbo build # Build Node packages only via Turbo
70 
71# Docker Services
72make docker-up # Start PostgreSQL and Redis
73make docker-down # Stop services
74make docker-logs # View service logs
75 
76# Cleanup
77make clean # Remove all build artifacts and dependencies
78make clean-backend # Clean backend (Python) artifacts only
79make clean-frontend # Clean frontend (Node) artifacts only
80 
81# Other
82make help # Show all available Makefile commands
83```
84 
85## Development Workflow
86 
871. **Python packages**: Located in `/packages/*/` with `pyproject.toml` or `setup.py`. Installed in editable mode during setup using uv.
882. **Node packages**: Managed via pnpm workspaces. Internal packages referenced as `workspace:*`.
893. **Turbo pipeline**: Configured in `turbo.json` with build dependencies and caching.
90 
91## Key Design Principles
92 
93- **Hooks-first frontend design**: The toolkit ships React hooks, not mandatory UI components
94- **Pluggable auth**: Support for multiple auth providers via adapters (Supabase, Clerk, Auth0, custom JWT/OIDC)
95- **Observability**: Structured logs, job metrics, audit trail on credit transactions
96- **GraphQL abstraction**: Example applications MUST NOT directly import from `urql` or GraphQL operations (e.g., `@weirdfingers/boards/graphql/operations`). All GraphQL usage must be abstracted behind hooks from `@weirdfingers/boards` (e.g., `useBoards`, `useBoard`, `useGenerators`). When adding new GraphQL functionality, create a hook in `/packages/frontend/src/hooks/` first, then use that hook in example applications.
97 
98## Code Placement Guidelines
99 
100**CRITICAL**: Boards is a toolkit of reusable packages, not just an application. Most code should go into published packages (`packages/`), not the application (`apps/baseboards`).
101 
102### Published Packages
103 
104The following packages are published to public registries:
105 
106- **`packages/backend`** → PyPI (Python package for backends)
107- **`packages/frontend`** → npm as `@weirdfingers/boards` (React hooks)
108- **`packages/cli-launcher`** → npm (CLI tool for scaffolding/deployment)
109- **Auth packages** → npm as `@weirdfingers/boards-auth-*` (separate packages per provider)
110 
111### Package Decision Tree
112 
113**When adding new code, ask:**
114 
1151. **Is this specific to the Baseboards application UI/UX?**
116 
117 - YES → `apps/baseboards`
118 - NO → Continue to question 2
119 
1202. **Is this reusable toolkit functionality?**
121 
122 - NO → Reconsider the design
123 - YES → Continue to question 3
124 
1253. **Is this backend/server-side logic?**
126 
127 - YES → `packages/backend`
128 - NO → Continue to question 4
129 
1304. **Is this React/frontend logic?**
131 - YES → `packages/frontend`
132 - NO → Determine appropriate package (CLI, auth, etc.)
133 
134### packages/backend (Python - Published to PyPI)
135 
136**SHOULD contain:**
137 
138- GraphQL schema definitions (Strawberry types and resolvers)
139- SQLAlchemy models and database logic
140- Business logic and service layer
141- FastAPI/Starlette routes and middleware
142- Auth plugins/adapters (backend auth logic)
143- Job queue integration (RQ/Dramatiq workers)
144- Database migrations
145- Reusable utilities for backend development
146 
147**SHOULD NOT contain:**
148 
149- Application-specific business rules
150- Hardcoded configuration for specific deployments
151- Frontend-specific logic
152 
153**Example:**
154 
155```python
156# ✅ Good - Generic board creation logic
157@strawberry.mutation
158def create_board(self, info: Info, input: CreateBoardInput) -> Board:
159 """Create a new board - reusable across any Boards deployment"""
160 board = Boards()
161 board.title = input.title
162 board.description = input.description
163 # ... generic board creation logic
164 return board
165 
166# ❌ Bad - Application-specific business rule
167@strawberry.mutation
168def create_board(self, info: Info, input: CreateBoardInput) -> Board:
169 """Create board with hardcoded Baseboards-specific limits"""
170 if user.boards_count > 10: # Hardcoded limit specific to Baseboards app
171 raise Exception("Maximum 10 boards")
172 # ...
173```
174 
175### packages/frontend (React/TypeScript - Published to npm)
176 
177**SHOULD contain:**
178 
179- React hooks for all Boards functionality
180- GraphQL operations and fragments
181- urql client configuration and exchanges
182- TypeScript type definitions for GraphQL responses
183- Generic, unstyled React components (sparingly - favor hooks)
184- Frontend auth adapters (Supabase, Clerk integration)
185- SSE/WebSocket utilities
186- Reusable state management utilities
187 
188**MUST be framework-agnostic:**
189 
190- React only (no Next.js-specific code)
191- Should work with Remix, Vite, Create React App, etc.
192- No `next/router`, `next/navigation`, `next/image`, etc.
193 
194**Components policy:**
195 
196- Favor hooks over components
197- If shipping components, they MUST support:
198 - Arbitrary theming (no hardcoded styles)
199 - Accessibility (a11y)
200 - Internationalization (i18n)
201- When in doubt, ship a hook and let apps build their own UI
202 
203**SHOULD NOT contain:**
204 
205- Next.js-specific code
206- Styled/opinionated components
207- Application business logic
208- Direct imports that bypass hooks (apps importing from `/graphql/operations` directly)
209 
210**Example:**
211 
212```typescript
213// ✅ Good - Generic hook for any React app
214export function useBoards() {
215 const [result] = useQuery({ query: BoardsQuery });
216 return {
217 boards: result.data?.boards ?? [],
218 loading: result.fetching,
219 error: result.error,
220 };
221}
222 
223// ✅ Good - Unstyled, accessible component
224export function BoardCard({ board, className, onSelect }: BoardCardProps) {
225 return (
226 <article
227 className={className}
228 role="button"
229 aria-label={board.title}
230 onClick={() => onSelect?.(board)}
231 >
232 {/* Minimal, unstyled structure */}
233 </article>
234 );
235}
236 
237// ❌ Bad - Next.js-specific code
238import { useRouter } from "next/navigation";
239export function useBoards() {
240 const router = useRouter(); // Not framework-agnostic!
241 // ...
242}
243 
244// ❌ Bad - Styled, opinionated component
245export function BoardCard({ board }: BoardCardProps) {
246 return (
247 <div className="bg-blue-500 rounded-lg p-4 shadow-xl">
248 {/* Hardcoded Tailwind styles - should be in app */}
249 </div>
250 );
251}
252```
253 
254### apps/baseboards (Next.js - Published via Docker)
255 
256**Purpose:** Baseboards serves dual roles:
257 
2581. **Reference implementation** - demonstrates best practices for using the packages
2592. **Standalone application** - production-ready Boards instance deployable via Docker
260 
261**SHOULD contain:**
262 
263- Next.js pages, layouts, and routing
264- UI components with styling (Tailwind, Radix UI, etc.)
265- Application-specific configuration (environment variables, themes)
266- Sensible defaults that users can deploy as-is
267- Example flows demonstrating package usage
268- Generic application logic (not overly opinionated)
269 
270**SHOULD import:**
271 
272- Hooks from `@weirdfingers/boards`
273- Types from `@weirdfingers/boards`
274 
275**SHOULD NOT import:**
276 
277- Direct urql client usage (use hooks instead)
278- GraphQL operations from `@weirdfingers/boards/graphql/operations`
279- Anything that bypasses the hooks abstraction
280 
281**SHOULD NOT contain:**
282 
283- Reusable business logic (move to `packages/frontend` or `packages/backend`)
284- Hardcoded business rules that make it too opinionated
285- Backend logic (keep in `packages/backend`)
286 
287**Philosophy:** Baseboards should be both:
288 
289- Generic enough to deploy unchanged for most use cases
290- Well-structured enough to serve as a customization starting point
291 
292**Example:**
293 
294```typescript
295// ✅ Good - Uses hooks from the package
296import { useBoards, useCreateBoard } from "@weirdfingers/boards";
297 
298export function BoardsPage() {
299 const { boards, loading } = useBoards();
300 const createBoard = useCreateBoard();
301 
302 return (
303 <div className="container mx-auto">
304 {/* Baseboards-specific styled UI */}
305 {boards.map((board) => (
306 <StyledBoardCard key={board.id} board={board} />
307 ))}
308 </div>
309 );
310}
311 
312// ❌ Bad - Bypasses hooks, imports GraphQL directly
313import { useQuery } from "urql";
314import { BoardsQuery } from "@weirdfingers/boards/graphql/operations";
315 
316export function BoardsPage() {
317 const [result] = useQuery({ query: BoardsQuery }); // Should use useBoards() hook
318 // ...
319}
320 
321// ❌ Bad - Reusable logic that should be in packages/frontend
322export function useBoardValidation() {
323 // This is generic logic that other apps would need - move to packages/frontend!
324 return { validateTitle, validateDescription };
325}
326```
327 
328### packages/cli-launcher (Node.js - Published to npm)
329 
330**SHOULD contain:**
331 
332- CLI commands for project scaffolding
333- Docker deployment utilities
334- Development environment setup
335 
336**SHOULD NOT contain:**
337 
338- Application business logic
339- Backend/frontend code (import from published packages instead)
340 
341### Auth Packages (Published to npm)
342 
343**Available packages:**
344 
345- `@weirdfingers/boards-auth-supabase` - Supabase authentication provider
346- `@weirdfingers/boards-auth-clerk` - Clerk authentication provider
347- `@weirdfingers/boards-auth-jwt` - JWT authentication provider
348- `@weirdfingers/boards-auth-auth0` (placeholder) - Auth0 authentication provider
349 
350Each contains frontend auth adapter implementations for their respective providers.
351 
352## Database Configuration
353 
354Local development uses Docker Compose with:
355 
356- PostgreSQL 15 on port 5433 (user: boards, password: boards_dev, database: boards_dev)
357- Redis 7 on port 6380
358 
359## Code Quality Rules
360 
361### Type Checking and Testing
362 
363- To typecheck the backend and frontend, run `make typecheck` at the root of the project
364- To run tests for the backend and frontend, run `make test` at the root of the project
365 
366### Logging
367 
368- For backend logging, always use `@packages/backend/src/boards/logging.py` which is based on `structlog`
369- Use keyword arguments for log data, avoid f-strings
370- Never use `exc_info=True` in log statements
371 
372### SQLAlchemy Object Creation
373 
374**IMPORTANT**: When creating SQLAlchemy model instances, DO NOT pass properties as kwargs to the constructor. Instead, set properties explicitly after instantiation. This allows the type checker (pyright) to catch incorrect property names.
375 
376**Bad** (kwargs bypass type checking):
377 
378```python
379new_board = Boards(
380 tenant_id=tenant_uuid,
381 owner_id=auth_context.user_id,
382 title=input.title,
383 descritpion=input.description, # Typo won't be caught!
384)
385```
386 
387**Good** (explicit assignment catches typos):
388 
389```python
390new_board = Boards()
391new_board.tenant_id = tenant_uuid
392new_board.owner_id = auth_context.user_id
393new_board.title = input.title
394new_board.descritpion = input.description # Type checker will error!
395```
396 
397### Database Migrations: `updated_at` Triggers
398 
399All tables with an `updated_at` column have a `BEFORE UPDATE` trigger that automatically sets `updated_at = CURRENT_TIMESTAMP`. When adding a new table with an `updated_at` column, you **must** also add a trigger for it in a migration:
400 
401```python
402op.execute("""
403 CREATE TRIGGER trg_<table_name>_updated_at
404 BEFORE UPDATE ON boards.<table_name>
405 FOR EACH ROW
406 EXECUTE FUNCTION boards.update_updated_at_column();
407""")
408```
409 
410The shared trigger function `boards.update_updated_at_column()` already exists. Do **not** manually set `updated_at` in application code -- the trigger handles it.
411 
412### GraphQL Schema Changes
413 
414**CRITICAL**: When modifying GraphQL types in the backend, you MUST update the frontend in the same commit:
415 
4161. **Backend changes** in `/packages/backend/src/boards/graphql/types/`:
417 
418 - Update the Strawberry GraphQL type definition
419 - If removing/renaming fields, grep the frontend codebase first
420 
4212. **Frontend changes** that MUST be synchronized:
422 
423 - Update GraphQL fragments in `/packages/frontend/src/graphql/operations.ts`
424 - Update TypeScript interfaces in `/packages/frontend/src/hooks/`
425 - Search for any component usage in example applications
426 
4273. **Validation**: GraphQL queries that reference non-existent fields will fail at schema validation (before resolver execution), returning errors like "Cannot query field 'fieldName' on type 'TypeName'". This prevents resolvers from being called.
428 
429**Example workflow when removing a field**:
430 
431```bash
432# 1. Remove from backend GraphQL type
433# 2. Search frontend for references
434grep -r "fieldName" packages/frontend apps/
435# 3. Update all found references
436# 4. Run typecheck to catch any missed TypeScript references
437make typecheck
438```
439 
440### Git Commit Policy
441 
442**IMPORTANT**: Claude Code must NEVER commit changes to git without being explicitly instructed to do so by the user.
443 
444Claude Code should:
445 
446- Make code changes as requested
447- Run tests and verify changes
448- Show git status and explain what files have been modified
449- Suggest commit messages if helpful
450 
451But Claude Code must NOT:
452 
453- Run `git add` commands
454- Run `git commit` commands
455- Run `git push` commands
456 
457Unless the user explicitly asks for commits to be made.
458 
459**CRITICAL**: Claude Code must NEVER push to remote repositories unless explicitly instructed to commit changes, always ask the user to push manually. This prevents accidental pushes to production or shared branches.
460 
461## Task Management
462This project uses a CLI ticket system for task management. Run `tk help` when you need to use it.
463 
@@ −1 +1 @@
1−---
2−description: Use pnpm to manage Node dependencies across the monorepo
3−globs: package.json,packages/**/package.json,apps/**/package.json,*.js,*.ts,*.tsx
4−---
1+# CLAUDE.md
52  
6−# Node Package Management (pnpm)
3+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
74  
8−Always use pnpm for Node dependency management in this repository.
5+## Project Overview
96  
10−- Do not use npm or yarn
11−- Monorepo commands run from the repo root unless a package-specific script is needed
12−- Workspace is defined via [pnpm-workspace.yaml](mdc:pnpm-workspace.yaml)
7+Boards is an open-source creative toolkit for AI-generated content (images, video, audio, text) built as a monorepo with both Python and TypeScript/JavaScript components.
138  
14−Common commands:
9+## Architecture
1510  
11+**Monorepo Structure:**
12+ 
13+- `/packages/` - Shared libraries (Python backend, React frontend)
14+- `/apps/` - Applications (Next.js example app, Docusaurus docs)
15+- `/design/` - Architecture and design documents
16+ 
17+**Tech Stack:**
18+ 
19+- **Backend**: Python 3.12 with SQLAlchemy + Supabase (storage and optional auth)
20+- **Frontend**: React + Next.js with TypeScript
21+- **Job System**: Framework-agnostic queue (RQ or Dramatiq) with workers
22+- **API**: GraphQL (Strawberry) with urql client; SSE for job progress
23+- **Infrastructure**: PostgreSQL, Redis (via Docker Compose)
24+- **Package Management**: pnpm (Node) and uv (Python)
25+- **Build System**: Turborepo for orchestrating builds
26+ 
27+## Essential Commands
28+ 
1629 ```bash
17−# Install deps
18−pnpm install
30+# Initial setup
31+make install # Install all dependencies (Python and Node)
32+make docker-up # Start PostgreSQL and Redis
1933  
20−# Add dependencies
21−pnpm add <pkg>
22−pnpm add -D <pkg>
34+# Development
35+make dev # Start all development servers (backend + frontend)
36+make dev-backend # Start backend development server only
37+make dev-worker # Start background worker (development)
38+make dev-worker-watch # Start background worker with auto-reload (requires entr)
39+make dev-frontend # Start frontend development servers only
40+pnpm turbo dev # Alternative: start dev servers via Turbo
2341  
24−# Run scripts (workspace-aware)
25−pnpm run <script>
26−pnpm turbo <task>
42+# Documentation
43+make docs # Start documentation development server
44+make dev-docs # Start documentation development server (same as above)
45+make build-docs # Build documentation for production
46+make serve-docs # Serve built documentation
47+ 
48+# Testing
49+make test # Run all tests (Python pytest + Node tests)
50+make test-backend # Run backend (Python) tests only
51+make test-frontend # Run frontend (Node) tests only
52+pnpm turbo test # Run Node tests only via Turbo
53+uv run pytest tests/ # Run Python tests in a specific package
54+ 
55+# Code Quality
56+make lint # Run all linters (ruff, pyright for Python; ESLint for JS)
57+make lint-backend # Lint backend (Python) only
58+make lint-frontend # Lint frontend (Node) only
59+make typecheck # Run all type checking (Python and TypeScript)
60+make typecheck-backend # Typecheck backend (Python) only
61+make typecheck-frontend # Typecheck frontend (TypeScript) only
62+pnpm turbo lint # Run Node linters only via Turbo
63+pnpm turbo typecheck # Run TypeScript checking only via Turbo
64+ 
65+# Building
66+make build # Build all packages (Python and Node)
67+make build-backend # Build backend (Python) only
68+make build-frontend # Build frontend (Node) only
69+pnpm turbo build # Build Node packages only via Turbo
70+ 
71+# Docker Services
72+make docker-up # Start PostgreSQL and Redis
73+make docker-down # Stop services
74+make docker-logs # View service logs
75+ 
76+# Cleanup
77+make clean # Remove all build artifacts and dependencies
78+make clean-backend # Clean backend (Python) artifacts only
79+make clean-frontend # Clean frontend (Node) artifacts only
80+ 
81+# Other
82+make help # Show all available Makefile commands
2783 ```
2884  
29−Make targets integrate pnpm where appropriate; prefer Makefile for unified flows when available.
85+## Development Workflow
86+ 
87+1. **Python packages**: Located in `/packages/*/` with `pyproject.toml` or `setup.py`. Installed in editable mode during setup using uv.
88+2. **Node packages**: Managed via pnpm workspaces. Internal packages referenced as `workspace:*`.
89+3. **Turbo pipeline**: Configured in `turbo.json` with build dependencies and caching.
90+ 
91+## Key Design Principles
92+ 
93+- **Hooks-first frontend design**: The toolkit ships React hooks, not mandatory UI components
94+- **Pluggable auth**: Support for multiple auth providers via adapters (Supabase, Clerk, Auth0, custom JWT/OIDC)
95+- **Observability**: Structured logs, job metrics, audit trail on credit transactions
96+- **GraphQL abstraction**: Example applications MUST NOT directly import from `urql` or GraphQL operations (e.g., `@weirdfingers/boards/graphql/operations`). All GraphQL usage must be abstracted behind hooks from `@weirdfingers/boards` (e.g., `useBoards`, `useBoard`, `useGenerators`). When adding new GraphQL functionality, create a hook in `/packages/frontend/src/hooks/` first, then use that hook in example applications.
97+ 
98+## Code Placement Guidelines
99+ 
100+**CRITICAL**: Boards is a toolkit of reusable packages, not just an application. Most code should go into published packages (`packages/`), not the application (`apps/baseboards`).
101+ 
102+### Published Packages
103+ 
104+The following packages are published to public registries:
105+ 
106+- **`packages/backend`** → PyPI (Python package for backends)
107+- **`packages/frontend`** → npm as `@weirdfingers/boards` (React hooks)
108+- **`packages/cli-launcher`** → npm (CLI tool for scaffolding/deployment)
109+- **Auth packages** → npm as `@weirdfingers/boards-auth-*` (separate packages per provider)
110+ 
111+### Package Decision Tree
112+ 
113+**When adding new code, ask:**
114+ 
115+1. **Is this specific to the Baseboards application UI/UX?**
116+ 
117+ - YES → `apps/baseboards`
118+ - NO → Continue to question 2
119+ 
120+2. **Is this reusable toolkit functionality?**
121+ 
122+ - NO → Reconsider the design
123+ - YES → Continue to question 3
124+ 
125+3. **Is this backend/server-side logic?**
126+ 
127+ - YES → `packages/backend`
128+ - NO → Continue to question 4
129+ 
130+4. **Is this React/frontend logic?**
131+ - YES → `packages/frontend`
132+ - NO → Determine appropriate package (CLI, auth, etc.)
133+ 
134+### packages/backend (Python - Published to PyPI)
135+ 
136+**SHOULD contain:**
137+ 
138+- GraphQL schema definitions (Strawberry types and resolvers)
139+- SQLAlchemy models and database logic
140+- Business logic and service layer
141+- FastAPI/Starlette routes and middleware
142+- Auth plugins/adapters (backend auth logic)
143+- Job queue integration (RQ/Dramatiq workers)
144+- Database migrations
145+- Reusable utilities for backend development
146+ 
147+**SHOULD NOT contain:**
148+ 
149+- Application-specific business rules
150+- Hardcoded configuration for specific deployments
151+- Frontend-specific logic
152+ 
153+**Example:**
154+ 
155+```python
156+# ✅ Good - Generic board creation logic
157+@strawberry.mutation
158+def create_board(self, info: Info, input: CreateBoardInput) -> Board:
159+ """Create a new board - reusable across any Boards deployment"""
160+ board = Boards()
161+ board.title = input.title
162+ board.description = input.description
163+ # ... generic board creation logic
164+ return board
165+ 
166+# ❌ Bad - Application-specific business rule
167+@strawberry.mutation
168+def create_board(self, info: Info, input: CreateBoardInput) -> Board:
169+ """Create board with hardcoded Baseboards-specific limits"""
170+ if user.boards_count > 10: # Hardcoded limit specific to Baseboards app
171+ raise Exception("Maximum 10 boards")
172+ # ...
173+```
174+ 
175+### packages/frontend (React/TypeScript - Published to npm)
176+ 
177+**SHOULD contain:**
178+ 
179+- React hooks for all Boards functionality
180+- GraphQL operations and fragments
181+- urql client configuration and exchanges
182+- TypeScript type definitions for GraphQL responses
183+- Generic, unstyled React components (sparingly - favor hooks)
184+- Frontend auth adapters (Supabase, Clerk integration)
185+- SSE/WebSocket utilities
186+- Reusable state management utilities
187+ 
188+**MUST be framework-agnostic:**
189+ 
190+- React only (no Next.js-specific code)
191+- Should work with Remix, Vite, Create React App, etc.
192+- No `next/router`, `next/navigation`, `next/image`, etc.
193+ 
194+**Components policy:**
195+ 
196+- Favor hooks over components
197+- If shipping components, they MUST support:
198+ - Arbitrary theming (no hardcoded styles)
199+ - Accessibility (a11y)
200+ - Internationalization (i18n)
201+- When in doubt, ship a hook and let apps build their own UI
202+ 
203+**SHOULD NOT contain:**
204+ 
205+- Next.js-specific code
206+- Styled/opinionated components
207+- Application business logic
208+- Direct imports that bypass hooks (apps importing from `/graphql/operations` directly)
209+ 
210+**Example:**
211+ 
212+```typescript
213+// ✅ Good - Generic hook for any React app
214+export function useBoards() {
215+ const [result] = useQuery({ query: BoardsQuery });
216+ return {
217+ boards: result.data?.boards ?? [],
218+ loading: result.fetching,
219+ error: result.error,
220+ };
221+}
222+ 
223+// ✅ Good - Unstyled, accessible component
224+export function BoardCard({ board, className, onSelect }: BoardCardProps) {
225+ return (
226+ <article
227+ className={className}
228+ role="button"
229+ aria-label={board.title}
230+ onClick={() => onSelect?.(board)}
231+ >
232+ {/* Minimal, unstyled structure */}
233+ </article>
234+ );
235+}
236+ 
237+// ❌ Bad - Next.js-specific code
238+import { useRouter } from "next/navigation";
239+export function useBoards() {
240+ const router = useRouter(); // Not framework-agnostic!
241+ // ...
242+}
243+ 
244+// ❌ Bad - Styled, opinionated component
245+export function BoardCard({ board }: BoardCardProps) {
246+ return (
247+ <div className="bg-blue-500 rounded-lg p-4 shadow-xl">
248+ {/* Hardcoded Tailwind styles - should be in app */}
249+ </div>
250+ );
251+}
252+```
253+ 
254+### apps/baseboards (Next.js - Published via Docker)
255+ 
256+**Purpose:** Baseboards serves dual roles:
257+ 
258+1. **Reference implementation** - demonstrates best practices for using the packages
259+2. **Standalone application** - production-ready Boards instance deployable via Docker
260+ 
261+**SHOULD contain:**
262+ 
263+- Next.js pages, layouts, and routing
264+- UI components with styling (Tailwind, Radix UI, etc.)
265+- Application-specific configuration (environment variables, themes)
266+- Sensible defaults that users can deploy as-is
267+- Example flows demonstrating package usage
268+- Generic application logic (not overly opinionated)
269+ 
270+**SHOULD import:**
271+ 
272+- Hooks from `@weirdfingers/boards`
273+- Types from `@weirdfingers/boards`
274+ 
275+**SHOULD NOT import:**
276+ 
277+- Direct urql client usage (use hooks instead)
278+- GraphQL operations from `@weirdfingers/boards/graphql/operations`
279+- Anything that bypasses the hooks abstraction
280+ 
281+**SHOULD NOT contain:**
282+ 
283+- Reusable business logic (move to `packages/frontend` or `packages/backend`)
284+- Hardcoded business rules that make it too opinionated
285+- Backend logic (keep in `packages/backend`)
286+ 
287+**Philosophy:** Baseboards should be both:
288+ 
289+- Generic enough to deploy unchanged for most use cases
290+- Well-structured enough to serve as a customization starting point
291+ 
292+**Example:**
293+ 
294+```typescript
295+// ✅ Good - Uses hooks from the package
296+import { useBoards, useCreateBoard } from "@weirdfingers/boards";
297+ 
298+export function BoardsPage() {
299+ const { boards, loading } = useBoards();
300+ const createBoard = useCreateBoard();
301+ 
302+ return (
303+ <div className="container mx-auto">
304+ {/* Baseboards-specific styled UI */}
305+ {boards.map((board) => (
306+ <StyledBoardCard key={board.id} board={board} />
307+ ))}
308+ </div>
309+ );
310+}
311+ 
312+// ❌ Bad - Bypasses hooks, imports GraphQL directly
313+import { useQuery } from "urql";
314+import { BoardsQuery } from "@weirdfingers/boards/graphql/operations";
315+ 
316+export function BoardsPage() {
317+ const [result] = useQuery({ query: BoardsQuery }); // Should use useBoards() hook
318+ // ...
319+}
320+ 
321+// ❌ Bad - Reusable logic that should be in packages/frontend
322+export function useBoardValidation() {
323+ // This is generic logic that other apps would need - move to packages/frontend!
324+ return { validateTitle, validateDescription };
325+}
326+```
327+ 
328+### packages/cli-launcher (Node.js - Published to npm)
329+ 
330+**SHOULD contain:**
331+ 
332+- CLI commands for project scaffolding
333+- Docker deployment utilities
334+- Development environment setup
335+ 
336+**SHOULD NOT contain:**
337+ 
338+- Application business logic
339+- Backend/frontend code (import from published packages instead)
340+ 
341+### Auth Packages (Published to npm)
342+ 
343+**Available packages:**
344+ 
345+- `@weirdfingers/boards-auth-supabase` - Supabase authentication provider
346+- `@weirdfingers/boards-auth-clerk` - Clerk authentication provider
347+- `@weirdfingers/boards-auth-jwt` - JWT authentication provider
348+- `@weirdfingers/boards-auth-auth0` (placeholder) - Auth0 authentication provider
349+ 
350+Each contains frontend auth adapter implementations for their respective providers.
351+ 
352+## Database Configuration
353+ 
354+Local development uses Docker Compose with:
355+ 
356+- PostgreSQL 15 on port 5433 (user: boards, password: boards_dev, database: boards_dev)
357+- Redis 7 on port 6380
358+ 
359+## Code Quality Rules
360+ 
361+### Type Checking and Testing
362+ 
363+- To typecheck the backend and frontend, run `make typecheck` at the root of the project
364+- To run tests for the backend and frontend, run `make test` at the root of the project
365+ 
366+### Logging
367+ 
368+- For backend logging, always use `@packages/backend/src/boards/logging.py` which is based on `structlog`
369+- Use keyword arguments for log data, avoid f-strings
370+- Never use `exc_info=True` in log statements
371+ 
372+### SQLAlchemy Object Creation
373+ 
374+**IMPORTANT**: When creating SQLAlchemy model instances, DO NOT pass properties as kwargs to the constructor. Instead, set properties explicitly after instantiation. This allows the type checker (pyright) to catch incorrect property names.
375+ 
376+**Bad** (kwargs bypass type checking):
377+ 
378+```python
379+new_board = Boards(
380+ tenant_id=tenant_uuid,
381+ owner_id=auth_context.user_id,
382+ title=input.title,
383+ descritpion=input.description, # Typo won't be caught!
384+)
385+```
386+ 
387+**Good** (explicit assignment catches typos):
388+ 
389+```python
390+new_board = Boards()
391+new_board.tenant_id = tenant_uuid
392+new_board.owner_id = auth_context.user_id
393+new_board.title = input.title
394+new_board.descritpion = input.description # Type checker will error!
395+```
396+ 
397+### Database Migrations: `updated_at` Triggers
398+ 
399+All tables with an `updated_at` column have a `BEFORE UPDATE` trigger that automatically sets `updated_at = CURRENT_TIMESTAMP`. When adding a new table with an `updated_at` column, you **must** also add a trigger for it in a migration:
400+ 
401+```python
402+op.execute("""
403+ CREATE TRIGGER trg_<table_name>_updated_at
404+ BEFORE UPDATE ON boards.<table_name>
405+ FOR EACH ROW
406+ EXECUTE FUNCTION boards.update_updated_at_column();
407+""")
408+```
409+ 
410+The shared trigger function `boards.update_updated_at_column()` already exists. Do **not** manually set `updated_at` in application code -- the trigger handles it.
411+ 
412+### GraphQL Schema Changes
413+ 
414+**CRITICAL**: When modifying GraphQL types in the backend, you MUST update the frontend in the same commit:
415+ 
416+1. **Backend changes** in `/packages/backend/src/boards/graphql/types/`:
417+ 
418+ - Update the Strawberry GraphQL type definition
419+ - If removing/renaming fields, grep the frontend codebase first
420+ 
421+2. **Frontend changes** that MUST be synchronized:
422+ 
423+ - Update GraphQL fragments in `/packages/frontend/src/graphql/operations.ts`
424+ - Update TypeScript interfaces in `/packages/frontend/src/hooks/`
425+ - Search for any component usage in example applications
426+ 
427+3. **Validation**: GraphQL queries that reference non-existent fields will fail at schema validation (before resolver execution), returning errors like "Cannot query field 'fieldName' on type 'TypeName'". This prevents resolvers from being called.
428+ 
429+**Example workflow when removing a field**:
430+ 
431+```bash
432+# 1. Remove from backend GraphQL type
433+# 2. Search frontend for references
434+grep -r "fieldName" packages/frontend apps/
435+# 3. Update all found references
436+# 4. Run typecheck to catch any missed TypeScript references
437+make typecheck
438+```
439+ 
440+### Git Commit Policy
441+ 
442+**IMPORTANT**: Claude Code must NEVER commit changes to git without being explicitly instructed to do so by the user.
443+ 
444+Claude Code should:
445+ 
446+- Make code changes as requested
447+- Run tests and verify changes
448+- Show git status and explain what files have been modified
449+- Suggest commit messages if helpful
450+ 
451+But Claude Code must NOT:
452+ 
453+- Run `git add` commands
454+- Run `git commit` commands
455+- Run `git push` commands
456+ 
457+Unless the user explicitly asks for commits to be made.
458+ 
459+**CRITICAL**: Claude Code must NEVER push to remote repositories unless explicitly instructed to commit changes, always ask the user to push manually. This prevents accidental pushes to production or shared branches.
460+ 
461+## Task Management
462+This project uses a CLI ticket system for task management. Run `tk help` when you need to use it.
30463  
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack