Browse Source

docs: map existing codebase

- STACK.md - Technologies and dependencies
- ARCHITECTURE.md - System design and patterns
- STRUCTURE.md - Directory layout
- CONVENTIONS.md - Code style and patterns
- TESTING.md - Test structure
- INTEGRATIONS.md - External services
- CONCERNS.md - Technical debt and issues
handoff-20260429-1057
shrimbly 6 months ago
parent
commit
0c9e75717a
  1. 149
      .planning/codebase/ARCHITECTURE.md
  2. 126
      .planning/codebase/CONCERNS.md
  3. 154
      .planning/codebase/CONVENTIONS.md
  4. 114
      .planning/codebase/INTEGRATIONS.md
  5. 81
      .planning/codebase/STACK.md
  6. 171
      .planning/codebase/STRUCTURE.md
  7. 180
      .planning/codebase/TESTING.md

149
.planning/codebase/ARCHITECTURE.md

@ -0,0 +1,149 @@
# Architecture
**Analysis Date:** 2026-01-09
## Pattern Overview
**Overall:** Monolithic Full-Stack Single-Page Application
**Key Characteristics:**
- Client-driven architecture with Zustand state management
- Next.js App Router for both UI and API routes
- Node-based visual workflow editor pattern
- Local-first with optional cloud AI services
## Layers
**Presentation Layer (React Components):**
- Purpose: UI rendering, user interaction, state binding
- Contains: Node components, canvas, modals, toolbars
- Location: `src/components/`
- Depends on: Store layer for state
- Used by: Root page component
**State Management Layer (Zustand):**
- Purpose: Central application state and business logic
- Contains: Workflow state, node/edge CRUD, execution logic
- Location: `src/store/workflowStore.ts`, `src/store/annotationStore.ts`
- Depends on: API layer for external calls
- Used by: All components via `useWorkflowStore()` hook
**API Layer (Next.js Routes):**
- Purpose: Server-side processing, external API calls
- Contains: Image generation, LLM, file operations
- Location: `src/app/api/`
- Depends on: External services (Gemini, OpenAI)
- Used by: Store layer via fetch calls
**Type System Layer:**
- Purpose: Single source of truth for TypeScript interfaces
- Contains: Node types, data interfaces, handle types
- Location: `src/types/index.ts`, `src/types/quickstart.ts`
- Depends on: Nothing
- Used by: All layers
**Utility Layer:**
- Purpose: Reusable business logic
- Contains: Cost calculation, grid splitting, image storage
- Location: `src/utils/`
- Depends on: Node.js built-ins
- Used by: Store and API layers
## Data Flow
**Workflow Execution Flow:**
1. User triggers execution (Cmd/Ctrl+Enter) via `FloatingActionBar` or `WorkflowCanvas`
2. `executeWorkflow()` called from Zustand store
3. Topological sort on node graph (dependency ordering)
4. For each node in order:
- Check if in locked group → skip if locked
- Check for pause edges → pause if found
- `getConnectedInputs(nodeId)` retrieves upstream data
- Execute node-specific logic (API call or transform)
5. `updateNodeData()` updates status (loading → complete/error)
6. `addIncurredCost()` tracks generation costs
**Node Data Flow via getConnectedInputs():**
- Image sources: `imageInput.data.image`, `annotation.data.outputImage`, `nanoBanana.data.outputImage`
- Text sources: `prompt.data.prompt`, `llmGenerate.data.outputText`
- Returns: `{ images: string[], text: string | null }`
**State Management:**
- Client-side: Zustand store with React subscriptions
- File-based: Workflow JSON saved to disk
- LocalStorage: Settings, costs, configs
## Key Abstractions
**Node System:**
- Purpose: Encapsulate workflow step types
- Examples: `ImageInputNode`, `NanoBananaNode`, `PromptNode`, `OutputNode`
- Pattern: BaseNode wrapper with type-specific content
- Location: `src/components/nodes/`
**Edge System:**
- Purpose: Define connections between nodes
- Examples: `EditableEdge` (with controls), `ReferenceEdge` (dashed)
- Pattern: React Flow edge components
- Location: `src/components/edges/`
**Group System:**
- Purpose: Logical node grouping with lock state
- Pattern: Groups stored in `Record<string, NodeGroup>`
- Behavior: Locked groups skip execution
**Store Actions:**
- Purpose: State mutations and async operations
- Examples: `addNode()`, `updateNodeData()`, `executeWorkflow()`
- Pattern: Zustand actions with `get()` and `set()`
## Entry Points
**Main Client Entry:**
- Location: `src/app/page.tsx`
- Triggers: Browser navigation to root URL
- Responsibilities: Initialize app, render WorkflowCanvas
**Root Layout:**
- Location: `src/app/layout.tsx`
- Triggers: All page renders
- Responsibilities: Metadata, global providers, Toast
**API Routes:**
- Location: `src/app/api/[route]/route.ts`
- Triggers: Fetch calls from client
- Responsibilities: Server-side processing, external API calls
## Error Handling
**Strategy:** Try/catch at boundaries with status updates
**Patterns:**
- API routes return `{ success, error, data }` JSON
- Node execution updates `status: 'error'` with error message
- Store catches async errors and updates node state
- Logging captures errors for debugging
## Cross-Cutting Concerns
**Logging:**
- Client: `src/utils/logger.ts` with session tracking
- Server: `src/utils/logger-server.ts`
- Categories: workflow, node, api, file, validation
**Validation:**
- Connection validation in `WorkflowCanvas.tsx` (`isValidConnection()`)
- Workflow validation in `workflowStore.ts` (`validateWorkflow()`)
- Quickstart validation in `src/lib/quickstart/validation.ts`
**Cost Tracking:**
- Calculation: `src/utils/costCalculator.ts`
- Storage: localStorage per workflow
- Display: `CostIndicator` component
---
*Architecture analysis: 2026-01-09*
*Update when major patterns change*

126
.planning/codebase/CONCERNS.md

@ -0,0 +1,126 @@
# Codebase Concerns
**Analysis Date:** 2026-01-09
## Tech Debt
**Large Monolithic Store File:**
- Issue: `src/store/workflowStore.ts` is 2,027 lines with mixed concerns
- Files: `src/store/workflowStore.ts`
- Why: Rapid development, all logic centralized for convenience
- Impact: Difficult to test, hard to navigate, violates single responsibility
- Fix approach: Split into `workflowActions.ts`, `workflowExecution.ts`, `workflowPersistence.ts`
**Silent Log Failures:**
- Issue: Fetch calls to `/api/logs` have `.catch()` with only console.error
- Files: `src/store/workflowStore.ts` (lines 1071-1082, 1327-1333, 1345-1351, 1700-1706)
- Why: Non-critical logging shouldn't block execution
- Impact: Silent failures, no user visibility into logging issues
- Fix approach: Add retry logic or toast notifications
## Known Bugs
**None Identified:**
- No TODO/FIXME comments indicating known bugs found in codebase scan
- Application appears stable based on code review
## Security Considerations
**Shell Command Execution:**
- Risk: `browse-directory/route.ts` executes osascript/PowerShell commands
- Files: `src/app/api/browse-directory/route.ts` (lines 19-21, 74-77)
- Current mitigation: Commands are hardcoded (not user input)
- Recommendations: Validate returned paths with `path.resolve()`, use `execFile` instead of `exec`
**Unvalidated Base64 Processing:**
- Risk: Large/malformed base64 strings could cause memory issues
- Files: `src/app/api/generate/route.ts` (line 74), `src/app/api/save-generation/route.ts`
- Current mitigation: None - Buffer.from() called on any size input
- Recommendations: Add size validation before processing (e.g., 10MB limit)
**API Keys in Environment:**
- Risk: Low - standard practice for API keys
- Files: `.env.local` (gitignored), `.env.example` (documented)
- Current mitigation: .gitignore includes .env.local
- Recommendations: Ensure .env.local never committed
## Performance Bottlenecks
**Synchronous localStorage Operations:**
- Problem: localStorage.getItem/setItem called synchronously during state updates
- Files: `src/store/workflowStore.ts` (lines 251, 273, 290, 305, 314, 320)
- Measurement: Not measured, but could block on large workflows
- Cause: Simple implementation for persistence
- Improvement path: Consider IndexedDB for large datasets, add debouncing
**Deep Cloning with JSON:**
- Problem: `JSON.parse(JSON.stringify())` used for cloning
- Files: `src/store/workflowStore.ts` (line 508)
- Measurement: Not measured
- Cause: Simple solution for deep cloning
- Improvement path: Use `structuredClone()` for better performance
## Fragile Areas
**Workflow Execution Pipeline:**
- Files: `src/store/workflowStore.ts` (executeWorkflow, lines 815-1356)
- Why fragile: 500+ lines of complex state management with topological sort
- Common failures: Edge cases with pause edges, group locking, error recovery
- Safe modification: Split into smaller functions, add unit tests first
- Test coverage: None - HIGH PRIORITY gap
**Connection Validation:**
- Files: `src/components/WorkflowCanvas.tsx` (isValidConnection)
- Why fragile: Type matching logic affects entire workflow
- Common failures: Invalid connections accepted or valid connections rejected
- Safe modification: Review handle type definitions in `src/types/index.ts`
- Test coverage: None
## Scaling Limits
**Workflow Size:**
- Current capacity: Unknown - no explicit limits
- Limit: Browser memory for large node graphs with many images
- Symptoms at limit: Slow rendering, memory pressure
- Scaling path: External image storage (already implemented), virtualization for node list
## Dependencies at Risk
**No Critical Risks Identified:**
- All dependencies appear actively maintained
- React 19, Next.js 16, TypeScript 5.9 are current versions
- @xyflow/react actively maintained
## Missing Critical Features
**No Tests for Critical Code:**
- Problem: Workflow execution logic untested
- Files: `src/store/workflowStore.ts`, `src/app/api/**`
- Current workaround: Manual testing only
- Blocks: Safe refactoring, confidence in changes
- Implementation complexity: Medium - need to mock API calls
## Test Coverage Gaps
**Workflow Execution:**
- What's not tested: `executeWorkflow()`, `getConnectedInputs()`, node-specific execution
- Risk: Bugs in core functionality not caught until runtime
- Priority: High
- Difficulty to test: Medium - requires mocking API calls and store setup
**API Routes:**
- What's not tested: All routes in `src/app/api/**`
- Risk: Server-side bugs not caught
- Priority: Medium
- Difficulty to test: Medium - need request/response mocking
**React Components:**
- What's not tested: All components in `src/components/**`
- Risk: UI bugs not caught
- Priority: Low - visual testing manual
- Difficulty to test: Medium - need React Testing Library setup
---
*Concerns audit: 2026-01-09*
*Update as issues are fixed or new ones discovered*

154
.planning/codebase/CONVENTIONS.md

@ -0,0 +1,154 @@
# Coding Conventions
**Analysis Date:** 2026-01-09
## Naming Patterns
**Files:**
- PascalCase for components: `WorkflowCanvas.tsx`, `BaseNode.tsx`, `CostDialog.tsx`
- camelCase for utilities: `costCalculator.ts`, `gridSplitter.ts`, `imageStorage.ts`
- kebab-case for API routes: `save-generation/`, `browse-directory/`
- `*.test.ts` for test files, colocated in `__tests__/` directories
**Functions:**
- camelCase for all functions: `executeWorkflow()`, `updateNodeData()`, `calculateGenerationCost()`
- No special prefix for async functions
- `handle*` for event handlers: `handleChange`, `handleOpenModal`, `handleSubmit`
**Variables:**
- camelCase for variables: `nodeData`, `selectedNodes`, `isModalOpen`
- UPPER_SNAKE_CASE for constants: `PRICING`, `COMMON_ASPECT_RATIOS`, `MODEL_MAP`
- No underscore prefix for private members
**Types:**
- PascalCase for interfaces, no I prefix: `WorkflowNode`, `NodeType`, `BaseNodeData`
- PascalCase for type aliases: `WorkflowNodeData`, `AspectRatio`, `NodeStatus`
- Node data types: `{NodeName}NodeData` (e.g., `ImageInputNodeData`, `NanoBananaNodeData`)
## Code Style
**Formatting:**
- 2-space indentation
- Double quotes for strings: `"use client"`, `"text"`
- Semicolons required
- No Prettier config (uses IDE defaults)
**Linting:**
- Next.js built-in ESLint via `npm run lint`
- No custom `.eslintrc` file
- TypeScript strict mode enabled in `tsconfig.json`
## Import Organization
**Order:**
1. React/framework imports: `import { useState } from "react"`
2. External packages: `import { Handle, Position } from "@xyflow/react"`
3. Internal modules with path alias: `import { useWorkflowStore } from "@/store/workflowStore"`
4. Type imports: `import { PromptNodeData } from "@/types"`
**Grouping:**
- Blank line between groups
- Related imports grouped together
**Path Aliases:**
- `@/*` maps to `src/*` (configured in `tsconfig.json`)
- Always use alias for internal imports
## Error Handling
**Patterns:**
- Try/catch at API route boundaries
- Status field updates for async operations: `status: 'loading' | 'complete' | 'error'`
- Error messages stored in node data for display
**API Routes:**
```typescript
return NextResponse.json({ success: true, data });
return NextResponse.json({ success: false, error: "message" }, { status: 500 });
```
**Store Actions:**
- Update node status on error
- Log errors for debugging
- Catch and handle async errors
## Logging
**Framework:**
- Custom logger in `src/utils/logger.ts`
- Session-based with unique IDs
- Console output in development
**Patterns:**
- Structured logging: `logger.info(category, message, context)`
- Categories: `workflow`, `node`, `api`, `file`, `validation`
- Sanitize sensitive data (truncate prompts, remove image data)
## Comments
**When to Comment:**
- Explain complex algorithms (e.g., topological sort in execution)
- Document connection validation rules
- Clarify non-obvious business logic
**JSDoc/TSDoc:**
- Used for public utility functions
- Include `@param`, `@returns` tags
- Example:
```typescript
/**
* Generate a unique image ID for external storage
*/
export function generateImageId(): string { ... }
```
**TODO Comments:**
- Format: `// TODO: description`
- Found sparingly in codebase
## Function Design
**Size:**
- Most functions under 50 lines
- Exception: `executeWorkflow()` is large (~500 lines) - candidate for splitting
**Parameters:**
- Use destructuring for component props: `{ id, data, selected }`
- Options object for complex parameters
**Return Values:**
- Explicit returns
- Return early for guard clauses
- API routes return consistent `{ success, data/error }` shape
## Module Design
**Exports:**
- Named exports preferred
- Default exports for React components (optional)
- Barrel exports via `index.ts` for component directories
**Store Pattern:**
- Single large Zustand store (`workflowStore.ts`)
- Actions defined inline with state
- Selectors via `useWorkflowStore((state) => state.property)`
## React Patterns
**Client Directive:**
- `"use client"` at top of client components
- Server components by default in App Router
**Hooks:**
- `useCallback` for memoized handlers
- `useState` for local component state
- `useWorkflowStore` for global state
**Modals:**
- Use `createPortal` to render outside React Flow stacking context
- Track modal count in store to prevent keyboard shortcuts
---
*Convention analysis: 2026-01-09*
*Update when patterns change*

114
.planning/codebase/INTEGRATIONS.md

@ -0,0 +1,114 @@
# External Integrations
**Analysis Date:** 2026-01-09
## APIs & External Services
**AI Image Generation - Google Gemini:**
- SDK/Client: `@google/genai` 1.30.0 - `package.json`
- Route: `src/app/api/generate/route.ts` (5-minute timeout)
- Models: `gemini-2.5-flash-image`, `gemini-3-pro-image-preview`
- Internal names: `nano-banana`, `nano-banana-pro`
- Auth: `GEMINI_API_KEY` env var
- Features: Aspect ratio, resolution (2K/4K), Google Search tool
**AI Text Generation - Google Gemini:**
- Route: `src/app/api/llm/route.ts` (1-minute timeout)
- Models: `gemini-2.5-flash`, `gemini-3-flash-preview`, `gemini-3-pro-preview`
- Auth: `GEMINI_API_KEY` env var
- Features: Temperature, max tokens, multimodal (text + images)
**AI Text Generation - OpenAI (Optional):**
- Route: `src/app/api/llm/route.ts`
- Models: `gpt-4.1-mini`, `gpt-4.1-nano`
- Endpoint: `https://api.openai.com/v1/chat/completions`
- Auth: `OPENAI_API_KEY` env var (optional)
- Features: Temperature, max tokens, multimodal support
## Data Storage
**File System (Server-side):**
- Workflow JSON files - `src/app/api/workflow/route.ts`
- Generated images as PNG - `src/app/api/save-generation/route.ts`
- Auto-creates `inputs/` and `generations/` subdirectories
- Uses `fs/promises` for async file operations
**LocalStorage (Client-side):**
- `node-banana-workflow-configs` - Project metadata and file paths
- `node-banana-workflow-costs` - Cost tracking per workflow
- `node-banana-nanoBanana-defaults` - Sticky generation settings
- Reference: `src/store/workflowStore.ts`
**Caching:**
- None (all database queries, no Redis)
## Authentication & Identity
**Auth Provider:**
- None - Local-first application
- API keys stored in environment variables only
## Monitoring & Observability
**Custom Logging:**
- Logger: `src/utils/logger.ts` (client), `src/utils/logger-server.ts` (server)
- Session-based logging with unique session IDs
- Structured JSON format with timestamps
- Categories: workflow, node execution, API calls, file operations
- Privacy: Truncates prompts (200 chars), sanitizes image data
- Server persistence: `src/app/api/logs/route.ts`
- Rotation: Keeps last 10 sessions
**Error Tracking:**
- Console logging only (no Sentry/external service)
**Analytics:**
- None
## CI/CD & Deployment
**Hosting:**
- Local development primary use case
- Compatible with Vercel for production deployment
**CI Pipeline:**
- None configured (no GitHub Actions workflows found)
## Environment Configuration
**Development:**
- Required: `GEMINI_API_KEY`
- Optional: `OPENAI_API_KEY`
- Secrets location: `.env.local` (gitignored)
- Reference: `.env.example`
**Production:**
- Same env vars as development
- No staging environment configured
## Webhooks & Callbacks
**Incoming:**
- None
**Outgoing:**
- None
## API Timeout Configuration
| Route | Timeout | Purpose |
|-------|---------|---------|
| `/api/generate` | 5 min | Image generation via Gemini |
| `/api/llm` | 1 min | Text generation (Google/OpenAI) |
| `/api/workflow` | Default | Save/load workflow files |
| Other routes | Default | Various operations |
## Request Body Size Limits
- Server Actions body limit: 50MB - `next.config.ts`
- Supports large image payloads in workflows
---
*Integration audit: 2026-01-09*
*Update when adding/removing external services*

81
.planning/codebase/STACK.md

@ -0,0 +1,81 @@
# Technology Stack
**Analysis Date:** 2026-01-09
## Languages
**Primary:**
- TypeScript 5.9.3 - All application code (`package.json`, `tsconfig.json`)
**Secondary:**
- JavaScript (JSX/TSX) - React components throughout `src/`
- CSS (Tailwind) - `src/app/globals.css`, `postcss.config.mjs`
## Runtime
**Environment:**
- Node.js 18+ - Referenced in README, no explicit .nvmrc
- Next.js 16 App Router - Server-side rendering and API routes
- React 19.2.0 - Client-side rendering
**Package Manager:**
- npm - Primary package manager
- Lockfile: `package-lock.json` present
## Frameworks
**Core:**
- Next.js 16.0.6 - Full-stack web framework with App Router (`next.config.ts`)
- React 19.2.0 - UI framework
- @xyflow/react 12.9.3 - Node-based visual editor / React Flow canvas
**Testing:**
- Vitest 4.0.16 - Unit testing framework (`vitest.config.ts`)
- @vitest/coverage-v8 4.0.16 - V8 coverage provider
**Build/Dev:**
- TypeScript 5.9.3 - Static type checking
- Turbopack - Rust-based bundler (enabled in `next.config.ts`)
- PostCSS 8.5.6 - CSS preprocessor with Autoprefixer 10.4.22
- Tailwind CSS 4.1.17 - Utility-first CSS framework
## Key Dependencies
**Critical:**
- `@xyflow/react` 12.9.3 - Node editor canvas (`src/components/WorkflowCanvas.tsx`)
- `zustand` 5.0.9 - State management (`src/store/workflowStore.ts`)
- `@google/genai` 1.30.0 - Google Gemini AI SDK (`src/app/api/generate/route.ts`)
- `konva` 10.0.12 + `react-konva` 19.2.1 - Canvas drawing (`src/components/nodes/AnnotationNode.tsx`)
**Infrastructure:**
- `jszip` 3.10.1 - ZIP file compression for workflow export
- `next` 16.0.6 - App routing and server functions
## Configuration
**Environment:**
- `.env.local` files for secrets (gitignored)
- Required: `GEMINI_API_KEY`
- Optional: `OPENAI_API_KEY`
**Build:**
- `tsconfig.json` - TypeScript config with path aliases (`@/*` → `src/*`)
- `next.config.ts` - Next.js with Turbopack, 50MB body size limit
- `postcss.config.mjs` - PostCSS with Tailwind CSS
- `vitest.config.ts` - Vitest with V8 coverage
## Platform Requirements
**Development:**
- macOS/Linux/Windows (any platform with Node.js 18+)
- No external dependencies beyond npm
**Production:**
- Designed for local execution (desktop app workflow)
- Can deploy to Vercel or similar Next.js hosting
- Requires access to Google Gemini API
---
*Stack analysis: 2026-01-09*
*Update after major dependency changes*

171
.planning/codebase/STRUCTURE.md

@ -0,0 +1,171 @@
# Codebase Structure
**Analysis Date:** 2026-01-09
## Directory Layout
```
node-banana/
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── layout.tsx # Root layout, metadata
│ │ ├── page.tsx # Main workflow page
│ │ ├── globals.css # Tailwind base styles
│ │ └── api/ # API routes
│ │ ├── generate/ # Image generation
│ │ ├── llm/ # Text generation
│ │ ├── workflow/ # Save/load workflows
│ │ └── ... # Other routes
│ ├── components/ # React components
│ │ ├── nodes/ # Node type implementations
│ │ ├── edges/ # Edge type implementations
│ │ ├── modals/ # Modal dialogs
│ │ ├── quickstart/ # Onboarding UI
│ │ └── *.tsx # Top-level components
│ ├── store/ # Zustand state
│ │ ├── workflowStore.ts # Central workflow state
│ │ └── annotationStore.ts # Drawing state
│ ├── types/ # TypeScript definitions
│ │ ├── index.ts # Main types
│ │ └── quickstart.ts # Quickstart types
│ ├── utils/ # Utilities
│ │ ├── costCalculator.ts # Pricing calculation
│ │ ├── gridSplitter.ts # Grid detection
│ │ ├── imageStorage.ts # Image persistence
│ │ └── logger*.ts # Logging
│ └── lib/ # Feature libraries
│ └── quickstart/ # Quickstart logic + tests
├── public/ # Static assets
├── examples/ # Community workflows
├── .planning/ # Project planning docs
├── package.json # Dependencies
├── tsconfig.json # TypeScript config
└── next.config.ts # Next.js config
```
## Directory Purposes
**src/app/**
- Purpose: Next.js App Router pages and API routes
- Contains: Page components, API handlers
- Key files: `page.tsx` (main entry), `layout.tsx` (root layout)
- Subdirectories: `api/` for server routes
**src/components/**
- Purpose: React UI components
- Contains: All visual components
- Key files: `WorkflowCanvas.tsx`, `Header.tsx`, `FloatingActionBar.tsx`
- Subdirectories: `nodes/`, `edges/`, `modals/`, `quickstart/`
**src/components/nodes/**
- Purpose: Node type implementations (7 types)
- Contains: `BaseNode.tsx` (wrapper), `*Node.tsx` (specific types)
- Key files: `NanoBananaNode.tsx`, `PromptNode.tsx`, `ImageInputNode.tsx`
**src/store/**
- Purpose: Zustand state management
- Contains: Store definitions and actions
- Key files: `workflowStore.ts` (2000+ lines, central state)
**src/types/**
- Purpose: TypeScript type definitions
- Contains: All interfaces and type unions
- Key files: `index.ts` (main types), `quickstart.ts`
**src/utils/**
- Purpose: Business logic utilities
- Contains: Standalone helper functions
- Key files: `costCalculator.ts`, `gridSplitter.ts`, `imageStorage.ts`
**src/lib/quickstart/**
- Purpose: Quickstart/onboarding feature
- Contains: Templates, prompts, validation
- Subdirectories: `__tests__/` for test files
## Key File Locations
**Entry Points:**
- `src/app/page.tsx` - Main application entry
- `src/app/layout.tsx` - Root layout and providers
**Configuration:**
- `tsconfig.json` - TypeScript config (path alias: `@/*`)
- `next.config.ts` - Next.js with Turbopack
- `vitest.config.ts` - Test configuration
- `.env.local` - Environment variables (gitignored)
**Core Logic:**
- `src/store/workflowStore.ts` - All workflow state and execution
- `src/components/WorkflowCanvas.tsx` - Canvas orchestration
- `src/types/index.ts` - Type definitions
**API Routes:**
- `src/app/api/generate/route.ts` - Image generation
- `src/app/api/llm/route.ts` - Text generation
- `src/app/api/workflow/route.ts` - File operations
**Testing:**
- `src/lib/quickstart/__tests__/*.test.ts` - Unit tests
**Documentation:**
- `README.md` - User-facing documentation
- `CLAUDE.md` - AI assistant instructions
## Naming Conventions
**Files:**
- PascalCase.tsx - React components (`WorkflowCanvas.tsx`)
- camelCase.ts - Utilities and stores (`costCalculator.ts`)
- kebab-case directories - API routes (`save-generation/`)
- *.test.ts - Test files (colocated in `__tests__/`)
**Directories:**
- camelCase - Feature directories (`quickstart/`)
- Plural for collections (`nodes/`, `edges/`, `modals/`)
**Special Patterns:**
- `route.ts` - Next.js API route handler
- `index.ts` - Barrel exports
- `__tests__/` - Test directory
## Where to Add New Code
**New Node Type:**
- Implementation: `src/components/nodes/{Name}Node.tsx`
- Types: Add to `src/types/index.ts` (NodeType union, data interface)
- Registration: `src/components/WorkflowCanvas.tsx` (nodeTypes)
- Store logic: `src/store/workflowStore.ts` (createDefaultNodeData, executeWorkflow)
**New API Route:**
- Handler: `src/app/api/{route-name}/route.ts`
- Export: `GET`, `POST`, etc. functions
**New Utility:**
- Implementation: `src/utils/{name}.ts`
- Tests: `src/utils/__tests__/{name}.test.ts`
**New Component:**
- Implementation: `src/components/{Name}.tsx`
- Or in feature directory: `src/components/{feature}/{Name}.tsx`
## Special Directories
**examples/**
- Purpose: Community workflow examples
- Source: JSON workflow files
- Committed: Yes
**.planning/**
- Purpose: Project planning documentation
- Source: GSD planning system
- Committed: Yes
**.next/**
- Purpose: Next.js build output
- Source: Generated during build
- Committed: No (gitignored)
---
*Structure analysis: 2026-01-09*
*Update when directory structure changes*

180
.planning/codebase/TESTING.md

@ -0,0 +1,180 @@
# Testing Patterns
**Analysis Date:** 2026-01-09
## Test Framework
**Runner:**
- Vitest 4.0.16
- Config: `vitest.config.ts` in project root
**Assertion Library:**
- Vitest built-in expect
- Matchers: `toBe`, `toEqual`, `toHaveLength`, `toContainEqual`, `toHaveProperty`
**Run Commands:**
```bash
npm test # Run all tests in watch mode
npm run test:run # Run tests once
npm run test:coverage # Run with coverage report
```
## Test File Organization
**Location:**
- Colocated in `__tests__/` directories within feature folders
- Pattern: `src/lib/{feature}/__tests__/*.test.ts`
**Naming:**
- `{module-name}.test.ts` for all tests
- No distinction between unit/integration in filename
**Current Test Files:**
```
src/lib/quickstart/__tests__/
├── templates.test.ts # Template data validation
├── prompts.test.ts # Prompt generation tests
└── validation.test.ts # JSON validation tests
```
## Test Structure
**Suite Organization:**
```typescript
import { describe, it, expect } from "vitest";
describe("validation", () => {
describe("validateWorkflowJSON", () => {
describe("root validation", () => {
it("should reject null input", () => {
const result = validateWorkflowJSON(null);
expect(result.valid).toBe(false);
expect(result.errors).toContainEqual({
path: "",
message: "Workflow must be an object",
});
});
});
});
});
```
**Patterns:**
- Nested `describe()` blocks for logical grouping
- `it()` with descriptive "should" naming
- Arrange/Act/Assert structure (implicit)
- One concept per test
## Mocking
**Framework:**
- No mocks currently used
- Tests work with actual functions and data
**What to Mock (if needed):**
- API calls (fetch)
- File system operations
- External services
**What NOT to Mock:**
- Pure functions
- Validation logic
- Data structures
## Fixtures and Factories
**Test Data:**
- Inline test data in test files
- No separate fixtures directory
**Pattern Example:**
```typescript
const validWorkflow = {
version: 1,
nodes: [],
edges: [],
};
```
## Coverage
**Requirements:**
- No enforced coverage target
- Coverage tracked for awareness
**Configuration:**
```typescript
// vitest.config.ts
coverage: {
provider: "v8",
reporter: ["text", "json", "html"],
include: ["src/lib/quickstart/**"],
exclude: ["node_modules", "src/__tests__"],
}
```
**View Coverage:**
```bash
npm run test:coverage
open coverage/index.html
```
## Test Types
**Unit Tests:**
- Current focus: Quickstart validation functions
- Test single functions in isolation
- Examples: `validateWorkflowJSON()`, `repairWorkflowJSON()`, `parseJSONFromResponse()`
**Integration Tests:**
- Not currently implemented
- Needed for: API routes, workflow execution
**E2E Tests:**
- Not currently implemented
- Would use Playwright if added
## Test Coverage Gaps
**Untested Areas:**
- `src/store/workflowStore.ts` - Core execution logic (HIGH PRIORITY)
- `src/app/api/**` - All API routes
- `src/components/**` - All React components
- `src/utils/costCalculator.ts` - Cost calculation
- `src/utils/gridSplitter.ts` - Grid detection
**Tested Areas:**
- `src/lib/quickstart/validation.ts` - Workflow JSON validation
- `src/lib/quickstart/templates.ts` - Template data structures
- `src/lib/quickstart/prompts.ts` - Prompt generation
## Common Patterns
**Async Testing:**
```typescript
it("should handle async operation", async () => {
const result = await asyncFunction();
expect(result).toBe("expected");
});
```
**Error Testing:**
```typescript
it("should reject invalid input", () => {
const result = validateWorkflowJSON(null);
expect(result.valid).toBe(false);
expect(result.errors).toContainEqual({
path: "",
message: "Workflow must be an object",
});
});
```
**Snapshot Testing:**
- Not used in this codebase
- Prefer explicit assertions
---
*Testing analysis: 2026-01-09*
*Update when test patterns change*
Loading…
Cancel
Save