diff --git a/CLAUDE.md b/CLAUDE.md
index a0c73de..a4cf3f9 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -38,10 +38,24 @@ claude-tutorial/
├── examples/
│ └── claude-md-template.md # Production-ready CLAUDE.md template
│
-├── prompts.md # Workshop exercise prompts
+├── prompts.md # Original workshop exercise prompts
+├── workshop-prompts.md # Hands-on workshop prompts (auto-generated)
├── WORKSHOP_GUIDE.md # Instructor guide for workshops
-├── claude-code-interactive-tutorial.pdf # Workshop slides
-└── create_*.py # Python scripts to generate presentations
+│
+├── # Presentation PDFs
+├── claude-code-interactive-tutorial.pdf # Original interactive workshop (2-3 hours)
+├── ai-first-lecture.pdf # 1-hour lecture (no hands-on)
+├── ai-first-workshop.pdf # 3-hour hands-on workshop (guided)
+├── ai-first-openended-workshop.pdf # 3-hour open-ended workshop (choose your project)
+├── openended-workshop-prompts.md # Prompts for open-ended workshop
+│
+├── # Python scripts to generate presentations
+├── presentation_utils.py # Shared utilities for PDF generation
+├── create_presentation.py # Generates overview PDF
+├── create_interactive_presentation_v2.py # Generates interactive tutorial PDF
+├── create_lecture_presentation.py # Generates 1-hour lecture PDF
+├── create_handson_workshop.py # Generates 3-hour guided workshop PDF
+└── create_openended_workshop.py # Generates 3-hour open-ended workshop PDF
```
## Key Concepts (Important for Editing)
@@ -122,10 +136,35 @@ The `examples/claude-md-template.md` is the **most important file** in this repo
### Workshop Materials
-The workshop materials work together as a system:
-- `claude-code-interactive-tutorial.pdf` - Main presentation slides
-- `prompts.md` - Copy-paste prompts for hands-on exercises (references slide numbers)
-- `WORKSHOP_GUIDE.md` - Instructor notes for running workshops
+The workshop materials work together as a system. There are three presentation options:
+
+**1. Original Interactive Workshop (2-3 hours)**
+- `claude-code-interactive-tutorial.pdf` - Interactive tutorial with hands-on exercises
+- `prompts.md` - Copy-paste prompts (references slide numbers)
+- Best for: Standard workshop sessions
+
+**2. Lecture Presentation (1 hour, no hands-on)**
+- `ai-first-lecture.pdf` - Comprehensive lecture covering all topics
+- No accompanying prompts file (lecture format)
+- Best for: Conference talks, team briefings, executive overviews
+- Topics: Philosophy, concerns, prompt engineering, testing, git, tips
+
+**3. Guided Hands-On Workshop (3 hours)**
+- `ai-first-workshop.pdf` - Guided workshop building auth feature
+- `workshop-prompts.md` - Copy-paste prompts (auto-generated)
+- Best for: Full training sessions with structured exercises
+- Attendees follow step-by-step exercises
+
+**4. Open-Ended Workshop (3 hours)**
+- `ai-first-openended-workshop.pdf` - Choose your own project
+- `openended-workshop-prompts.md` - Prompts for open-ended format
+- Reference repo: `github.com/emmanuelandre/unveiling-claude`
+- Best for: Experienced developers, hackathon-style sessions
+- Attendees choose from sample specs or bring their own idea
+- Minimal guidance after project selection - independent work with AI
+
+**Instructor Guide:**
+- `WORKSHOP_GUIDE.md` - Notes for running any workshop format
**Workshop GitHub Repository Convention:**
- All attendees create a private GitHub repository named: `unveiling-claude`
@@ -144,9 +183,22 @@ The workshop materials work together as a system:
### Python Presentation Scripts
The `create_*.py` files generate presentation PDFs:
-- Not part of the tutorial content
-- Used to regenerate PDFs when updating slides
-- No need to maintain unless updating presentations
+
+| Script | Output | Purpose |
+|--------|--------|---------|
+| `presentation_utils.py` | (shared module) | Common utilities for all presentations |
+| `create_presentation.py` | `claude-code-tutorial.pdf` | Simple 17-slide overview |
+| `create_interactive_presentation_v2.py` | `claude-code-interactive-tutorial.pdf` | Original interactive workshop |
+| `create_lecture_presentation.py` | `ai-first-lecture.pdf` | 1-hour lecture (no hands-on) |
+| `create_handson_workshop.py` | `ai-first-workshop.pdf` + `workshop-prompts.md` | 3-hour hands-on workshop |
+
+**To regenerate presentations:**
+```bash
+.venv/bin/python3 create_lecture_presentation.py # Lecture
+.venv/bin/python3 create_handson_workshop.py # Workshop
+```
+
+**Dependencies:** `reportlab` (installed in `.venv`)
## Common Tasks
@@ -224,7 +276,10 @@ fix: correct code example in git workflow
| `docs/06-testing-strategy.md` | E2E-first testing philosophy | Core methodology |
| `docs/07-ai-first-workflow.md` | 10-step development process | Core methodology |
| `docs/11-git-workflow.md` | Git conventions and best practices | Referenced by template |
-| `prompts.md` | Workshop exercise prompts | Used with PDF workshop |
+| `prompts.md` | Original workshop exercise prompts | Used with interactive tutorial PDF |
+| `workshop-prompts.md` | Hands-on workshop prompts | Auto-generated, used with 3-hour workshop |
+| `ai-first-lecture.pdf` | 1-hour lecture slides | No hands-on, conference/briefing format |
+| `ai-first-workshop.pdf` | 3-hour workshop slides | Hands-on, build from scratch format |
## Important Notes
@@ -254,7 +309,7 @@ When making changes, preserve these core principles taught in this tutorial:
---
-**Last Updated**: 2025-11-16
+**Last Updated**: 2025-12-04
**Repository Type**: Educational Documentation
**Primary Audience**: Software developers learning AI-first development with Claude Code
- always update /docs, the pdf slides and the prompts.md
diff --git a/README.md b/README.md
index 34fa33b..b806f05 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,13 @@ A comprehensive guide to working effectively with Claude Code (claude.ai/code) f
### Best Practices
- [Git Workflow](./docs/11-git-workflow.md) - Branch naming, commits, and PR management
+- [Documentation Organization](./docs/12-documentation-organization.md) - Structure for plans, architecture, specs, and rules
+- [Documentation Writing](./docs/13-documentation-writing.md) - API docs, code comments, and ADRs
+- [Code Review](./docs/14-code-review.md) - Reviewing AI-generated code effectively
+- [Security Practices](./docs/15-security.md) - Authentication, validation, and secrets management
+- [Performance Optimization](./docs/16-performance.md) - Database, API, and frontend performance
+- [CI/CD and Deployment](./docs/17-ci-cd.md) - GitHub Actions and deployment pipelines
+- [Advanced Topics](./docs/18-advanced-topics.md) - MCP servers, multi-repo, and legacy code
### Reference
- [Troubleshooting](./docs/19-troubleshooting.md) - Common issues and solutions
@@ -30,6 +37,7 @@ A comprehensive guide to working effectively with Claude Code (claude.ai/code) f
### Examples
- [CLAUDE.md Template](./examples/claude-md-template.md) - Production-ready project configuration
+- [my-api-project](./examples/my-api-project/) - Workshop reference example (Go API with PostgreSQL)
### Workshop Materials
- [Interactive Tutorial Slides](./claude-code-interactive-tutorial.pdf) - 40+ slide hands-on workshop
diff --git a/WORKSHOP_GUIDE.md b/WORKSHOP_GUIDE.md
index fc836ab..f806792 100644
--- a/WORKSHOP_GUIDE.md
+++ b/WORKSHOP_GUIDE.md
@@ -1,15 +1,202 @@
# Workshop Presentation Guide
+## Available Presentations
+
+| Presentation | Duration | Format | Use Case |
+|--------------|----------|--------|----------|
+| `ai-first-lecture.pdf` | 1 hour | Lecture (no hands-on) | Conference talks, team briefings |
+| `ai-first-workshop.pdf` | 3 hours | Guided hands-on | Training sessions, bootcamps |
+| `ai-first-openended-workshop.pdf` | 3 hours | Open-ended hands-on | Hackathons, experienced devs |
+| `claude-code-interactive-tutorial.pdf` | 2-3 hours | Interactive | Standard workshops |
+| `claude-code-tutorial.pdf` | 30 min | Overview | Quick introductions |
+
## Files Overview
### Presentation Files
-- **`claude-code-tutorial.pdf`** - 17-slide overview presentation (use for short talks)
-- **`claude-code-interactive-tutorial.pdf`** - 40+ slide interactive workshop (full hands-on session)
-- **`prompts.md`** - All workshop prompts with page references for easy copy-paste
+- **`ai-first-lecture.pdf`** - 1-hour lecture covering all AI-first topics (NO hands-on)
+- **`ai-first-workshop.pdf`** - 3-hour guided workshop (everyone builds same feature)
+- **`workshop-prompts.md`** - Prompts for the guided workshop (auto-generated)
+- **`ai-first-openended-workshop.pdf`** - 3-hour open-ended workshop (choose your project)
+- **`openended-workshop-prompts.md`** - Prompts for open-ended workshop (auto-generated)
+- **`claude-code-interactive-tutorial.pdf`** - Original 40+ slide interactive workshop
+- **`prompts.md`** - Original workshop prompts with page references
+- **`claude-code-tutorial.pdf`** - 17-slide overview presentation (short talks)
### Python Scripts
+- **`presentation_utils.py`** - Shared utilities for PDF generation
+- **`create_lecture_presentation.py`** - Generates the 1-hour lecture PDF
+- **`create_handson_workshop.py`** - Generates the 3-hour guided workshop PDF
+- **`create_openended_workshop.py`** - Generates the 3-hour open-ended workshop PDF
+- **`create_interactive_presentation_v2.py`** - Generates the interactive workshop PDF + prompts.md
- **`create_presentation.py`** - Generates the 17-slide overview PDF
-- **`create_interactive_presentation_v2.py`** - Generates the interactive workshop PDF and prompts.md
+
+---
+
+## Option 1: 1-Hour Lecture (No Hands-On)
+
+**Use:** `ai-first-lecture.pdf`
+
+### When to Use
+- Conference talks
+- Team briefings
+- Executive presentations
+- Introduction sessions without setup time
+
+### Topics Covered (~50 min + Q&A)
+1. AI-First Philosophy (4 min)
+2. Addressing Common Concerns (5 min)
+3. Prompt Engineering vs Vibe Coding (4 min)
+4. Getting Started with Prompt Engineering (6 min)
+5. Scaling to Large Projects (5 min)
+6. Feature Documentation Best Practices (5 min)
+7. Testing Strategies (5 min)
+8. Project Planning & 10-Step Workflow (4 min)
+9. Git Best Practices (4 min)
+10. Tips & Tricks (5 min)
+
+### Setup
+- Open `ai-first-lecture.pdf` on projector
+- No attendee setup needed
+- Allow 10-15 min Q&A at end
+
+---
+
+## Option 2: 3-Hour Hands-On Workshop
+
+**Use:** `ai-first-workshop.pdf` + `workshop-prompts.md`
+
+### When to Use
+- Full training sessions
+- Bootcamps
+- Teams wanting practical experience
+- Groups with 3+ hours available
+
+### Prerequisites for Attendees
+- Laptop with internet
+- Claude Code access (or other AI coding assistant)
+- Git installed
+- GitHub account
+- Preferred language runtime (Go, Node, Python)
+- Code editor (VS Code, Cursor, etc.)
+
+### Reference Repository
+Attendees use `github.com/emmanuelandre/unveiling-claude` as reference (NOT copy-paste).
+They build their OWN project from scratch.
+
+### Timeline
+
+| Part | Duration | Content | Hands-On |
+|------|----------|---------|----------|
+| Part 1 | 20 min | Philosophy & setup | No |
+| Part 2 | 30 min | Project setup | Exercises 1-3 |
+| Break 1 | 5 min | | |
+| Part 3 | 60 min | Build auth feature | Exercises 4-10 |
+| Break 2 | 10 min | | |
+| Part 4 | 25 min | Testing deep dive | Exercises 11-12 |
+| Part 5 | 20 min | Git & best practices | Exercises 13-14 |
+| Part 6 | 25 min | Final challenge | Exercise 15 |
+| Wrap-up | 5 min | Summary | No |
+
+### Key Exercises
+1. Create GitHub repository
+2. Create CLAUDE.md project rules
+3. Initialize Git workflow
+4. Write feature specification
+5. Create database schema
+6. Implement repository layer
+7. Create API handlers
+8. Write E2E tests
+9. Run and debug tests
+10. Add unit tests
+11. Create proper commits
+12. Push and create PR
+13. Final challenge (choose feature)
+
+---
+
+## Option 3: 3-Hour Open-Ended Workshop
+
+**Use:** `ai-first-openended-workshop.pdf` + `openended-workshop-prompts.md`
+
+### When to Use
+- Hackathons
+- Experienced developers
+- Teams who want to explore their own ideas
+- Groups comfortable with self-directed learning
+
+### Prerequisites for Attendees
+- Laptop with internet
+- Claude Code access (or other AI coding assistant)
+- Git installed
+- GitHub account
+- Preferred language runtime (Go, Node, Python, TypeScript)
+- Code editor (VS Code, Cursor, etc.)
+
+### Sample Projects Available
+
+Attendees can choose from `github.com/emmanuelandre/unveiling-claude`:
+
+| Project | Description | Complexity |
+|---------|-------------|------------|
+| **manu-code** | AI-powered CLI code assistant | High |
+| **task-manager** | Task management system with API | Medium |
+| **my-api-project** | Simple API project starter | Low |
+| **prompt-ops** | Prompt operations tooling | Medium |
+| **ui-to-test** | UI testing project | Medium |
+
+Or attendees can propose their **own project idea**.
+
+### Timeline
+
+| Part | Duration | Content | Hands-On |
+|------|----------|---------|----------|
+| Part 1 | 10 min | AI-First philosophy recap | No |
+| Part 1 | 15 min | Sample projects overview | No |
+| Part 1 | 15 min | Project selection | Exercise 1 |
+| Part 1 | 5 min | Setup (fork/create repo) | Exercise 2 |
+| Part 2 | 20 min | Planning phase | Exercise 3 |
+| Part 2 | 35 min | Implementation sprint 1 | Exercise 4 |
+| Break | 10 min | | |
+| Part 2 | 25 min | Implementation sprint 2 | Exercise 5 |
+| Part 3 | 15 min | Git workflow | Exercise 6 |
+| Part 3 | 20 min | Show & Tell demos | No |
+| Part 3 | 10 min | Wrap-up | No |
+
+### Key Exercises
+1. Browse & choose your project
+2. Initial setup (fork or create repo)
+3. Create your plan with AI (CLAUDE.md + spec)
+4. Implementation sprint 1 (core feature)
+5. Implementation sprint 2 (continue + polish)
+6. Commit and push / create PR
+
+### Key Difference from Guided Workshop
+
+In the **guided workshop** (Option 2):
+- Everyone builds the same authentication feature
+- Step-by-step instructions for each part
+- Instructor demonstrates, then attendees follow
+
+In the **open-ended workshop** (Option 3):
+- Everyone chooses their own project
+- Minimal guidance after project selection
+- Attendees work independently with their AI assistant
+- Focus on learning through exploration
+
+### Instructor Tips for Open-Ended Format
+
+1. **During project selection** - Walk around and help attendees decide
+2. **During sprints** - Be available for questions but don't guide too much
+3. **Encourage experimentation** - Different approaches are expected
+4. **Show & Tell is key** - Let attendees share what they learned
+
+---
+
+## Option 4: Original Interactive Workshop (2-3 hours)
+
+**Use:** `claude-code-interactive-tutorial.pdf` + `prompts.md`
+
+(See existing guide content below)
## How to Use During Workshop
@@ -115,18 +302,61 @@ Claude creates a comprehensive CLAUDE.md with architecture, commands, and conven
If you need to update content:
```bash
-# Update the overview presentation
-python3 create_presentation.py
+# Activate virtual environment (required for reportlab)
+source .venv/bin/activate
-# Update the interactive workshop + prompts
-python3 create_interactive_presentation_v2.py
+# Generate 1-hour lecture
+.venv/bin/python3 create_lecture_presentation.py
+
+# Generate 3-hour guided workshop + prompts
+.venv/bin/python3 create_handson_workshop.py
+
+# Generate 3-hour open-ended workshop + prompts
+.venv/bin/python3 create_openended_workshop.py
+
+# Generate original interactive workshop + prompts
+.venv/bin/python3 create_interactive_presentation_v2.py
+
+# Generate overview presentation
+.venv/bin/python3 create_presentation.py
```
-Both commands generate PDFs. The v2 script also generates `prompts.md`.
+All scripts use `presentation_utils.py` for shared styling and functions.
+
+## Using the Reference Example
+
+The `examples/my-api-project/` directory contains a complete reference implementation.
+
+### What's Included
+- `CLAUDE.md` - Production-ready project configuration
+- `migrations/001_create_users.up.sql` - Database migration with triggers
+- `migrations/001_create_users.down.sql` - Rollback migration
+
+### How to Use During Workshop
+
+1. **Attendees complete exercises independently** first
+2. **After each exercise**, show the reference example for comparison
+3. **Discuss differences** - different approaches are OK if they work!
+4. **Do NOT show before exercise** - prevents learning
+
+### When to Show Reference
+
+| After Exercise | Show |
+|----------------|------|
+| Page 9 (Create CLAUDE.md) | `examples/my-api-project/CLAUDE.md` |
+| Page 15 (Review Schema) | `examples/my-api-project/migrations/` |
+
+### Discussion Points
+
+- Reference CLAUDE.md includes automatic `updated_at` trigger
+- Reference migration has both up and down versions
+- Compare attendee outputs - different is OK if it works!
+- Highlight patterns: indexes, constraints, comments
## Post-Workshop
Share with attendees:
- Full documentation in `/docs` folder
- CLAUDE.md template in `/examples`
+- Reference project in `/examples/my-api-project`
- Encourage them to try the final exercise at home
diff --git a/ai-first-lecture.pdf b/ai-first-lecture.pdf
new file mode 100644
index 0000000..3c29d3a
Binary files /dev/null and b/ai-first-lecture.pdf differ
diff --git a/ai-first-openended-workshop.pdf b/ai-first-openended-workshop.pdf
new file mode 100644
index 0000000..b3a3341
Binary files /dev/null and b/ai-first-openended-workshop.pdf differ
diff --git a/ai-first-workshop.pdf b/ai-first-workshop.pdf
new file mode 100644
index 0000000..0cc007e
Binary files /dev/null and b/ai-first-workshop.pdf differ
diff --git a/claude-code-interactive-tutorial.pdf b/claude-code-interactive-tutorial.pdf
index 40aab14..ab23e0b 100644
Binary files a/claude-code-interactive-tutorial.pdf and b/claude-code-interactive-tutorial.pdf differ
diff --git a/create_handson_workshop.py b/create_handson_workshop.py
new file mode 100644
index 0000000..8dda693
--- /dev/null
+++ b/create_handson_workshop.py
@@ -0,0 +1,899 @@
+#!/usr/bin/env python3
+"""
+Generate 3-hour AI-First Development hands-on workshop presentation.
+Attendees build from scratch using unveiling-claude as reference.
+Tool-agnostic with Claude Code/Windsurf as examples.
+"""
+
+from reportlab.lib.styles import getSampleStyleSheet
+from reportlab.platypus import Spacer, PageBreak
+from reportlab.lib.units import inch
+from presentation_utils import (
+ create_document,
+ create_title_slide,
+ create_section_slide,
+ create_content_slide,
+ create_two_column_slide,
+ create_code_slide,
+ create_hands_on_slide,
+ create_thank_you_slide,
+ export_prompts_to_markdown,
+ NumberedCanvas,
+ DARK_BLUE
+)
+
+# Collect all prompts for export
+ALL_PROMPTS = []
+
+
+def create_presentation():
+ """Generate the complete workshop presentation."""
+ doc = create_document("ai-first-workshop.pdf")
+ styles = getSampleStyleSheet()
+ story = []
+ page_num = 1
+
+ # =================
+ # TITLE
+ # =================
+ create_title_slide(
+ story, styles,
+ "AI-First Development",
+ "Hands-On Workshop",
+ "Build from scratch using AI • 3 Hours • Reference: github.com/emmanuelandre/unveiling-claude"
+ )
+ page_num += 1
+
+ # =================
+ # AGENDA
+ # =================
+ create_content_slide(story, styles, "Workshop Agenda (3 Hours)", [
+ "Part 1: Foundation (20 min) - Philosophy & Setup",
+ "Part 2: Project Setup (30 min) - Create Your Project",
+ "☕ Break 1 (5 min)",
+ "Part 3: Core Workflow (60 min) - Build a Feature End-to-End",
+ "☕ Break 2 (10 min)",
+ "Part 4: Testing Deep Dive (25 min) - E2E & Unit Tests",
+ "Part 5: Git & Best Practices (20 min) - Commits, PRs, Prompts",
+ "Part 6: Final Challenge (25 min) - Complete Feature Solo",
+ "Wrap-up (5 min)"
+ ])
+ page_num += 1
+
+ # =================
+ # PART 1: FOUNDATION
+ # =================
+ create_section_slide(story, styles, "Part 1: Foundation")
+ page_num += 1
+
+ create_content_slide(story, styles, "The AI-First Philosophy", [
+ "Traditional: Human writes code → AI assists",
+ "AI-First: AI executes 100% → Human validates 100%",
+ ("This means:", [
+ "AI handles ALL coding, testing, documentation",
+ "Human handles ALL validation, review, decisions",
+ "Clear handoff points at each step"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "The 10-Step Development Process", [
+ "1. Specification (Human writes detailed spec)",
+ "2. Database Schema (AI designs → Human reviews)",
+ "3. Repository Layer (AI implements → Human reviews)",
+ "4. API Endpoints (AI creates → Human reviews)",
+ "5. API E2E Tests (AI writes → Human verifies)",
+ "6. Frontend Components (AI builds → Human reviews)",
+ "7. UI E2E Tests (AI creates → Human verifies)",
+ "8. Documentation (AI updates → Human reviews)",
+ "9. Code Review (Human conducts)",
+ "10. Deployment (AI executes → Human verifies)"
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Workshop Approach", [
+ ("What You'll Build:", [
+ "Your OWN project from scratch",
+ "A complete feature with API and tests",
+ "Real Git workflow with commits and PR"
+ ]),
+ ("Reference Material:", [
+ "github.com/emmanuelandre/unveiling-claude",
+ "Contains working examples to study",
+ "Use as patterns, not copy-paste"
+ ]),
+ ("Choose Your Stack:", [
+ "Go, Node, Python - whatever you prefer",
+ "Prompts are stack-agnostic"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Prerequisites Check", [
+ "✓ Git 2.x or higher installed",
+ "✓ Code editor (VS Code, Cursor, etc.)",
+ "✓ AI coding assistant access (Claude Code, Windsurf, etc.)",
+ "✓ GitHub account",
+ "✓ Your preferred language runtime (Go, Node, Python)",
+ "✓ GitHub CLI (gh) - optional but recommended"
+ ])
+ page_num += 1
+
+ # =================
+ # PART 2: PROJECT SETUP
+ # =================
+ create_section_slide(story, styles, "Part 2: Project Setup")
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Exercise 1: Create Your Repository",
+"""Create a new GitHub repository for your project:
+
+1. Go to github.com and create a new PRIVATE repository
+ Name: my-ai-project (or your preferred name)
+
+2. Clone it locally:
+ git clone https://github.com/[YOUR-USERNAME]/my-ai-project.git
+ cd my-ai-project
+
+3. Verify:
+ git status
+ Should show: "On branch main, nothing to commit"
+
+Reference: Check unveiling-claude repo structure for ideas""",
+ "Local repository initialized and connected to GitHub",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Exercise 2: Create Project Rules File",
+"""Ask your AI assistant:
+
+Help me create a project rules file for my project.
+
+Project details:
+- Language: [Go/Node/Python]
+- Type: REST API with database
+- Database: PostgreSQL (or SQLite for simplicity)
+- Testing: E2E with [Cypress/Go test/pytest]
+
+Include these sections:
+1. Project Overview (what this project does)
+2. Tech Stack (language, framework, database)
+3. Project Structure (recommended directories)
+4. Commands (build, test, run)
+5. Git Workflow (branch naming, commit format)
+6. Testing Requirements (E2E mandatory)
+
+Save as CLAUDE.md (or .windsurfrules for Windsurf)""",
+ "Project rules file created with all sections",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_content_slide(story, styles, "What Goes in a Project Rules File", [
+ ("Project Overview:", [
+ "Brief description of what this project does"
+ ]),
+ ("Tech Stack:", [
+ "Language, frameworks, database, testing tools"
+ ]),
+ ("Commands:", [
+ "How to build, test, run, and lint"
+ ]),
+ ("Git Workflow:", [
+ "Branch naming conventions",
+ "Commit message format"
+ ]),
+ ("Testing Requirements:", [
+ "Coverage expectations",
+ "What must be tested"
+ ])
+ ])
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Exercise 3: Initialize Git Workflow",
+"""Ask your AI assistant:
+
+Set up the git workflow for my project:
+
+1. Create .gitignore for [Go/Node/Python] project
+ Include: build outputs, dependencies, IDE files, .env
+
+2. Create initial directory structure:
+ - cmd/ or src/ for source code
+ - tests/ or test/ for tests
+ - migrations/ for database migrations
+ - docs/ for documentation
+
+3. Create initial commit:
+ git add .
+ git commit -m "chore: initial project setup"
+
+4. Create feature branch for our first feature:
+ git checkout -b feature/user-auth""",
+ "Git initialized with proper structure and on feature branch",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ # =================
+ # BREAK 1
+ # =================
+ create_section_slide(story, styles, "☕ 5-Minute Break")
+ page_num += 1
+
+ # =================
+ # PART 3: CORE WORKFLOW
+ # =================
+ create_section_slide(story, styles, "Part 3: Core Workflow - Build a Feature")
+ page_num += 1
+
+ create_content_slide(story, styles, "Feature: User Authentication", [
+ ("We'll build:", [
+ "User registration endpoint",
+ "User login endpoint",
+ "JWT token authentication",
+ "E2E tests for all endpoints"
+ ]),
+ ("Following the 10-step process:", [
+ "Step 1: Write specification",
+ "Step 2: Create database schema",
+ "Step 3-4: Implement repository and API",
+ "Step 5: Write E2E tests"
+ ]),
+ "Each step: AI implements → You review → Approve or request changes"
+ ])
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Step 1: Write Feature Specification",
+"""Ask your AI assistant:
+
+I need to implement user authentication for my API.
+
+Requirements:
+- Users register with email and password
+- Users login with email and password
+- JWT tokens for authentication
+- Password hashing (never store plain text)
+
+Database Schema Needed:
+- users table: id, email, password_hash, created_at, updated_at
+
+API Endpoints:
+POST /api/auth/register - Register new user
+ Request: { email, password }
+ Response: { user_id, email, token }
+
+POST /api/auth/login - Login existing user
+ Request: { email, password }
+ Response: { user_id, email, token }
+
+Success Criteria:
+- Passwords hashed with bcrypt
+- JWT expires after 1 hour
+- Proper HTTP status codes (201, 200, 400, 401)
+- E2E tests cover happy path and errors
+
+Please confirm you understand before we proceed.""",
+ "AI confirms understanding, may ask clarifying questions",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_content_slide(story, styles, "Reviewing the Specification", [
+ ("Check that AI understood:", [
+ "All requirements captured?",
+ "Endpoints match your expectations?",
+ "Any clarifying questions to answer?"
+ ]),
+ ("Common clarifications:", [
+ "Password minimum length?",
+ "Token expiration time?",
+ "Error message format?"
+ ]),
+ 'If satisfied: "Looks good, please create the database migration"',
+ 'If changes needed: "Change X to Y because..."'
+ ])
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Step 2: Create Database Schema",
+"""Ask your AI assistant:
+
+Create the database migration for the users table.
+
+Requirements:
+- Table name: users
+- Columns: id (primary key), email (unique), password_hash, created_at, updated_at
+- Add index on email column for fast lookups
+
+For Go: Create migrations/001_create_users.up.sql and .down.sql
+For Node: Create migrations/001_create_users.js
+For Python: Create migrations/001_create_users.py
+
+Use appropriate types for your database:
+- PostgreSQL: SERIAL, VARCHAR, TIMESTAMP
+- SQLite: INTEGER PRIMARY KEY, TEXT
+
+Include both up (create) and down (drop) migrations.""",
+ "Migration file(s) created with proper schema",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_code_slide(story, styles, "Expected: Database Migration (SQL)", "sql",
+"""-- migrations/001_create_users.up.sql
+CREATE TABLE users (
+ id SERIAL PRIMARY KEY,
+ email VARCHAR(255) UNIQUE NOT NULL,
+ password_hash VARCHAR(255) NOT NULL,
+ created_at TIMESTAMP DEFAULT NOW(),
+ updated_at TIMESTAMP DEFAULT NOW()
+);
+
+CREATE INDEX idx_users_email ON users(email);
+
+-- migrations/001_create_users.down.sql
+DROP TABLE IF EXISTS users;""")
+ page_num += 1
+
+ create_content_slide(story, styles, "Review Checklist: Database Schema", [
+ ("Check before approving:", [
+ "Column types appropriate for your database?",
+ "Primary key defined correctly?",
+ "Unique constraint on email?",
+ "Index on frequently queried columns (email)?",
+ "Timestamps with default values?",
+ "Down migration is safe (doesn't lose other data)?"
+ ]),
+ 'If good: "Schema looks good, please implement the repository layer"',
+ 'If issues: "Change X to Y..."'
+ ])
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Step 3: Implement Repository Layer",
+"""Ask your AI assistant:
+
+Implement the repository layer for user operations.
+
+Create a UserRepository with these methods:
+- Create(email, passwordHash) -> User
+- FindByEmail(email) -> User or null
+- FindByID(id) -> User or null
+
+Requirements:
+- Use prepared statements (prevent SQL injection)
+- Handle database errors gracefully
+- Return appropriate errors (not found, duplicate, etc.)
+
+Place in:
+- Go: internal/repository/user_repository.go
+- Node: src/repositories/userRepository.js
+- Python: app/repositories/user_repository.py
+
+Follow patterns from the project rules file.""",
+ "Repository file created with all methods",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Step 4: Implement API Handlers",
+"""Ask your AI assistant:
+
+Implement the API handlers for authentication.
+
+Create handlers for:
+1. POST /api/auth/register
+ - Validate email format
+ - Validate password (minimum 8 characters)
+ - Hash password with bcrypt
+ - Create user in database
+ - Generate and return JWT token
+ - Return 400 for validation errors
+ - Return 409 for duplicate email
+
+2. POST /api/auth/login
+ - Find user by email
+ - Verify password against hash
+ - Generate and return JWT token
+ - Return 401 for invalid credentials
+
+Include:
+- Input validation
+- Proper HTTP status codes
+- JSON response format: { success: true/false, data/error }
+- Wire up routes to main application""",
+ "Handler files created and routes configured",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_code_slide(story, styles, "Expected: API Handler Structure", "go",
+"""// Pseudo-code structure (adapt for your language)
+
+func Register(request) response {
+ // 1. Parse and validate input
+ email, password := parseRequest(request)
+ if !validEmail(email) {
+ return error(400, "Invalid email")
+ }
+ if len(password) < 8 {
+ return error(400, "Password too short")
+ }
+
+ // 2. Hash password
+ hash := bcrypt.Hash(password)
+
+ // 3. Create user
+ user, err := repo.Create(email, hash)
+ if err == DuplicateEmail {
+ return error(409, "Email already exists")
+ }
+
+ // 4. Generate token
+ token := jwt.Generate(user.ID)
+
+ return success(201, { user, token })
+}""")
+ page_num += 1
+
+ create_content_slide(story, styles, "Review Checklist: API Implementation", [
+ ("Security:", [
+ "Password hashed before storing?",
+ "No plain text passwords in logs?",
+ "SQL injection prevented (prepared statements)?"
+ ]),
+ ("Error Handling:", [
+ "Appropriate status codes?",
+ "Clear error messages (no internal details exposed)?",
+ "All error paths handled?"
+ ]),
+ ("Validation:", [
+ "Email format validated?",
+ "Password requirements checked?",
+ "Required fields validated?"
+ ])
+ ])
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Step 5: Write E2E API Tests",
+"""Ask your AI assistant:
+
+Create E2E tests for the authentication endpoints.
+
+Test cases needed:
+1. Register - Happy path (201)
+ - New user can register
+ - Response includes token
+
+2. Register - Duplicate email (409)
+ - Cannot register same email twice
+
+3. Register - Invalid email (400)
+ - Rejects malformed email
+
+4. Register - Weak password (400)
+ - Rejects password < 8 chars
+
+5. Login - Valid credentials (200)
+ - Returns token
+
+6. Login - Invalid password (401)
+ - Wrong password rejected
+
+7. Login - Non-existent user (401)
+ - Unknown email rejected
+
+Use your testing framework:
+- Go: internal/handlers/auth_test.go
+- Node: tests/api/auth.test.js (Jest/Vitest)
+- Python: tests/test_auth.py (pytest)
+
+Include setup and teardown for test database.""",
+ "Test file created with all test cases",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_code_slide(story, styles, "Expected: E2E Test Structure", "javascript",
+"""// Example test structure (adapt for your framework)
+
+describe('Auth API', () => {
+ beforeEach(() => {
+ // Clear test database
+ });
+
+ describe('POST /api/auth/register', () => {
+ it('registers new user successfully', async () => {
+ const response = await request(app)
+ .post('/api/auth/register')
+ .send({ email: 'test@example.com', password: 'SecurePass123' });
+
+ expect(response.status).toBe(201);
+ expect(response.body.token).toBeDefined();
+ });
+
+ it('rejects duplicate email', async () => {
+ // First registration
+ await request(app)
+ .post('/api/auth/register')
+ .send({ email: 'test@example.com', password: 'SecurePass123' });
+
+ // Duplicate attempt
+ const response = await request(app)
+ .post('/api/auth/register')
+ .send({ email: 'test@example.com', password: 'SecurePass123' });
+
+ expect(response.status).toBe(409);
+ });
+ });
+});""")
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Run and Verify Tests",
+"""Run your E2E tests:
+
+For Go:
+ go test -v ./internal/handlers/...
+
+For Node:
+ npm test -- --grep "Auth API"
+
+For Python:
+ pytest tests/test_auth.py -v
+
+Expected: All 7 test cases pass (green)
+
+If tests fail, share the error with your AI assistant:
+"Test [name] is failing with this error:
+[paste error output]
+
+Please analyze the failure and suggest a fix."
+
+Continue until ALL tests pass!""",
+ "All E2E tests passing (7/7 green)",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ # =================
+ # BREAK 2
+ # =================
+ create_section_slide(story, styles, "☕ 10-Minute Break")
+ page_num += 1
+
+ # =================
+ # PART 4: TESTING DEEP DIVE
+ # =================
+ create_section_slide(story, styles, "Part 4: Testing Deep Dive")
+ page_num += 1
+
+ create_content_slide(story, styles, "Testing Philosophy", [
+ "Both E2E and Unit tests are MANDATORY",
+ ("E2E Tests Cover:", [
+ "Complete user journeys",
+ "API endpoint behavior",
+ "Integration between components"
+ ]),
+ ("Unit Tests Cover:", [
+ "Business logic and calculations",
+ "Utility functions",
+ "Edge cases and error handling"
+ ]),
+ "Takeaway: E2E catches integration issues, Unit catches logic bugs"
+ ])
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Exercise: Add Unit Tests",
+"""Ask your AI assistant:
+
+Add unit tests for the authentication logic.
+
+Create unit tests for:
+1. Password validation function
+ - Test: 8+ chars passes
+ - Test: < 8 chars fails
+ - Test: Empty string fails
+
+2. Email validation function
+ - Test: valid@email.com passes
+ - Test: invalid-email fails
+ - Test: Empty string fails
+
+3. JWT token generation
+ - Test: Token contains user ID
+ - Test: Token has correct expiration
+
+4. Password hashing
+ - Test: Same password produces different hashes (salt)
+ - Test: Verify function works
+
+Place in appropriate test file:
+- Go: internal/auth/auth_test.go
+- Node: tests/unit/auth.test.js
+- Python: tests/unit/test_auth.py""",
+ "Unit tests created and passing",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_content_slide(story, styles, "Testing Best Practices", [
+ ("Use data-test attributes for UI:", [
+ 'data-test="login-button" not button.primary'
+ ]),
+ ("Test user journeys, not implementation:", [
+ '"User can log in" not "Login function returns token"'
+ ]),
+ ("Coverage priorities:", [
+ "1. Happy path - must work",
+ "2. Error cases - validation, auth failures",
+ "3. Edge cases - empty strings, nulls"
+ ]),
+ "Run tests in pre-commit hooks"
+ ])
+ page_num += 1
+
+ # =================
+ # PART 5: GIT & BEST PRACTICES
+ # =================
+ create_section_slide(story, styles, "Part 5: Git & Best Practices")
+ page_num += 1
+
+ create_content_slide(story, styles, "Git Workflow Standards", [
+ ("Branch Naming:", [
+ "feature/user-auth",
+ "fix/login-bug",
+ "refactor/api-cleanup"
+ ]),
+ ("Commit Format:", [
+ "feat(auth): add user registration",
+ "fix(auth): handle duplicate email error",
+ "test(auth): add E2E tests for login"
+ ]),
+ ("Hard Rules:", [
+ "Never commit to main directly",
+ "Never skip pre-commit checks",
+ "Never commit secrets"
+ ])
+ ])
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Exercise: Create Proper Commits",
+"""Ask your AI assistant:
+
+Help me commit my authentication feature properly.
+
+My changes include:
+- Database migration for users table
+- Repository layer
+- API handlers
+- E2E tests
+- Unit tests
+
+Steps:
+1. Review what's changed: git status
+2. Stage all changes: git add .
+3. Create commit with conventional format
+
+Suggested commit message:
+feat(auth): add user registration and login
+
+- Add users table migration
+- Implement user repository with CRUD
+- Create register and login endpoints
+- Add E2E tests for all auth endpoints
+- Add unit tests for validation logic
+
+After committing, verify with: git log --oneline -1""",
+ "Commit created with proper conventional commit message",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Exercise: Create Pull Request",
+"""Ask your AI assistant:
+
+Help me push my branch and create a pull request.
+
+Steps:
+1. Push branch to remote:
+ git push -u origin feature/user-auth
+
+2. Create PR (with GitHub CLI):
+ gh pr create --title "feat: Add user authentication" \\
+ --body "## Summary
+ - User registration endpoint
+ - User login endpoint
+ - JWT token authentication
+ - E2E tests (7 passing)
+ - Unit tests for validation
+
+ ## Testing
+ - All E2E tests pass
+ - All unit tests pass
+ - Manual testing completed
+
+ ## Checklist
+ - [x] Code follows project conventions
+ - [x] Tests added
+ - [x] Documentation updated"
+
+Or create PR through GitHub web interface.""",
+ "PR created on GitHub with description",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_content_slide(story, styles, "Effective Prompt Engineering", [
+ ("Be Specific:", [
+ 'Not "add validation" but "validate email format and password min 8 chars"'
+ ]),
+ ("Provide Context:", [
+ "Reference existing patterns in the codebase",
+ "Specify where files should be placed"
+ ]),
+ ("Include Success Criteria:", [
+ '"Tests should pass"',
+ '"Return proper HTTP status codes"'
+ ]),
+ ("Break Down Complex Tasks:", [
+ "Number your steps",
+ "Validate after each step"
+ ])
+ ])
+ page_num += 1
+
+ create_two_column_slide(
+ story, styles,
+ "Good vs Bad Prompts",
+ "❌ Bad",
+ [
+ '"Add search"',
+ '"Fix the bug"',
+ '"Make it faster"',
+ '"Add validation"'
+ ],
+ "✅ Good",
+ [
+ '"Add search: filter by email, case-insensitive, return paginated"',
+ '"Fix: login returns 500 when email contains + character"',
+ '"Add pagination: 20 per page, cursor-based, sort by created_at"',
+ '"Validate: email format, password 8+ chars, both required"'
+ ]
+ )
+ page_num += 1
+
+ # =================
+ # PART 6: FINAL CHALLENGE
+ # =================
+ create_section_slide(story, styles, "Part 6: Final Challenge")
+ page_num += 1
+
+ create_content_slide(story, styles, "Final Exercise: Complete Feature", [
+ ("Build ONE of these features end-to-end:", [
+ "Option A: GET /api/auth/me - Get current user profile",
+ "Option B: PUT /api/auth/password - Change password",
+ "Option C: POST /api/auth/logout - Logout (invalidate token)"
+ ]),
+ ("Follow the full workflow:", [
+ "1. Write specification",
+ "2. Update database if needed",
+ "3. Implement repository and handler",
+ "4. Write E2E tests",
+ "5. Add unit tests if applicable",
+ "6. Commit and add to PR"
+ ]),
+ "Time: 25 minutes"
+ ])
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Final Challenge: Your Feature",
+"""Choose ONE feature and implement it fully:
+
+OPTION A: GET /api/auth/me
+- Returns current user info from JWT token
+- Response: { id, email, created_at }
+- Tests: valid token returns user, invalid token returns 401
+
+OPTION B: PUT /api/auth/password
+- Request: { current_password, new_password }
+- Verify current password, update to new
+- Tests: success, wrong current password, weak new password
+
+OPTION C: POST /api/auth/logout
+- Invalidate current token (add to blacklist)
+- Tests: logout succeeds, token no longer works
+
+Steps:
+1. Tell AI which feature you chose
+2. Have AI implement it
+3. Review the code
+4. Run tests
+5. Commit with conventional format
+
+Time limit: 25 minutes""",
+ "New feature implemented with passing tests and committed",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ # =================
+ # WRAP-UP
+ # =================
+ create_section_slide(story, styles, "Wrap-Up")
+ page_num += 1
+
+ create_content_slide(story, styles, "What We Built Today", [
+ "✓ Project from scratch with proper structure",
+ "✓ Project rules file (CLAUDE.md)",
+ "✓ User authentication feature",
+ "✓ Database migration",
+ "✓ Repository and API layers",
+ "✓ E2E tests (7+ test cases)",
+ "✓ Unit tests",
+ "✓ Proper Git workflow",
+ "✓ Pull request ready for review"
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Key Takeaways", [
+ "AI executes 100%, Human validates 100%",
+ "Always write specs BEFORE AI implements",
+ "Review every piece of AI-generated code",
+ "Tests are mandatory (E2E + Unit)",
+ "Use project rules file to maintain consistency",
+ "Conventional commits and proper Git workflow",
+ "Break complex tasks into smaller steps"
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Resources & Next Steps", [
+ ("Reference Repository:", [
+ "github.com/emmanuelandre/unveiling-claude",
+ "Study the patterns, adapt for your projects"
+ ]),
+ ("AI Tools:", [
+ "Claude Code: claude.ai/code",
+ "Windsurf: codeium.com/windsurf",
+ "Cursor: cursor.sh"
+ ]),
+ ("Your Next Project:", [
+ "Start with a project rules file",
+ "Use the 10-step workflow",
+ "Build good habits from day one"
+ ])
+ ])
+ page_num += 1
+
+ # =================
+ # THANK YOU
+ # =================
+ create_thank_you_slide(story, styles, "Thank You!", "Happy Building! 🚀")
+
+ # Build PDF
+ doc.build(story, canvasmaker=NumberedCanvas)
+ print("✅ Workshop presentation created: ai-first-workshop.pdf")
+
+ # Export prompts
+ export_prompts_to_markdown(
+ ALL_PROMPTS,
+ "workshop-prompts.md",
+ "AI-First Workshop Prompts"
+ )
+ print("✅ Workshop prompts exported: workshop-prompts.md")
+
+
+if __name__ == "__main__":
+ create_presentation()
diff --git a/create_interactive_presentation_v2.py b/create_interactive_presentation_v2.py
index 79c09a1..0a1505f 100644
--- a/create_interactive_presentation_v2.py
+++ b/create_interactive_presentation_v2.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
"""
-Generate comprehensive interactive Claude Code tutorial presentation
+Generate comprehensive interactive AI-First Development tutorial presentation
+Supports Claude Code and Windsurf IDE
All examples use React (frontend) and Go (backend)
Properly formatted prompts with line breaks
"""
@@ -61,16 +62,16 @@ def create_title_slide(story, styles):
"""Title slide"""
story.append(Spacer(1, 1.5*inch))
- title = Paragraph('Claude Code', styles['Title'])
+ title = Paragraph('AI-First Development', styles['Title'])
story.append(title)
story.append(Spacer(1, 0.2*inch))
- subtitle = Paragraph('Interactive Tutorial & Workshop', styles['Title'])
+ subtitle = Paragraph('Interactive Tutorial & Workshop', styles['Title'])
story.append(subtitle)
- story.append(Spacer(1, 0.3*inch))
+ story.append(Spacer(1, 0.2*inch))
- desc = Paragraph('AI-First Development for Modern Software Teams', styles['Title'])
- story.append(desc)
+ tools = Paragraph('Using Claude Code, Windsurf, and AI Coding Assistants', styles['Title'])
+ story.append(tools)
story.append(PageBreak())
@@ -209,8 +210,69 @@ def export_prompts_to_markdown():
f.write('\n```\n\n')
f.write(f'**EXPECTED RESULT:**\n')
f.write(f'{item["expected"]}\n\n')
+
+ # Add reference examples for specific pages
+ if item["page"] == 9:
+ f.write('\n**REFERENCE EXAMPLE:**\n')
+ f.write('Compare your generated CLAUDE.md with `examples/my-api-project/CLAUDE.md` to see a production-ready example.\n\n')
+ elif item["page"] == 15:
+ f.write('\n**REFERENCE EXAMPLE:**\n')
+ f.write('See `examples/my-api-project/migrations/001_create_users.up.sql` for a complete migration including:\n')
+ f.write('- Proper index on email column\n')
+ f.write('- Automatic updated_at trigger\n')
+ f.write('- Both up.sql and down.sql files\n\n')
+
f.write('---\n\n')
+ # Add new documentation organization exercises at the end
+ f.write('## NEW: Documentation Organization Exercise\n\n')
+ f.write('**PROMPT:**\n```\n')
+ f.write('''I'm starting a new project. Help me decide on documentation structure.
+
+Project details:
+- Solo developer
+- 3-month project
+- Single Go API service
+- ~40 tasks estimated
+
+Based on these factors, should I use:
+A) Simple flat structure (plan.md, architecture.md at root)
+B) Nested structure (project/planning/, project/specs/)
+
+Create the appropriate documentation files for my choice.
+Include:
+- plan.md or devplan.md with milestones
+- architecture.md with system design
+- requirements.md with key features
+''')
+ f.write('```\n\n')
+ f.write('**EXPECTED RESULT:**\n')
+ f.write('Claude recommends nested structure (40 tasks, 3 months) and creates starter files\n\n')
+ f.write('**REFERENCE:**\n')
+ f.write('See [docs/12-documentation-organization.md](docs/12-documentation-organization.md) for decision criteria and templates.\n\n')
+ f.write('---\n\n')
+
+ f.write('## NEW: Migrate Flat to Nested Structure\n\n')
+ f.write('**PROMPT:**\n```\n')
+ f.write('''My project has grown. I started with simple flat docs:
+- plan.md
+- architecture.md
+- requirements.md
+
+Now I have 50+ tasks across 5 features. Help me migrate to
+the nested structure:
+- Move plan.md content to project/planning/devplan.md
+- Create project/planning/devprogress.md for tracking
+- Split requirements into project/specs/ by feature
+- Keep architecture.md updated
+
+Preserve all existing content during migration.
+''')
+ f.write('```\n\n')
+ f.write('**EXPECTED RESULT:**\n')
+ f.write('Documentation migrated to nested structure with content preserved\n\n')
+ f.write('---\n\n')
+
def create_presentation():
"""Generate the complete interactive presentation"""
doc = SimpleDocTemplate(
@@ -233,6 +295,8 @@ def create_presentation():
# AGENDA
create_content_slide(story, styles, "Workshop Agenda", [
"Part 1: Philosophy & Foundation",
+ "Addressing Common Concerns about AI-First Development",
+ "Prompt Engineering vs Vibe Coding",
"Part 2: Getting Started Hands-On",
"Part 3: Core Workflow (Interactive)",
"Part 4: Testing Strategy (Live Demo)",
@@ -280,16 +344,211 @@ def create_presentation():
create_content_slide(story, styles, "Testing Philosophy", [
"E2E tests are MANDATORY (API + UI user journeys)",
- "Unit tests are MANDATORY (business logic, utilities, edge cases)",
- "Component tests are GOOD TO HAVE (test containers for microservices)",
+ "Unit tests are MANDATORY (business logic, edge cases)",
+ "Component tests are GOOD TO HAVE (microservices)",
("Test-First Approach:", [
"Define coverage targets before implementation",
- "Build testing infrastructure/framework first",
- "Track coverage from unit, component, and E2E tests",
- "Coverage thresholds vary by project (higher is better)",
+ "Build testing infrastructure first",
"Tests are your regression safety net"
+ ])
+ ])
+ page_num += 1
+
+ # =================
+ # ADDRESSING COMMON CONCERNS
+ # =================
+ create_section_slide(story, styles, "Addressing Common Concerns")
+ page_num += 1
+
+ create_content_slide(story, styles, "Common Concerns About AI-First Development", [
+ "1. Code Quality & Reliability - Hallucinations, hidden bugs",
+ "2. Security Risks - Insecure patterns, data leakage",
+ "3. Maintainability & Technical Debt - Opaque code, inconsistent style",
+ "4. Design Integrity - Architecture drift, loss of intent",
+ "5. Testing & Validation - False sense of coverage",
+ "6. IP & Compliance - License ambiguity, auditability",
+ "7. Developer Experience - Skill atrophy, workflow disruption",
+ "8. Accountability - Who owns AI-generated bugs?"
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Concern #1: Code Quality & Reliability", [
+ ("The Concern:", [
+ "AI generates syntactically correct but logically flawed code",
+ "Hidden bugs pass tests but fail in edge cases",
+ "Engineers might trust AI output without validation"
+ ]),
+ ("How We Address It:", [
+ "Human validates 100% - Every line is reviewed",
+ "Mandatory E2E tests catch integration issues",
+ "Pre-commit checks enforce quality gates",
+ "Three-layer review: Self → Automated → Peer"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Concern #2: Security Risks", [
+ ("The Concern:", [
+ "AI might introduce vulnerabilities",
+ "Proprietary code exposed to AI tools"
+ ]),
+ ("How We Address It:", [
+ "Security checklist in code review",
+ "Automated security scanning in CI",
+ "Explicit prompts for secure patterns"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "How Your Data is Handled", [
+ ("Your code stays on your machine:", [
+ "AI assistants run locally",
+ "Files are read/written locally"
+ ]),
+ ("When you ask for help:", [
+ "Relevant code sent to AI API as context",
+ "Processed but NOT stored on AI servers",
+ "Similar to pasting code in chat"
+ ]),
+ ("Different from cloud IDEs:", [
+ "Cloud IDEs store your code remotely",
+ "AI assistants only send context when asked"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Concern #3: Maintainability & Technical Debt", [
+ ("The Concern:", [
+ "AI-generated code hard to understand/maintain",
+ "Suggestions may not follow team conventions"
+ ]),
+ ("How We Address It:", [
+ "Project rules (CLAUDE.md / Windsurf Rules) define conventions",
+ "Consistent patterns across codebase",
+ "Human review catches non-idiomatic code"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Concern #4: Design Integrity", [
+ ("The Concern:", [
+ "AI optimizes locally, not holistically",
+ "May ignore design principles (SOLID)"
+ ]),
+ ("How We Address It:", [
+ "Architecture in project rules (CLAUDE.md / Windsurf Rules)",
+ "Human writes specs BEFORE AI implements",
+ "Design decisions in ADRs",
+ "AI follows existing patterns"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Concern #5: Testing & Validation", [
+ ("The Concern:", [
+ "AI generates tests that don't cover real scenarios",
+ "Non-deterministic outputs hard to debug",
+ "AI-generated modules may not integrate well"
+ ]),
+ ("How We Address It:", [
+ "Test-first approach - define tests before implementation",
+ "E2E tests validate complete user journeys",
+ "Human verifies test quality, not just coverage",
+ "Integration testing mandatory in CI"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Concerns #6-8: IP, Experience & Accountability", [
+ ("IP & Compliance:", [
+ "Review AI suggestions for license issues",
+ "Keep audit trail of AI-generated code in commits"
+ ]),
+ ("Developer Experience:", [
+ "AI executes, Human validates - skills remain sharp",
+ "Review process maintains deep code understanding",
+ "Pair programming with AI, not replacement"
+ ]),
+ ("Accountability:", [
+ "Human approves every PR - human owns the code",
+ "Clear handoffs document who validated what",
+ "Git history shows human review at each step"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "The Bottom Line", [
+ "AI-First ≠ AI-Only",
+ ("The methodology addresses concerns through:", [
+ "Systematic validation at every step",
+ "Comprehensive testing (E2E + Unit)",
+ "Clear human ownership and accountability",
+ "Documented conventions in project rules"
+ ]),
+ "Result: Faster development WITH maintained quality"
+ ])
+ page_num += 1
+
+ # =================
+ # PROMPT ENGINEERING VS VIBE CODING
+ # =================
+ create_section_slide(story, styles, "Prompt Engineering vs Vibe Coding")
+ page_num += 1
+
+ create_content_slide(story, styles, "What is Vibe Coding?", [
+ "Informal, exploratory approach with minimal instructions",
+ ("Characteristics:", [
+ "Speed over precision",
+ "AI 'guesses' intent",
+ "Minimal context"
+ ]),
+ "Example: 'Make something that sorts numbers'",
+ ("Result:", [
+ "Quick for prototypes",
+ "Unpredictable code quality"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "What is Prompt Engineering?", [
+ "Precise, structured inputs to guide AI behavior",
+ ("Characteristics:", [
+ "Context and constraints provided",
+ "Clear success criteria"
+ ]),
+ "Example: 'Write Python function to sort integers ascending, no built-in sort'",
+ ("Result:", [
+ "Predictable, production code",
+ "Consistent with standards"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Side-by-Side Comparison", [
+ ("Speed:", [
+ "Vibe: Fast initial results",
+ "Prompt: Less rework overall"
+ ]),
+ ("Quality:", [
+ "Vibe: Unpredictable",
+ "Prompt: Consistent"
+ ]),
+ ("Best For:", [
+ "Vibe: Prototypes",
+ "Prompt: Production code"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "This Workshop Uses Prompt Engineering", [
+ "Structured, production-quality prompting",
+ ("The AI-First workflow:", [
+ "Human writes specification",
+ "AI executes within boundaries",
+ "Human validates output"
]),
- "Measure coverage to ensure quality and confidence"
+ "Flow: Spec → Schema → Code → Tests",
+ "Result: Code you can ship to production"
])
page_num += 1
@@ -832,30 +1091,28 @@ def create_presentation():
page_num += 1
create_content_slide(story, styles, "Keys to Success", [
- ("1. CLAUDE.md is essential", [
- "Keep it current and comprehensive",
- "Document all conventions and patterns"
+ ("1. Project rules are essential", [
+ "CLAUDE.md / Windsurf Rules - keep current",
+ "Document conventions and patterns"
]),
("2. Clear handoffs between AI and human", [
- "AI completes a step fully before handoff",
+ "AI completes step fully before handoff",
"Human approves or requests changes"
]),
- ("3. Systematic quality gates", [
- "Tests must pass before proceeding",
- "Reviews must approve before merging"
+ ("3. Quality gates", [
+ "Tests pass before proceeding",
+ "Reviews approve before merging"
])
])
page_num += 1
create_content_slide(story, styles, "Common Mistakes to Avoid", [
- "❌ Vague prompts → Be specific with examples",
- "❌ Skipping tests → Always write E2E tests first",
- "❌ Committing untested code → Run checks locally",
- "❌ Ignoring CLAUDE.md → Keep it updated",
- "❌ Large unfocused PRs → Make small, atomic changes",
- "✅ Review all AI output before committing",
- "✅ Use conventional commits",
- "✅ Run pre-commit checks"
+ "❌ Vague prompts → Be specific",
+ "❌ Skipping tests → Write E2E tests first",
+ "❌ Untested commits → Run checks locally",
+ "❌ Ignoring project rules → Keep them updated",
+ "❌ Large PRs → Make atomic changes",
+ "✅ Review AI output before committing"
])
page_num += 1
@@ -893,15 +1150,13 @@ def create_presentation():
create_content_slide(story, styles, "The Challenge of Large Projects", [
("When projects grow:", [
- "100+ tasks across multiple modules",
- "Complex dependencies between features",
- "Weeks or months of development",
- "Context loss between sessions",
- "Need systematic progress tracking"
+ "100+ tasks across modules",
+ "Complex dependencies",
+ "Context loss between sessions"
]),
("The Solution:", [
- "Phased development with living documentation",
- "Centralized project planning structure",
+ "Phased development",
+ "Centralized planning structure",
"Continuous progress monitoring"
])
])
@@ -910,47 +1165,40 @@ def create_presentation():
create_content_slide(story, styles, "Project Planning Structure", [
("Directory Layout:", [
"project/planning/ - Master plan and progress",
- "project/specs/ - Detailed feature specifications",
- "project/sessions/ - Session summaries",
- "project/development/ - Quick reference guides"
+ "project/specs/ - Feature specifications",
+ "project/sessions/ - Session summaries"
]),
("Key Files:", [
- "devplan.md - Master plan with all phases",
- "devprogress.md - Living progress tracker",
- "database.md - Complete schema documentation",
- "Session notes - What happened each session"
+ "devplan.md - Master plan with phases",
+ "devprogress.md - Progress tracker",
+ "database.md - Schema documentation"
])
])
page_num += 1
create_content_slide(story, styles, "The Master Plan (devplan.md)", [
("Contains:", [
- "10 phases with clear objectives",
- "Dependency mapping (what depends on what)",
- "Vertical slice workflow per feature",
- "All tasks with checkboxes",
- "Estimated timelines"
+ "Phases with clear objectives",
+ "Dependency mapping",
+ "Tasks with checkboxes"
]),
("Workflow per Feature:", [
- "DB → Backend API → API Tests → UI → UI Tests → Docs",
- "Complete each layer before moving forward",
- "Never skip the testing phases"
+ "DB → API → Tests → UI → UI Tests",
+ "Complete each layer before moving",
+ "Never skip testing"
])
])
page_num += 1
create_content_slide(story, styles, "Progress Tracker (devprogress.md)", [
("Update After Every Session:", [
- "Mark completed tasks with [x]",
+ "Mark completed tasks [x]",
"Update phase percentages",
- "Track current sprint goals",
- "Document blockers and decisions",
- "Calculate overall progress"
+ "Document blockers"
]),
("Quick Stats Table:", [
- "Phase | Status | Progress | Backend | UI | Tests",
- "🔴 Not Started | 🟡 In Progress | 🟢 Complete",
- "Visual overview of project health"
+ "Phase | Status | Progress",
+ "🔴 Not Started | 🟡 In Progress | 🟢 Complete"
])
])
page_num += 1
@@ -1105,38 +1353,30 @@ def create_presentation():
create_content_slide(story, styles, "Best Practices for Large Projects", [
("Update Progress Religiously:", [
- "After every session - mark completed tasks",
- "Calculate percentages accurately",
- "Document blockers immediately",
- "Create session notes with decisions"
+ "Mark tasks after every session",
+ "Document blockers immediately"
]),
("Keep Plans vs Reality Aligned:", [
- "devplan.md = original blueprint (stable)",
- "devprogress.md = current reality (dynamic)",
- "Adjust plan when reality diverges significantly"
+ "devplan.md = blueprint (stable)",
+ "devprogress.md = reality (dynamic)"
]),
("Use Phase-Based Branches:", [
- "phase-0-foundation, phase-1-projects, etc.",
- "Complete entire phase before merging",
- "Easier to track and review large changes"
+ "phase-0-foundation, phase-1-projects",
+ "Complete phase before merging"
])
])
page_num += 1
create_content_slide(story, styles, "When to Use This Approach", [
("Small Projects (<20 tasks):", [
- "❌ Don't need planning structure",
- "✅ Simple CLAUDE.md is enough"
+ "Simple project rules file is enough"
]),
("Medium Projects (20-50 tasks):", [
- "✅ Create devplan.md and devprogress.md",
- "✅ Update progress after sessions"
+ "Create devplan.md and devprogress.md"
]),
("Large Projects (50+ tasks):", [
- "✅ Full planning structure",
- "✅ Daily progress updates",
- "✅ Session notes after every session",
- "✅ Detailed specs for complex features"
+ "Full planning structure",
+ "Session notes after every session"
])
])
page_num += 1
@@ -1148,28 +1388,25 @@ def create_presentation():
page_num += 1
create_content_slide(story, styles, "What We Learned", [
- "✓ AI-First philosophy: AI executes, Human validates",
+ "✓ AI-First: AI executes, Human validates",
"✓ 10-step systematic development process",
"✓ E2E tests as primary testing strategy",
- "✓ Proper git workflow and conventional commits",
- "✓ Effective prompt engineering techniques",
- "✓ CLAUDE.md as project instruction manual",
- "✓ Scaling to large projects with phased planning",
- "✓ Progress tracking with devplan.md and devprogress.md",
- "✓ Quality gates at every step"
+ "✓ Git workflow and conventional commits",
+ "✓ Prompt engineering techniques",
+ "✓ Project rules (CLAUDE.md / Windsurf Rules)",
+ "✓ Phased planning for large projects"
])
page_num += 1
create_content_slide(story, styles, "Your Action Plan", [
("Next Steps:", [
- "1. Create CLAUDE.md for your project",
- "2. Set up git workflow (branches, conventional commits)",
+ "1. Create project rules file (CLAUDE.md / Windsurf Rules)",
+ "2. Set up git workflow",
"3. Start with one feature using 10-step process",
- "4. Write E2E tests for everything",
- "5. Review and iterate"
+ "4. Write E2E tests for everything"
]),
("Resources:", [
- "Claude Code: claude.ai/code",
+ "AI Assistants: Claude Code, Windsurf",
"Prompts: See prompts.md file"
])
])
diff --git a/create_lecture_presentation.py b/create_lecture_presentation.py
new file mode 100644
index 0000000..3ac9cac
--- /dev/null
+++ b/create_lecture_presentation.py
@@ -0,0 +1,742 @@
+#!/usr/bin/env python3
+"""
+Generate 1-hour AI-First Development lecture presentation.
+No hands-on exercises - practitioner-level depth with actionable takeaways.
+Tool-agnostic with Claude Code/Windsurf as examples.
+"""
+
+from reportlab.lib.styles import getSampleStyleSheet
+from presentation_utils import (
+ create_document,
+ create_title_slide,
+ create_section_slide,
+ create_content_slide,
+ create_two_column_slide,
+ create_code_slide,
+ create_thank_you_slide,
+ NumberedCanvas
+)
+
+
+def create_presentation():
+ """Generate the complete lecture presentation."""
+ doc = create_document("ai-first-lecture.pdf")
+ styles = getSampleStyleSheet()
+ story = []
+
+ # =================
+ # TITLE
+ # =================
+ create_title_slide(
+ story, styles,
+ "AI-First Development",
+ "A Practitioner's Guide",
+ "Applicable to Claude Code, Windsurf, Cursor, and other AI coding assistants"
+ )
+
+ # =================
+ # AGENDA
+ # =================
+ create_content_slide(story, styles, "Agenda", [
+ "1. AI-First Philosophy",
+ "2. Addressing Common Concerns",
+ "3. Prompt Engineering vs Vibe Coding",
+ "4. Getting Started with Prompt Engineering",
+ "5. Scaling to Large Projects",
+ "6. Best Practices for Feature Documentation",
+ "7. Testing Strategies",
+ "8. Project Planning & Workflow",
+ "9. Git Best Practices",
+ "10. Tips & Tricks"
+ ])
+
+ # =================
+ # SECTION 1: AI-FIRST PHILOSOPHY
+ # =================
+ create_section_slide(story, styles, "1. AI-First Philosophy")
+
+ create_content_slide(story, styles, "What is AI-First Development?", [
+ "Traditional: Human writes code → AI assists occasionally",
+ "AI-First: AI executes 100% → Human validates 100%",
+ ("Key distinction:", [
+ "AI handles ALL coding, testing, documentation",
+ "Human handles ALL validation, review, decisions",
+ "Clear handoff points at each step"
+ ]),
+ "Takeaway: Humans become architects & validators, AI becomes the builder"
+ ])
+
+ create_content_slide(story, styles, "Core Development Principles", [
+ ("Specifications Drive Implementation:", [
+ "Database schema → API contracts → UI components",
+ "Write specs BEFORE AI implements"
+ ]),
+ ("Micro-Teams of 2:", [
+ "2 humans + AI assistant = redundancy without overhead",
+ "Each team owns end-to-end features"
+ ]),
+ ("Own Your Stack:", [
+ "Be your own QA engineer",
+ "Be your own DevOps engineer",
+ "Own the entire vertical slice"
+ ])
+ ])
+
+ create_content_slide(story, styles, "The Paradigm Shift", [
+ ("From:", [
+ '"AI helps me write code"',
+ '"Let me ask AI to fix this bug"',
+ '"AI suggests completions"'
+ ]),
+ ("To:", [
+ '"AI executes my specifications"',
+ '"I validate what AI produced"',
+ '"AI implements the full feature"'
+ ]),
+ "Takeaway: Treat AI as your execution engine, not just an assistant"
+ ])
+
+ create_content_slide(story, styles, "When AI-First Works Best", [
+ ("Ideal scenarios:", [
+ "New features with clear requirements",
+ "CRUD operations and API endpoints",
+ "Test generation and documentation",
+ "Refactoring with defined patterns"
+ ]),
+ ("Less ideal scenarios:", [
+ "Real-time pair programming",
+ "Highly visual design work",
+ "Hardware-specific debugging"
+ ])
+ ])
+
+ # =================
+ # SECTION 2: ADDRESSING COMMON CONCERNS
+ # =================
+ create_section_slide(story, styles, "2. Addressing Common Concerns")
+
+ create_content_slide(story, styles, "Common Concerns Engineers Raise", [
+ "1. Code Quality & Reliability - Hallucinations, hidden bugs",
+ "2. Security Risks - Insecure patterns, data exposure",
+ "3. Maintainability - Opaque code, inconsistent style",
+ "4. Design Integrity - Architecture drift, loss of intent",
+ "5. Testing & Validation - False sense of coverage",
+ "6. IP & Compliance - License ambiguity",
+ "7. Developer Experience - Skill atrophy",
+ "8. Accountability - Who owns AI-generated bugs?"
+ ])
+
+ create_content_slide(story, styles, "Code Quality & Security", [
+ ("The Concern:", [
+ "AI generates syntactically correct but logically flawed code",
+ "AI might introduce vulnerabilities"
+ ]),
+ ("How We Address It:", [
+ "Human validates 100% - every line is reviewed",
+ "Mandatory E2E tests catch integration issues",
+ "Pre-commit checks enforce quality gates",
+ "Three-layer review: Self → Automated → Peer"
+ ]),
+ "Takeaway: Trust but verify - always review AI output"
+ ])
+
+ create_content_slide(story, styles, "Maintainability & Design", [
+ ("The Concern:", [
+ "AI-generated code hard to understand",
+ "May not follow team conventions",
+ "Optimizes locally, not holistically"
+ ]),
+ ("How We Address It:", [
+ "Project rules file defines conventions (CLAUDE.md, .windsurfrules)",
+ "Architecture documented upfront",
+ "Human writes specs BEFORE AI implements",
+ "AI follows existing patterns"
+ ]),
+ "Takeaway: Document your standards where AI can read them"
+ ])
+
+ create_content_slide(story, styles, "Testing, IP & Accountability", [
+ ("Testing:", [
+ "Test-first approach - define tests before implementation",
+ "Human verifies test quality, not just coverage"
+ ]),
+ ("IP & Compliance:", [
+ "Review AI suggestions for license issues",
+ "Keep audit trail in commit history"
+ ]),
+ ("Accountability:", [
+ "Human approves every PR = human owns the code",
+ "Git history shows human review at each step"
+ ]),
+ "Takeaway: Human approval = Human ownership"
+ ])
+
+ create_content_slide(story, styles, "The Bottom Line", [
+ "AI-First ≠ AI-Only",
+ ("The methodology addresses concerns through:", [
+ "Systematic validation at every step",
+ "Comprehensive testing (E2E + Unit)",
+ "Clear human ownership and accountability",
+ "Documented conventions in project rules"
+ ]),
+ "Result: Faster development WITH maintained quality"
+ ])
+
+ # =================
+ # SECTION 3: PROMPT VS VIBE
+ # =================
+ create_section_slide(story, styles, "3. Prompt Engineering vs Vibe Coding")
+
+ create_content_slide(story, styles, "What is Vibe Coding?", [
+ "Informal, exploratory approach with minimal instructions",
+ ("Characteristics:", [
+ "Speed over precision",
+ 'AI "guesses" intent',
+ "Minimal context provided"
+ ]),
+ 'Example: "Make something that sorts numbers"',
+ ("Result:", [
+ "Quick for prototypes",
+ "Unpredictable code quality"
+ ])
+ ])
+
+ create_content_slide(story, styles, "What is Prompt Engineering?", [
+ "Precise, structured inputs to guide AI behavior",
+ ("Characteristics:", [
+ "Context and constraints provided",
+ "Clear success criteria",
+ "Examples included when helpful"
+ ]),
+ 'Example: "Write Python function to sort integers ascending, no built-in sort, return new list"',
+ "Result: Predictable, production-ready code"
+ ])
+
+ create_two_column_slide(
+ story, styles,
+ "Side-by-Side Comparison",
+ "Vibe Coding",
+ [
+ "Fast initial results",
+ "Unpredictable quality",
+ "Best for prototypes",
+ "More rework later",
+ "Hard to maintain"
+ ],
+ "Prompt Engineering",
+ [
+ "Slower initial setup",
+ "Consistent quality",
+ "Best for production",
+ "Less rework overall",
+ "Easy to maintain"
+ ]
+ )
+
+ create_content_slide(story, styles, "When to Use Each", [
+ ("Use Vibe Coding for:", [
+ "Quick prototypes and experiments",
+ "Exploring APIs or libraries",
+ "Throwaway code"
+ ]),
+ ("Use Prompt Engineering for:", [
+ "Production code",
+ "Team projects",
+ "Anything that will be maintained",
+ "Code that needs tests"
+ ]),
+ "Takeaway: Default to prompt engineering for professional work"
+ ])
+
+ # =================
+ # SECTION 4: PROMPT ENGINEERING
+ # =================
+ create_section_slide(story, styles, "4. Getting Started with Prompt Engineering")
+
+ create_content_slide(story, styles, "Core Prompt Principles", [
+ ("Be Specific:", [
+ 'Not "fix the bug" but "fix the race condition in token refresh"'
+ ]),
+ ("Provide Context:", [
+ "Architecture, patterns, constraints",
+ "Reference specific files"
+ ]),
+ ("Define Success:", [
+ "What should work when done?",
+ "What tests should pass?"
+ ]),
+ "Takeaway: Treat prompts like specifications"
+ ])
+
+ create_two_column_slide(
+ story, styles,
+ "Good vs Bad Prompts",
+ "❌ Bad Prompts",
+ [
+ '"Add search to the API"',
+ '"Fix the authentication"',
+ '"Make it faster"',
+ '"Add validation"'
+ ],
+ "✅ Good Prompts",
+ [
+ '"Add search: filter by email/name, case-insensitive, debounce 300ms"',
+ '"Fix token refresh race condition when concurrent API calls"',
+ '"Add pagination to /users endpoint, 20 per page, cursor-based"',
+ '"Validate email format and password min 8 chars on registration"'
+ ]
+ )
+
+ create_content_slide(story, styles, "Prompt Patterns", [
+ ("Feature Request:", [
+ "Requirements → Technical Details → Success Criteria"
+ ]),
+ ("Bug Fix:", [
+ "Expected vs Actual → Steps to Reproduce → Error Message"
+ ]),
+ ("Multi-Step:", [
+ "Break into numbered steps",
+ "Define validation at each step"
+ ]),
+ "Takeaway: Use templates for consistent results"
+ ])
+
+ create_code_slide(story, styles, "Example: Well-Structured Prompt", "prompt",
+"""I need to implement user authentication for my API.
+
+Requirements:
+- Users register with email/password
+- JWT tokens for authentication
+- Password hashing with bcrypt
+
+API Endpoints:
+POST /api/auth/register - Register new user
+POST /api/auth/login - Login and get JWT
+
+Success Criteria:
+- Passwords never stored in plain text
+- JWT expires after 1 hour
+- E2E tests cover happy path and error cases
+
+Please create the database migration first.""")
+
+ create_content_slide(story, styles, "Common Prompt Mistakes", [
+ ("Over-reliance:", [
+ '"Build me a complete e-commerce platform"',
+ "Fix: Break into smaller, specific requests"
+ ]),
+ ("Under-specification:", [
+ '"Add validation"',
+ "Fix: Specify what to validate and how"
+ ]),
+ ("Forgetting Tests:", [
+ '"Implement user authentication"',
+ 'Fix: Add "Include E2E tests for..."'
+ ])
+ ])
+
+ # =================
+ # SECTION 5: SCALING LARGE PROJECTS
+ # =================
+ create_section_slide(story, styles, "5. Scaling to Large Projects")
+
+ create_content_slide(story, styles, "The Challenge of Large Projects", [
+ ("When projects grow:", [
+ "100+ tasks across modules",
+ "Complex dependencies",
+ "Context loss between sessions"
+ ]),
+ ("The Solution:", [
+ "Phased development",
+ "Centralized planning structure",
+ "Continuous progress tracking"
+ ])
+ ])
+
+ create_content_slide(story, styles, "Project Planning Structure", [
+ ("Directory Layout:", [
+ "project/planning/ - Master plan and progress",
+ "project/specs/ - Feature specifications",
+ "project/sessions/ - Session summaries"
+ ]),
+ ("Key Files:", [
+ "devplan.md - Master plan with phases and dependencies",
+ "devprogress.md - Progress tracker with checkboxes",
+ "database.md - Schema documentation"
+ ]),
+ "Takeaway: Organize documentation for AI consumption"
+ ])
+
+ create_content_slide(story, styles, "The Master Plan (devplan.md)", [
+ ("Contains:", [
+ "Phases with clear objectives",
+ "Dependency mapping between features",
+ "Tasks with checkboxes"
+ ]),
+ ("Workflow per Feature:", [
+ "DB → API → Tests → UI → UI Tests",
+ "Complete each layer before moving on",
+ "Never skip testing"
+ ])
+ ])
+
+ create_content_slide(story, styles, "Progress Tracking (devprogress.md)", [
+ ("Update After Every Session:", [
+ "Mark completed tasks [x]",
+ "Update phase percentages",
+ "Document blockers"
+ ]),
+ ("Quick Stats Table:", [
+ "Phase | Status | Progress",
+ "🔴 Not Started | 🟡 In Progress | 🟢 Complete"
+ ]),
+ "Takeaway: Update progress religiously - it's your context for next session"
+ ])
+
+ create_content_slide(story, styles, "When to Use What", [
+ ("Small Projects (<20 tasks):", [
+ "Simple project rules file is enough"
+ ]),
+ ("Medium Projects (20-50 tasks):", [
+ "Add devplan.md and devprogress.md"
+ ]),
+ ("Large Projects (50+ tasks):", [
+ "Full planning structure",
+ "Session notes after every session"
+ ]),
+ "Takeaway: Scale documentation with project complexity"
+ ])
+
+ # =================
+ # SECTION 6: FEATURE DOCUMENTATION
+ # =================
+ create_section_slide(story, styles, "6. Best Practices for Feature Documentation")
+
+ create_content_slide(story, styles, "The 5-Document Approach", [
+ "For large features, create 5 documents:",
+ ("1. Planning Document (What & When):", [
+ "Timeline, scope, decisions, success criteria"
+ ]),
+ ("2. Architecture Document (How):", [
+ "System diagrams, database schema, error handling"
+ ]),
+ ("3. API Contracts (Interface):", [
+ "Endpoints, request/response examples, error codes"
+ ]),
+ ("4. User Journey (Experience):", [
+ "Personas, step-by-step flows, edge cases"
+ ]),
+ ("5. UI Wireframes (Visuals):", [
+ "Page layouts, component specs, responsive design"
+ ])
+ ])
+
+ create_content_slide(story, styles, "Planning Document Structure", [
+ ("Key Sections:", [
+ "Related Documentation - links to other docs",
+ "Overview - problem statement and solution",
+ "Key Decisions - with rationale",
+ "Scope - what's in and explicitly out",
+ "Implementation Phases - with tasks",
+ "Critical Files - all files to create/modify",
+ "Success Criteria - measurable goals"
+ ]),
+ "Takeaway: Explicit scope prevents scope creep"
+ ])
+
+ create_content_slide(story, styles, "Architecture & API Contracts", [
+ ("Architecture Document:", [
+ "ASCII system diagrams showing component interactions",
+ "Complete database schema with indexes",
+ "Error handling strategies"
+ ]),
+ ("API Contracts:", [
+ "Endpoint summary table",
+ "Request/response JSON examples",
+ "Error codes with descriptions"
+ ]),
+ "Takeaway: AI produces better code with precise contracts"
+ ])
+
+ create_content_slide(story, styles, "Design Review Process", [
+ ("Review Stages:", [
+ "Draft → Review → Approved → Implement"
+ ]),
+ ("Technical Review Focus:", [
+ "Architecture - does it integrate cleanly?",
+ "API Design - RESTful and consistent?",
+ "Database - indexes sufficient?",
+ "Security - auth and validation complete?"
+ ]),
+ "Takeaway: Catch issues early when changes are cheap"
+ ])
+
+ # =================
+ # SECTION 7: TESTING STRATEGIES
+ # =================
+ create_section_slide(story, styles, "7. Testing Strategies")
+
+ create_content_slide(story, styles, "Modern Testing Philosophy", [
+ "Both E2E and Unit tests are MANDATORY",
+ ("E2E Tests (Required):", [
+ "Complete user journeys",
+ "API endpoint testing",
+ "UI workflow testing"
+ ]),
+ ("Unit Tests (Required):", [
+ "Business logic",
+ "Utilities and helpers",
+ "Edge cases and data transformations"
+ ]),
+ ("Component Tests (When applicable):", [
+ "Microservices integration",
+ "Database operations with test containers"
+ ])
+ ])
+
+ create_content_slide(story, styles, "Test-First Approach", [
+ ("Before Implementation:", [
+ "Define coverage targets (70-90%)",
+ "Build testing infrastructure first",
+ "Document test scenarios"
+ ]),
+ ("During Implementation:", [
+ "Write tests alongside code",
+ "Run tests frequently",
+ "Don't proceed if tests fail"
+ ]),
+ "Takeaway: Tests are your regression safety net"
+ ])
+
+ create_content_slide(story, styles, "Testing Best Practices", [
+ "Test user journeys, not implementation details",
+ "Use data-test attributes for stable selectors",
+ ("Coverage priorities:", [
+ "Happy path - must pass",
+ "Critical failures - invalid inputs, permissions",
+ "Edge cases - boundary conditions",
+ "Error scenarios - network failures, timeouts"
+ ]),
+ "Run tests in pre-commit hooks",
+ "Takeaway: Tests that run automatically get run consistently"
+ ])
+
+ create_content_slide(story, styles, "Coverage Measurement", [
+ ("Track coverage from all test types:", [
+ "Unit test coverage",
+ "E2E test coverage",
+ "Component test coverage (if applicable)"
+ ]),
+ ("Merge coverage reports:", [
+ "See the complete picture",
+ "Identify gaps"
+ ]),
+ "Takeaway: Measure coverage from ALL test types combined"
+ ])
+
+ # =================
+ # SECTION 8: PROJECT PLANNING
+ # =================
+ create_section_slide(story, styles, "8. Project Planning & Workflow")
+
+ create_content_slide(story, styles, "The 10-Step Development Process", [
+ "1. Specification (Human writes detailed spec)",
+ "2. Database Schema (AI designs → Human reviews)",
+ "3. Repository Layer (AI implements → Human reviews)",
+ "4. API Endpoints (AI creates → Human reviews)",
+ "5. API E2E Tests (AI writes → Human verifies)",
+ "6. Frontend Components (AI builds → Human reviews)",
+ "7. UI E2E Tests (AI creates → Human verifies)",
+ "8. Documentation (AI updates → Human reviews)",
+ "9. Code Review (Human conducts)",
+ "10. Deployment (AI executes → Human verifies)"
+ ])
+
+ create_content_slide(story, styles, "Handoffs & Quality Gates", [
+ ("Each Step Has:", [
+ "Clear deliverables",
+ "Human approval checkpoint",
+ "Tests that must pass"
+ ]),
+ ("Quality Gates:", [
+ "Schema reviewed before repository",
+ "API tests pass before frontend",
+ "All tests pass before PR"
+ ]),
+ "Takeaway: Never skip a step, never skip a review"
+ ])
+
+ create_two_column_slide(
+ story, styles,
+ "AI vs Human Responsibilities",
+ "AI Executes",
+ [
+ "Design database schema",
+ "Implement repository layer",
+ "Create API endpoints",
+ "Write tests",
+ "Build UI components",
+ "Update documentation",
+ "Execute deployment"
+ ],
+ "Human Validates",
+ [
+ "Write specifications",
+ "Review all code",
+ "Verify tests are meaningful",
+ "Conduct code review",
+ "Merge pull requests",
+ "Make architectural decisions"
+ ]
+ )
+
+ # =================
+ # SECTION 9: GIT BEST PRACTICES
+ # =================
+ create_section_slide(story, styles, "9. Git Best Practices")
+
+ create_content_slide(story, styles, "Branch Naming & Commits", [
+ ("Branch Naming: /", [
+ "feature/user-auth",
+ "fix/login-bug",
+ "refactor/api-cleanup",
+ "docs/readme-update"
+ ]),
+ ("Conventional Commits: (): ", [
+ "feat(auth): add Google OAuth login",
+ "fix(api): handle null user gracefully",
+ "test(auth): add E2E tests for login flow"
+ ]),
+ "Takeaway: Consistent naming enables automation"
+ ])
+
+ create_content_slide(story, styles, "Pre-Commit Checks (Mandatory)", [
+ ("Must Run Before Every Commit:", [
+ "Lint - code formatting and style",
+ "Tests - unit and E2E tests",
+ "Build - verify it compiles/bundles"
+ ]),
+ ("Set Up Hooks:", [
+ "Use husky (Node) or pre-commit (Python)",
+ "Fail commit if any check fails"
+ ]),
+ "Takeaway: Catch issues locally, not in PR review"
+ ])
+
+ create_content_slide(story, styles, "Hard Rules", [
+ "❌ Never commit directly to main",
+ "❌ Never merge your own PR without review",
+ "❌ Never commit code that fails tests",
+ "❌ Never commit secrets (.env, credentials)",
+ "❌ Never force push to main",
+ ("AI Boundaries:", [
+ "✅ AI can: create branches, commit, push, open PRs",
+ "❌ AI cannot: merge PRs, approve PRs"
+ ]),
+ "Takeaway: Humans control what gets merged"
+ ])
+
+ # =================
+ # SECTION 10: TIPS & TRICKS
+ # =================
+ create_section_slide(story, styles, "10. Tips & Tricks")
+
+ create_content_slide(story, styles, "Communication Tips", [
+ ("Be Specific:", [
+ '"Fix the race condition in token refresh" not "fix the bug"'
+ ]),
+ ("Reference Files:", [
+ '"In src/models/user.ts, add email_verified field"'
+ ]),
+ ("Request Explanations:", [
+ '"Implement and explain the trade-offs"'
+ ]),
+ ("Verify Understanding:", [
+ '"Before implementing, confirm: Goal is X, constraints are Y"'
+ ])
+ ])
+
+ create_content_slide(story, styles, "Productivity Techniques", [
+ ("Multi-Step Requests:", [
+ "Number your steps",
+ "Define validation at each step"
+ ]),
+ ("Batch Related Changes:", [
+ '"Update all error responses to use format X"'
+ ]),
+ ("Progressive Refinement:", [
+ "Basic → Add feature → Add polish"
+ ]),
+ ("Start Sessions with Context:", [
+ '"Continuing work on X. Last session we did Y."'
+ ])
+ ])
+
+ create_content_slide(story, styles, "Working with Large Codebases", [
+ ("Navigate:", [
+ '"Show me all files that handle authentication"'
+ ]),
+ ("Understand First:", [
+ '"Explain how the current auth flow works"'
+ ]),
+ ("Refactor Safely:", [
+ '"Refactor X to Y. Ensure all existing tests pass."'
+ ]),
+ "Takeaway: Use AI to explore unfamiliar code"
+ ])
+
+ create_content_slide(story, styles, "Pro Tips Summary", [
+ "Start sessions with context",
+ "End sessions with notes (what was done, what's next)",
+ "Use checkpoints - commit after each logical step",
+ "Trust but verify - always review AI output",
+ "Keep project rules file current",
+ "Build a prompt library for your team",
+ "Takeaway: Document what prompts work for your project"
+ ])
+
+ # =================
+ # SUMMARY
+ # =================
+ create_section_slide(story, styles, "Summary & Action Plan")
+
+ create_content_slide(story, styles, "Key Takeaways", [
+ "✓ AI-First: AI executes 100%, Human validates 100%",
+ "✓ Prompt Engineering > Vibe Coding for production",
+ "✓ Project rules file is essential",
+ "✓ 10-step workflow with clear handoffs",
+ "✓ E2E + Unit tests are both mandatory",
+ "✓ Pre-commit checks are non-negotiable",
+ "✓ Humans control what gets merged"
+ ])
+
+ create_content_slide(story, styles, "Your Action Plan", [
+ ("Start Today:", [
+ "Create a project rules file for your current project"
+ ]),
+ ("Next Feature:", [
+ "Use the 10-step process",
+ "Write specs BEFORE AI implements"
+ ]),
+ ("As Projects Grow:", [
+ "Add planning structure (devplan.md, devprogress.md)"
+ ]),
+ ("Resources:", [
+ "Claude Code: claude.ai/code",
+ "Windsurf: codeium.com/windsurf",
+ "Cursor: cursor.sh"
+ ])
+ ])
+
+ # =================
+ # THANK YOU
+ # =================
+ create_thank_you_slide(story, styles, "Thank You!", "Questions?")
+
+ # Build PDF
+ doc.build(story, canvasmaker=NumberedCanvas)
+ print("✅ Lecture presentation created: ai-first-lecture.pdf")
+
+
+if __name__ == "__main__":
+ create_presentation()
diff --git a/create_openended_workshop.py b/create_openended_workshop.py
new file mode 100644
index 0000000..07840c1
--- /dev/null
+++ b/create_openended_workshop.py
@@ -0,0 +1,651 @@
+#!/usr/bin/env python3
+"""
+Generate 3-hour AI-First Open-Ended Workshop presentation.
+Attendees choose a project from unveiling-claude specs or their own idea.
+Minimal guidance after project selection - independent work with AI.
+"""
+
+from reportlab.lib.styles import getSampleStyleSheet
+from reportlab.platypus import Spacer, PageBreak
+from reportlab.lib.units import inch
+from presentation_utils import (
+ create_document,
+ create_title_slide,
+ create_section_slide,
+ create_content_slide,
+ create_two_column_slide,
+ create_hands_on_slide,
+ create_thank_you_slide,
+ export_prompts_to_markdown,
+ NumberedCanvas,
+)
+
+# Collect all prompts for export
+ALL_PROMPTS = []
+
+
+def create_presentation():
+ """Generate the complete open-ended workshop presentation."""
+ doc = create_document("ai-first-openended-workshop.pdf")
+ styles = getSampleStyleSheet()
+ story = []
+ page_num = 1
+
+ # =================
+ # TITLE
+ # =================
+ create_title_slide(
+ story, styles,
+ "AI-First Development",
+ "Open-Ended Workshop",
+ "Choose Your Project • Build with AI • 3 Hours"
+ )
+ page_num += 1
+
+ # =================
+ # AGENDA
+ # =================
+ create_content_slide(story, styles, "Workshop Agenda (3 Hours)", [
+ "Part 1: Foundation & Project Selection (45 min)",
+ ("", [
+ "AI-First philosophy quick recap",
+ "Review sample projects from unveiling-claude",
+ "Choose your project (or bring your own idea)",
+ "Initial setup"
+ ]),
+ "Part 2: Independent Build (90 min)",
+ ("", [
+ "Planning phase with AI",
+ "Implementation sprints (with break)",
+ "Work at your own pace"
+ ]),
+ "Part 3: Review & Share (45 min)",
+ ("", [
+ "Git workflow - commit and PR",
+ "Show & Tell - demo your progress",
+ "Wrap-up and next steps"
+ ])
+ ])
+ page_num += 1
+
+ # =================
+ # PART 1: FOUNDATION & PROJECT SELECTION
+ # =================
+ create_section_slide(story, styles, "Part 1: Foundation & Project Selection")
+ page_num += 1
+
+ # Quick Recap
+ create_content_slide(story, styles, "AI-First Philosophy (Quick Recap)", [
+ "AI executes 100% → Human validates 100%",
+ ("Core principle:", [
+ "AI handles coding, testing, documentation",
+ "Human handles validation, review, decisions"
+ ]),
+ "You are the architect, AI is the builder",
+ "Today: You choose what to build!"
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "The 10-Step Workflow (Reference)", [
+ "1. Specification (Human writes)",
+ "2. Database Schema (AI → Human reviews)",
+ "3. Repository Layer (AI → Human reviews)",
+ "4. API Endpoints (AI → Human reviews)",
+ "5. API Tests (AI → Human verifies)",
+ "6. Frontend (AI → Human reviews)",
+ "7. UI Tests (AI → Human verifies)",
+ "8. Documentation (AI → Human reviews)",
+ "9. Code Review (Human)",
+ "10. Deployment (AI → Human verifies)",
+ "Use as much or as little as fits your project"
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Today's Format", [
+ ("Different from guided workshops:", [
+ "YOU choose the project",
+ "YOU decide what to build",
+ "YOU work at your own pace"
+ ]),
+ ("Instructor is here to:", [
+ "Help when you're stuck",
+ "Answer questions",
+ "Keep time"
+ ]),
+ "Goal: Experience real AI-first development"
+ ])
+ page_num += 1
+
+ # Sample Projects Overview
+ create_section_slide(story, styles, "Sample Projects Overview")
+ page_num += 1
+
+ create_content_slide(story, styles, "Sample Specs: github.com/emmanuelandre/unveiling-claude", [
+ "Repository contains several project specifications",
+ ("Each project has:", [
+ "Detailed specifications",
+ "Architecture documents",
+ "Implementation guidance"
+ ]),
+ "Review the specs before choosing",
+ "Or: Bring your own project idea!"
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Option 1: manu-code (High Complexity)", [
+ "AI-powered CLI code generation assistant",
+ ("Features:", [
+ "Natural language to code",
+ "Multi-provider support (Anthropic, OpenAI, Gemini)",
+ "File operations, shell execution, git integration"
+ ]),
+ ("Tech Stack:", [
+ "TypeScript / Node.js",
+ "Commander, Inquirer CLI libraries"
+ ]),
+ "Good for: Experienced developers wanting a challenge",
+ "Spec: manu-code/manu-code-specs.md"
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Option 2: task-manager (Medium Complexity)", [
+ "Task management system with API",
+ ("Features:", [
+ "CRUD operations for tasks",
+ "User authentication",
+ "Task assignment and status tracking"
+ ]),
+ ("Tech Stack:", [
+ "Go or Node.js backend",
+ "PostgreSQL database"
+ ]),
+ "Good for: Learning full-stack API development",
+ "Spec: task-manager/ directory"
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Option 3: my-api-project (Low Complexity)", [
+ "Simple REST API starter project",
+ ("Features:", [
+ "Basic CRUD endpoints",
+ "Database migrations",
+ "Simple authentication"
+ ]),
+ ("Tech Stack:", [
+ "Go backend",
+ "PostgreSQL or SQLite"
+ ]),
+ "Good for: Beginners or quick projects",
+ "Spec: my-api-project/ directory"
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Option 4: Other Projects", [
+ ("prompt-ops:", [
+ "Prompt operations tooling",
+ "Medium complexity"
+ ]),
+ ("ui-to-test:", [
+ "UI testing project",
+ "Focus on frontend testing"
+ ]),
+ ("Bring Your Own Idea:", [
+ "Have a project in mind? Build it!",
+ "Personal tool, side project, experiment",
+ "Tell your AI assistant what you want to build"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "How to Review a Spec", [
+ ("When looking at a spec, check:", [
+ "What problem does it solve?",
+ "What are the core features?",
+ "What tech stack is suggested?",
+ "What can I realistically build in 90 minutes?"
+ ]),
+ ("Scoping for today:", [
+ "Pick ONE feature to implement",
+ "Focus on core functionality",
+ "Tests are important but scope them too"
+ ])
+ ])
+ page_num += 1
+
+ # Project Selection Exercise
+ create_hands_on_slide(
+ story, styles,
+ "Exercise 1: Browse & Choose Your Project",
+"""Go to: github.com/emmanuelandre/unveiling-claude
+
+Browse the available projects:
+- manu-code/ - AI CLI assistant (High complexity)
+- task-manager/ - Task management API (Medium)
+- my-api-project/ - Simple API starter (Low)
+- prompt-ops/ - Prompt operations (Medium)
+- ui-to-test/ - UI testing (Medium)
+
+Read the specs and choose ONE project.
+
+OR: Come up with your own idea!
+
+When ready, raise your hand to share your choice.""",
+ "You've chosen a project and have a rough idea of what to build",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_content_slide(story, styles, "Decision Checklist", [
+ ("Before moving on, confirm:", [
+ "☐ I've chosen a project",
+ "☐ I know which feature(s) to focus on",
+ "☐ I have a rough idea of the tech stack",
+ "☐ I'm ready to start!"
+ ]),
+ ("If stuck:", [
+ "Start with my-api-project (simplest)",
+ "Ask instructor for guidance",
+ "Pair with someone on the same project"
+ ])
+ ])
+ page_num += 1
+
+ # Setup
+ create_hands_on_slide(
+ story, styles,
+ "Exercise 2: Initial Setup",
+"""Choose ONE option:
+
+OPTION A: Fork unveiling-claude (if using sample project)
+1. Go to github.com/emmanuelandre/unveiling-claude
+2. Click "Fork" to create your copy
+3. Clone your fork:
+ git clone https://github.com/[YOUR-USERNAME]/unveiling-claude.git
+ cd unveiling-claude/[your-project]
+
+OPTION B: Create new repo (if using own idea)
+1. Create new repo on GitHub
+2. Clone it locally:
+ git clone https://github.com/[YOUR-USERNAME]/[your-repo].git
+ cd [your-repo]
+ git checkout -b feature/initial-setup
+
+Open your AI assistant and get ready!""",
+ "Repository set up and ready to work",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ # =================
+ # PART 2: INDEPENDENT BUILD
+ # =================
+ create_section_slide(story, styles, "Part 2: Independent Build (90 min)")
+ page_num += 1
+
+ create_content_slide(story, styles, "How This Part Works", [
+ ("You will work independently:", [
+ "Use your AI assistant as your coding partner",
+ "Follow the 10-step workflow (as much as applies)",
+ "Ask instructor if completely stuck"
+ ]),
+ ("Timeline:", [
+ "Planning Phase: 20 min",
+ "Implementation Sprint 1: 35 min",
+ "Break: 10 min",
+ "Implementation Sprint 2: 25 min"
+ ]),
+ "Checkpoints will be announced"
+ ])
+ page_num += 1
+
+ # Planning Phase
+ create_section_slide(story, styles, "Planning Phase (20 min)")
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Exercise 3: Create Your Plan with AI",
+"""Tell your AI assistant:
+
+I want to build [PROJECT NAME].
+
+Project context: [Brief description or link to spec]
+
+Help me create:
+1. A CLAUDE.md (or project rules file) with:
+ - Project overview
+ - Tech stack
+ - Project structure
+ - Commands (build, test, run)
+ - Testing requirements
+
+2. A specification for the FIRST feature I should build
+ - Keep it scoped for ~60 min implementation
+ - Include success criteria
+
+3. A rough implementation plan
+
+My tech stack preference: [Go/Node/Python/TypeScript]""",
+ "CLAUDE.md created and first feature specified",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_content_slide(story, styles, "Planning Tips", [
+ ("Keep scope realistic:", [
+ "One feature, working end-to-end",
+ "Better to finish small than abandon big"
+ ]),
+ ("Be specific with AI:", [
+ "Describe what you want clearly",
+ "Include constraints and preferences",
+ "Ask for clarification if needed"
+ ]),
+ ("Example good scope:", [
+ "User registration endpoint with validation",
+ "Single CRUD resource with tests",
+ "CLI command that does one thing well"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Checkpoint: Share Your Plan", [
+ ("In 2 minutes, be ready to share:", [
+ "What project did you choose?",
+ "What feature are you building?",
+ "What's your first step?"
+ ]),
+ "Quick round-robin (30 seconds each)",
+ "This helps everyone stay on track"
+ ])
+ page_num += 1
+
+ # Implementation Guidelines
+ create_content_slide(story, styles, "Implementation Guidelines", [
+ ("Follow the workflow:", [
+ "Database/data layer first (if needed)",
+ "Core logic/API second",
+ "Tests third",
+ "Don't skip tests!"
+ ]),
+ ("Working with AI:", [
+ "Review what AI generates",
+ "Ask for explanations if unclear",
+ "Request changes if needed"
+ ]),
+ ("When stuck:", [
+ "Ask AI to explain the error",
+ "Try a different approach",
+ "Ask instructor for help"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Quality Checkpoints", [
+ ("After each component, verify:", [
+ "☐ Does it compile/run?",
+ "☐ Does it do what the spec says?",
+ "☐ Are there obvious bugs?",
+ "☐ Is the code readable?"
+ ]),
+ ("Don't worry about:", [
+ "Perfect code on first try",
+ "Complete feature coverage",
+ "Production-ready polish"
+ ]),
+ "Focus on: Working software you understand"
+ ])
+ page_num += 1
+
+ # Sprint 1
+ create_section_slide(story, styles, "Sprint 1: Build Core Feature (35 min)")
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Exercise 4: Implementation Sprint 1",
+"""Time to build! Follow your plan.
+
+Suggested approach:
+1. Start with data layer (database schema, models)
+2. Then business logic (repository, handlers)
+3. Then tests
+
+Example prompt to start:
+"Based on our spec, let's start implementing.
+First, create the database schema for [your feature].
+Include proper types, indexes, and constraints."
+
+Continue from there. Work at your own pace.
+
+Checkpoint in 35 minutes!""",
+ "Core feature partially or fully implemented",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_content_slide(story, styles, "Sprint 1 Checkpoint Questions", [
+ ("Where are you?", [
+ "Database/models done?",
+ "Core logic started?",
+ "Any blockers?"
+ ]),
+ ("Quick assessment:", [
+ "On track → Keep going",
+ "Behind → Scope down",
+ "Stuck → Ask for help"
+ ]),
+ "No judgment - everyone works at different speeds"
+ ])
+ page_num += 1
+
+ # Break
+ create_section_slide(story, styles, "Break (10 min)")
+ page_num += 1
+
+ # Sprint 2
+ create_section_slide(story, styles, "Sprint 2: Continue Building (25 min)")
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Exercise 5: Implementation Sprint 2",
+"""Continue building your feature.
+
+Focus on:
+- Completing what you started
+- Adding tests for what works
+- Making it demo-able
+
+If you finished early:
+- Add another small feature
+- Improve tests
+- Clean up code
+- Help a neighbor
+
+Remember: Something working > Something perfect
+
+Checkpoint in 25 minutes - prepare for demo!""",
+ "Feature implemented and ready to demo",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_content_slide(story, styles, "Prepare for Demo", [
+ ("In your demo, plan to show:", [
+ "What you built (quick walkthrough)",
+ "One working feature in action",
+ "What you learned"
+ ]),
+ ("Keep it short:", [
+ "2-3 minutes max per person",
+ "Focus on the interesting parts",
+ "It's OK if it's not finished!"
+ ])
+ ])
+ page_num += 1
+
+ # =================
+ # PART 3: REVIEW & SHARE
+ # =================
+ create_section_slide(story, styles, "Part 3: Review & Share")
+ page_num += 1
+
+ # Git Workflow
+ create_content_slide(story, styles, "Git Workflow", [
+ ("Before demo, commit your work:", [
+ "Stage changes: git add .",
+ "Review: git status",
+ "Commit with conventional format"
+ ]),
+ ("Commit message format:", [
+ "feat(scope): description",
+ "Example: feat(auth): add user registration endpoint"
+ ]),
+ "Push to your fork/repo"
+ ])
+ page_num += 1
+
+ create_hands_on_slide(
+ story, styles,
+ "Exercise 6: Commit and Push",
+"""Commit and push your work:
+
+1. Review changes:
+ git status
+ git diff
+
+2. Stage and commit:
+ git add .
+ git commit -m "feat([scope]): [what you built]
+
+ - [Key thing 1]
+ - [Key thing 2]
+ - [Key thing 3]"
+
+3. Push:
+ git push origin [your-branch]
+
+4. (Optional) Create PR:
+ gh pr create --title "feat: [your feature]" \\
+ --body "## What I Built
+ [Description]
+
+ ## What Works
+ - [Feature 1]
+ - [Feature 2]"
+
+Or create PR through GitHub web interface.""",
+ "Code committed and pushed to GitHub",
+ page_num, ALL_PROMPTS)
+ page_num += 1
+
+ create_content_slide(story, styles, "PR Description Template", [
+ ("Include:", [
+ "## What I Built - brief description",
+ "## What Works - list working features",
+ "## What's Next - future improvements",
+ "## Lessons Learned - optional but valuable"
+ ]),
+ "This documents your workshop experience",
+ "Great reference for continuing at home"
+ ])
+ page_num += 1
+
+ # Show & Tell
+ create_section_slide(story, styles, "Show & Tell (20 min)")
+ page_num += 1
+
+ create_content_slide(story, styles, "Demo Format", [
+ ("Each person: 2-3 minutes", [
+ "What project did you choose?",
+ "What did you build?",
+ "Quick demo of one thing working",
+ "What was interesting/challenging?"
+ ]),
+ ("It's OK to show:", [
+ "Partially working features",
+ "Interesting failures",
+ "What you learned from errors"
+ ]),
+ "Celebrate progress, not perfection!"
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "While Others Demo", [
+ ("Listen for:", [
+ "Interesting approaches",
+ "Useful AI prompts",
+ "Problems you also faced"
+ ]),
+ "Save questions for after all demos",
+ "Note ideas for your own projects"
+ ])
+ page_num += 1
+
+ # Wrap-up
+ create_section_slide(story, styles, "Wrap-Up")
+ page_num += 1
+
+ create_content_slide(story, styles, "Key Learnings", [
+ ("Today you experienced:", [
+ "Choosing and scoping a project",
+ "Planning with AI assistance",
+ "Independent implementation",
+ "Real development workflow"
+ ]),
+ ("The AI-First approach:", [
+ "AI helps you move faster",
+ "You make the decisions",
+ "Review everything",
+ "Tests matter"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Continue at Home", [
+ ("Your project isn't finished - keep going!", [
+ "Complete the feature you started",
+ "Add more tests",
+ "Try another feature from the spec"
+ ]),
+ ("Tips for solo work:", [
+ "Commit frequently",
+ "Take breaks",
+ "Review AI output carefully",
+ "Document what works"
+ ])
+ ])
+ page_num += 1
+
+ create_content_slide(story, styles, "Resources", [
+ ("Sample Specs:", [
+ "github.com/emmanuelandre/unveiling-claude"
+ ]),
+ ("AI Tools:", [
+ "Claude Code: claude.ai/code",
+ "Windsurf: codeium.com/windsurf",
+ "Cursor: cursor.sh"
+ ]),
+ ("Documentation:", [
+ "See /docs folder for detailed guides",
+ "CLAUDE.md templates in /examples"
+ ])
+ ])
+ page_num += 1
+
+ # =================
+ # THANK YOU
+ # =================
+ create_thank_you_slide(story, styles, "Thank You!", "Keep Building!")
+
+ # Build PDF
+ doc.build(story, canvasmaker=NumberedCanvas)
+ print("✅ Open-ended workshop created: ai-first-openended-workshop.pdf")
+
+ # Export prompts
+ export_prompts_to_markdown(
+ ALL_PROMPTS,
+ "openended-workshop-prompts.md",
+ "AI-First Open-Ended Workshop Prompts"
+ )
+ print("✅ Prompts exported: openended-workshop-prompts.md")
+
+
+if __name__ == "__main__":
+ create_presentation()
diff --git a/docs/04-claude-md.md b/docs/04-claude-md.md
index f2a49b5..293a48a 100644
--- a/docs/04-claude-md.md
+++ b/docs/04-claude-md.md
@@ -259,9 +259,8 @@ git commit -m "docs: update CLAUDE.md with new API patterns"
## Example Projects
-- [API Service](../examples/api-service-claude.md)
-- [React App](../examples/react-app-claude.md)
-- [Microservices](../examples/microservices-claude.md)
+- [CLAUDE.md Template](../examples/claude-md-template.md) - Comprehensive production-ready template
+- [my-api-project](../examples/my-api-project/CLAUDE.md) - Workshop reference example (Go API)
---
diff --git a/docs/08-feature-workflow.md b/docs/08-feature-workflow.md
index f64f99a..9dc6e53 100644
--- a/docs/08-feature-workflow.md
+++ b/docs/08-feature-workflow.md
@@ -698,4 +698,4 @@ gh pr create --title "feat: Add password reset functionality" \
---
-**Prev:** [AI-First Workflow](./07-ai-first-workflow.md) | **Next:** [Real-World Examples](./09-real-world-examples.md)
+**Prev:** [AI-First Workflow](./07-ai-first-workflow.md) | **Next:** [Project Planning & Documentation Structure](./09-project-planning-structure.md)
diff --git a/docs/11-git-workflow.md b/docs/11-git-workflow.md
index b0f7c8b..428aee2 100644
--- a/docs/11-git-workflow.md
+++ b/docs/11-git-workflow.md
@@ -331,4 +331,4 @@ git config --global alias.lg "log --graph --oneline --all"
---
-**Prev:** [Scaling to Large Projects](./10-scaling-large-projects.md) | **Next:** [Documentation Strategies](./12-documentation.md)
+**Prev:** [Scaling to Large Projects](./10-scaling-large-projects.md) | **Next:** [Documentation Organization](./12-documentation-organization.md)
diff --git a/docs/12-documentation-organization.md b/docs/12-documentation-organization.md
new file mode 100644
index 0000000..9c0dff9
--- /dev/null
+++ b/docs/12-documentation-organization.md
@@ -0,0 +1,1195 @@
+# Documentation Organization
+
+How to structure your project documentation for effective AI-first development.
+
+## Why Documentation Structure Matters
+
+In AI-first development, your documentation serves multiple purposes:
+- **Context for Claude** - Persistent knowledge across sessions
+- **Team alignment** - Single source of truth for conventions
+- **Progress tracking** - Clear visibility into project state
+- **Knowledge preservation** - Decisions and rationale captured
+
+The right structure depends on your project size, team, and duration.
+
+## The Two Patterns
+
+### Pattern 1: Simple Flat Structure
+
+Best for: Solo projects, < 20 tasks, short duration (weeks)
+
+```
+project-root/
+├── CLAUDE.md # Project configuration for Claude
+├── README.md # Project overview
+├── plan.md # Development roadmap
+├── architecture.md # System design
+├── requirements.md # Feature requirements
+├── ui-specs.md # UI specifications (if applicable)
+└── src/ # Source code
+```
+
+**Advantages:**
+- Quick to set up
+- Easy to navigate
+- Low overhead
+- All context in one place
+
+**When to use:**
+- Solo developer or pair
+- Project duration < 1 month
+- Single service/application
+- < 20 total tasks
+
+### Pattern 2: Nested Directory Structure
+
+Best for: Teams, 20+ tasks, long-term projects
+
+```
+project-root/
+├── CLAUDE.md # Project configuration
+├── README.md # Project overview
+├── project/ # Documentation hub
+│ ├── planning/ # Master plans and progress
+│ │ ├── devplan.md
+│ │ ├── devprogress.md
+│ │ ├── database.md
+│ │ └── sitemap.md
+│ ├── specs/ # Feature specifications
+│ │ ├── 01-auth.md
+│ │ ├── 02-dashboard.md
+│ │ └── ...
+│ ├── architecture/ # Architecture documents
+│ │ ├── backend.md
+│ │ ├── frontend.md
+│ │ └── infrastructure.md
+│ ├── sessions/ # Session summaries
+│ └── archive/ # Historical docs
+└── src/
+```
+
+**Advantages:**
+- Scales with project complexity
+- Clear separation of concerns
+- Better for team collaboration
+- Supports phased development
+
+**When to use:**
+- Team of 2+ developers
+- Project duration > 1 month
+- Multiple services/components
+- 20+ tasks across phases
+
+> See [Project Planning & Documentation Structure](./09-project-planning-structure.md) for detailed guidance on the nested pattern.
+
+## Decision Matrix
+
+| Factor | Flat Structure | Nested Structure |
+|--------|---------------|------------------|
+| Team size | 1-2 developers | 3+ developers |
+| Project duration | < 1 month | > 1 month |
+| Task count | < 20 tasks | 20+ tasks |
+| Services | Single service | Multiple services |
+| Phases | 1-2 phases | 3+ phases |
+
+**Decision flowchart:**
+
+```
+Is your project > 1 month duration?
+├── No → Use Flat Structure
+└── Yes → Do you have 20+ tasks?
+ ├── No → Use Flat Structure
+ └── Yes → Use Nested Structure
+```
+
+---
+
+## Core Documentation Files
+
+These files are essential regardless of which pattern you choose.
+
+### plan.md / devplan.md
+
+**Purpose:** Development roadmap, task tracking, and progress visibility.
+
+**Template (Flat Pattern):**
+
+```markdown
+# Development Plan
+
+## Overview
+[One-paragraph project description]
+
+## Goals
+- [ ] Goal 1: [Description]
+- [ ] Goal 2: [Description]
+- [ ] Goal 3: [Description]
+
+## Milestones
+
+### Milestone 1: [Name]
+**Target:** [Date or sprint]
+**Status:** In Progress / Complete / Blocked
+
+Tasks:
+- [ ] Task 1.1: [Description]
+- [ ] Task 1.2: [Description]
+- [x] Task 1.3: [Completed task]
+
+### Milestone 2: [Name]
+**Target:** [Date or sprint]
+**Status:** Not Started
+
+Tasks:
+- [ ] Task 2.1: [Description]
+- [ ] Task 2.2: [Description]
+
+## Current Focus
+
+**Active:** [Current task being worked on]
+**Next:** [Next task after current]
+**Blocked:** [Any blockers, or "None"]
+
+## Completed
+
+- [x] [Completed milestone or task]
+- [x] [Completed milestone or task]
+
+## Notes
+
+[Any important context, decisions, or changes to the plan]
+```
+
+**Template (Nested Pattern - devplan.md):**
+
+```markdown
+# Project Development Plan
+
+## Development Strategy
+
+### Core Principles
+1. Database First - Schema before implementation
+2. API First - Backend before frontend
+3. Test Driven - Tests at each layer
+4. Incremental - Follow dependency order
+5. Vertical Slices - Complete stack per feature
+
+### Implementation Workflow (Per Feature)
+1. DATABASE: Migration → Repository → Mock data
+2. BACKEND API: Handlers → Validation → Permissions
+3. API E2E TESTS: Cypress/Playwright tests → All pass
+4. FRONTEND UI: Components → Forms → Integration
+5. UI E2E TESTS: UI tests → All pass
+6. DOCUMENTATION: API docs → Comments → Changelog
+
+### Dependency Map
+```
+[Entity] → [Entity] → [Entity]
+Example: Organizations → Users → Permissions → Features
+```
+
+### Development Phases
+
+#### Phase 0: Foundation
+- [ ] Database setup
+- [ ] Authentication
+- [ ] Core infrastructure
+
+#### Phase 1: Core Features
+- [ ] Feature A
+- [ ] Feature B
+
+#### Phase 2: Advanced Features
+- [ ] Feature C
+- [ ] Feature D
+
+[Continue for all phases...]
+```
+
+---
+
+### architecture.md
+
+**Purpose:** System design, component relationships, and technical decisions.
+
+**Template:**
+
+```markdown
+# Architecture
+
+## System Overview
+
+[High-level description of what the system does and its main components]
+
+## Architecture Diagram
+
+```
+┌─────────────┐ ┌─────────────┐ ┌─────────────┐
+│ Client │────▶│ API │────▶│ Database │
+│ (React) │ │ (Go) │ │ (PostgreSQL)│
+└─────────────┘ └─────────────┘ └─────────────┘
+ │
+ ▼
+ ┌─────────────┐
+ │ Cache │
+ │ (Redis) │
+ └─────────────┘
+```
+
+## Components
+
+### Component: [Name]
+**Purpose:** [What it does]
+**Technology:** [Tech stack]
+**Key Files:**
+- `path/to/main/file`
+- `path/to/other/file`
+
+**Responsibilities:**
+- Responsibility 1
+- Responsibility 2
+
+### Component: [Name]
+[Repeat for each component...]
+
+## Data Flow
+
+### Flow: [User Action]
+1. User initiates [action]
+2. Frontend sends request to [endpoint]
+3. API validates and processes
+4. Database updated
+5. Response returned
+
+## Key Architectural Decisions
+
+| Decision | Options Considered | Choice | Rationale |
+|----------|-------------------|--------|-----------|
+| Database | PostgreSQL, MySQL, MongoDB | PostgreSQL | ACID compliance, JSON support |
+| Auth | Sessions, JWT | JWT | Stateless, mobile-friendly |
+| Cache | Redis, Memcached | Redis | Data structures, persistence |
+
+## External Dependencies
+
+| Dependency | Purpose | Documentation |
+|------------|---------|---------------|
+| Stripe | Payments | [Link] |
+| SendGrid | Email | [Link] |
+
+## Security Considerations
+
+- All API endpoints require authentication except [exceptions]
+- Sensitive data encrypted at rest
+- HTTPS enforced in production
+```
+
+---
+
+### requirements.md
+
+**Purpose:** Functional and non-functional requirements with acceptance criteria.
+
+**Template:**
+
+```markdown
+# Requirements
+
+## Functional Requirements
+
+### FR-001: [Feature Name]
+**Priority:** High / Medium / Low
+**Status:** Planned / In Progress / Complete
+
+**Description:**
+[What the feature does from user perspective]
+
+**User Story:**
+As a [role], I want to [action] so that [benefit].
+
+**Acceptance Criteria:**
+- [ ] Criterion 1: [Specific, testable condition]
+- [ ] Criterion 2: [Specific, testable condition]
+- [ ] Criterion 3: [Specific, testable condition]
+
+**Dependencies:**
+- FR-XXX: [Dependent feature]
+
+---
+
+### FR-002: [Feature Name]
+[Repeat structure...]
+
+---
+
+## Non-Functional Requirements
+
+### NFR-001: Performance
+- Page load time < 3 seconds on 3G
+- API response time < 500ms (p95)
+- Support 1000 concurrent users
+
+### NFR-002: Security
+- OWASP Top 10 compliance
+- Data encrypted at rest and in transit
+- Session timeout after 30 minutes inactivity
+
+### NFR-003: Availability
+- 99.9% uptime SLA
+- Automated failover
+- Daily backups with 30-day retention
+
+### NFR-004: Accessibility
+- WCAG 2.1 AA compliance
+- Keyboard navigation support
+- Screen reader compatible
+
+## Constraints
+
+- Must integrate with existing [system]
+- Budget: [amount]
+- Timeline: [deadline]
+- Tech stack: [required technologies]
+```
+
+---
+
+### ui-specs.md
+
+**Purpose:** Frontend specifications, design system, and page layouts.
+
+**Template:**
+
+```markdown
+# UI Specifications
+
+## Design System
+
+### Colors
+| Name | Hex | Usage |
+|------|-----|-------|
+| Primary | #3B82F6 | Buttons, links, accents |
+| Secondary | #6B7280 | Secondary text, borders |
+| Success | #10B981 | Success states |
+| Error | #EF4444 | Error states |
+| Background | #F9FAFB | Page background |
+
+### Typography
+| Element | Font | Size | Weight |
+|---------|------|------|--------|
+| H1 | Inter | 36px | 700 |
+| H2 | Inter | 24px | 600 |
+| Body | Inter | 16px | 400 |
+| Small | Inter | 14px | 400 |
+
+### Spacing
+- Base unit: 4px
+- Scale: 4, 8, 12, 16, 24, 32, 48, 64
+
+### Components
+- Buttons: Primary, Secondary, Ghost, Danger
+- Inputs: Text, Select, Checkbox, Radio
+- Cards: Default, Elevated, Interactive
+
+---
+
+## Pages
+
+### Page: [Page Name]
+**Route:** `/path`
+**Access:** Public / Authenticated / Admin
+
+**Purpose:**
+[What users accomplish on this page]
+
+**Layout:**
+```
+┌─────────────────────────────────┐
+│ Header │
+├─────────┬───────────────────────┤
+│ Sidebar │ Main Content │
+│ │ ┌─────────────────┐ │
+│ │ │ Component A │ │
+│ │ └─────────────────┘ │
+│ │ ┌─────────────────┐ │
+│ │ │ Component B │ │
+│ │ └─────────────────┘ │
+└─────────┴───────────────────────┘
+```
+
+**Components:**
+| Component | Purpose | Data Source |
+|-----------|---------|-------------|
+| Header | Navigation | Auth state |
+| Sidebar | Menu items | User role |
+| Component A | [Purpose] | API: /endpoint |
+
+**States:**
+- **Loading:** Skeleton placeholder
+- **Empty:** "No items found" message with CTA
+- **Error:** Error message with retry button
+- **Success:** Data displayed in table/list
+
+**User Actions:**
+| Action | Trigger | Result |
+|--------|---------|--------|
+| Create item | Click "Add" button | Modal opens |
+| Delete item | Click trash icon | Confirmation dialog |
+| Filter | Select dropdown | List filters |
+
+---
+
+### Page: [Next Page]
+[Repeat structure...]
+
+---
+
+## User Flows
+
+### Flow: [Flow Name]
+1. User lands on [page]
+2. User clicks [element]
+3. System displays [response]
+4. User completes [action]
+5. System confirms [result]
+
+## Responsive Breakpoints
+
+| Breakpoint | Width | Layout Changes |
+|------------|-------|----------------|
+| Mobile | < 640px | Single column, hamburger menu |
+| Tablet | 640-1024px | Two columns, collapsible sidebar |
+| Desktop | > 1024px | Full layout with fixed sidebar |
+```
+
+---
+
+### README.md
+
+**Purpose:** Project entry point for developers and stakeholders.
+
+**Template:**
+
+```markdown
+# Project Name
+
+[One-line description of what this project does]
+
+## Overview
+
+[2-3 paragraph description covering:]
+- What problem it solves
+- Who it's for
+- Key features
+
+## Quick Start
+
+### Prerequisites
+- Node.js 18+
+- PostgreSQL 16
+- Docker (optional)
+
+### Installation
+
+```bash
+# Clone the repository
+git clone [repo-url]
+cd [project-name]
+
+# Install dependencies
+npm install
+
+# Set up environment
+cp .env.example .env
+# Edit .env with your values
+
+# Run database migrations
+npm run db:migrate
+
+# Start development server
+npm run dev
+```
+
+### Verify Installation
+```bash
+# Run tests
+npm test
+
+# Open in browser
+open http://localhost:3000
+```
+
+## Project Structure
+
+```
+├── src/
+│ ├── api/ # API routes and handlers
+│ ├── components/ # React components
+│ ├── lib/ # Shared utilities
+│ └── pages/ # Page components
+├── tests/ # Test files
+├── docs/ # Documentation
+└── scripts/ # Build and utility scripts
+```
+
+## Documentation
+
+- [Architecture](./architecture.md)
+- [API Documentation](./docs/api.md)
+- [Contributing Guide](./CONTRIBUTING.md)
+
+## Development
+
+### Commands
+
+| Command | Description |
+|---------|-------------|
+| `npm run dev` | Start development server |
+| `npm run build` | Build for production |
+| `npm test` | Run tests |
+| `npm run lint` | Run linter |
+
+### Environment Variables
+
+| Variable | Description | Required |
+|----------|-------------|----------|
+| `DATABASE_URL` | PostgreSQL connection string | Yes |
+| `JWT_SECRET` | Secret for JWT signing | Yes |
+| `PORT` | Server port (default: 3000) | No |
+
+## Contributing
+
+1. Create a feature branch: `git checkout -b feature/your-feature`
+2. Make your changes
+3. Run tests: `npm test`
+4. Submit a pull request
+
+## License
+
+[License type] - see [LICENSE](./LICENSE) for details
+```
+
+---
+
+### Rules & Memory
+
+For persistent context across Claude sessions, use these patterns:
+
+#### .claude/rules/ Directory
+
+Create project-specific rules that Claude follows:
+
+```
+.claude/
+└── rules/
+ ├── coding-standards.md
+ ├── testing-requirements.md
+ └── git-conventions.md
+```
+
+**Example: coding-standards.md**
+```markdown
+# Coding Standards
+
+## Naming Conventions
+- Functions: camelCase
+- Components: PascalCase
+- Constants: UPPER_SNAKE_CASE
+- Files: kebab-case
+
+## Code Organization
+- One component per file
+- Group related files in feature folders
+- Keep files under 300 lines
+
+## Required Patterns
+- All API calls through service layer
+- Error boundaries around async operations
+- Loading states for all data fetching
+```
+
+#### Memory/Context Files
+
+For session continuity, maintain context files:
+
+**CONTEXT.md** (Session handoff)
+```markdown
+# Current Context
+
+## Last Session
+**Date:** 2025-01-15
+**Focus:** Implementing user authentication
+**Branch:** feature/user-auth
+
+## Current State
+- [x] Database migration complete
+- [x] Repository layer done
+- [ ] API handlers in progress (2/4 done)
+- [ ] Tests not started
+
+## Next Steps
+1. Complete login handler
+2. Add JWT middleware
+3. Write E2E tests
+
+## Open Questions
+- Should we implement refresh tokens? (Decided: Yes)
+- Token expiry time? (Pending decision)
+
+## References
+- Spec: project/specs/01-auth.md
+- Migration: migrations/001_users.up.sql
+```
+
+---
+
+## The Hybrid Approach
+
+Start simple, evolve as needed.
+
+### Starting Flat
+
+Begin with flat structure for new projects:
+
+```
+my-project/
+├── CLAUDE.md
+├── README.md
+├── plan.md
+├── architecture.md
+└── src/
+```
+
+### Graduating to Nested
+
+When your project grows (20+ tasks, multiple phases), migrate:
+
+**Step 1:** Create the directory structure
+```bash
+mkdir -p project/{planning,specs,architecture,sessions}
+```
+
+**Step 2:** Move and split existing files
+```bash
+# Move plan.md content
+mv plan.md project/planning/devplan.md
+# Create progress tracker
+touch project/planning/devprogress.md
+
+# Split architecture if needed
+mv architecture.md project/architecture/overview.md
+
+# Create first spec from requirements
+mv requirements.md project/specs/00-overview.md
+```
+
+**Step 3:** Update CLAUDE.md references
+```markdown
+## Documentation Structure
+
+This project uses the nested documentation pattern:
+- Planning: `project/planning/`
+- Specifications: `project/specs/`
+- Architecture: `project/architecture/`
+- Session notes: `project/sessions/`
+```
+
+### Migration Prompt
+
+Ask Claude to help migrate:
+
+```
+My project has grown and I need to migrate from flat to nested
+documentation structure. Current files:
+- plan.md (tasks and progress)
+- architecture.md (system design)
+- requirements.md (features)
+
+Please:
+1. Create project/ directory structure
+2. Split plan.md into devplan.md and devprogress.md
+3. Move architecture.md to project/architecture/
+4. Split requirements into separate spec files per feature
+5. Update CLAUDE.md to reference new structure
+
+Preserve all existing content during migration.
+```
+
+---
+
+## Feature Documentation Deep Dive
+
+For larger features that span multiple days or involve complex requirements, use this comprehensive documentation approach.
+
+### The Five Document Types
+
+When planning a significant feature, create these five interconnected documents:
+
+| Document | Purpose | Location |
+|----------|---------|----------|
+| Planning | High-level overview, decisions, timeline | `/docs/planning/features/{feature}.md` |
+| Architecture | Technical design, system interactions | `/docs/architecture/{feature}-architecture.md` |
+| API Contracts | Endpoint specifications, request/response | `/docs/specs/{feature}/api-contracts.md` |
+| User Journey | Personas, flows, edge cases | `/docs/specs/{feature}/user-journey.md` |
+| UI Wireframes | Page layouts, component specs | `/docs/specs/{feature}/ui-wireframes.md` |
+
+### Feature Planning Document
+
+**Purpose:** High-level overview, key decisions, timeline, and success criteria.
+
+```markdown
+# Feature: {Feature Name}
+
+**Status:** Planning | In Progress | Complete
+**Priority:** High | Medium | Low
+**Last Updated:** YYYY-MM-DD
+
+## Related Documentation
+- [Architecture](../architecture/{feature}-architecture.md)
+- [API Contracts](../specs/{feature}/api-contracts.md)
+- [UI Wireframes](../specs/{feature}/ui-wireframes.md)
+- [User Journey](../specs/{feature}/user-journey.md)
+
+## Overview
+{2-3 paragraphs describing the feature, its value, and high-level approach}
+
+## Key Decisions
+
+| Decision | Choice | Rationale |
+|----------|--------|-----------|
+| {Decision 1} | {Choice made} | {Why this choice} |
+
+## Scope
+
+### In Scope
+- {Item 1}
+- {Item 2}
+
+### Out of Scope (Deferred)
+- {Item 1} - {Reason}
+
+## Implementation Phases
+
+### Phase 1: {Name}
+- [ ] Task 1
+- [ ] Task 2
+
+### Phase 2: {Name}
+- [ ] Task 1
+
+## Critical Files
+
+**Backend:**
+- `path/to/file.go` - {Purpose}
+
+**Frontend:**
+- `path/to/component.tsx` - {Purpose}
+
+**Database:**
+- `migrations/xxx_create_table.sql`
+
+## Success Criteria
+
+### By End of Phase 1
+- [ ] Metric 1 achieved
+- [ ] Metric 2 achieved
+```
+
+### Feature Architecture Document
+
+**Purpose:** Technical design, database schema, API design, and integration points.
+
+**Key Patterns:**
+
+**ASCII System Diagrams:**
+```
+┌─────────┐ ┌─────────┐ ┌─────────┐
+│ UI │────▶│ API │────▶│ Queue │
+└─────────┘ └─────────┘ └────┬────┘
+ │
+ ┌────────────────┘
+ ▼
+ ┌──────────┐ ┌──────────┐
+ │ Worker │────▶│ Database │
+ └──────────┘ └──────────┘
+```
+
+**Database Schema with Indexes:**
+```sql
+CREATE TABLE feature_items (
+ id SERIAL PRIMARY KEY,
+ org_id INT NOT NULL REFERENCES organizations(id),
+ user_id INT NOT NULL REFERENCES users(id),
+ status VARCHAR(50) NOT NULL DEFAULT 'pending',
+ metadata JSONB,
+ created_at TIMESTAMPTZ DEFAULT NOW(),
+ updated_at TIMESTAMPTZ DEFAULT NOW()
+);
+
+CREATE INDEX idx_feature_items_org ON feature_items(org_id);
+CREATE INDEX idx_feature_items_status ON feature_items(status);
+```
+
+**Pipeline Stage Tables:**
+
+| Stage | Duration | Description |
+|-------|----------|-------------|
+| 1. Validate | <1s | Input validation |
+| 2. Process | ~5s | Core transformation |
+| 3. Verify | ~10s | Output verification |
+
+### API Contracts Document
+
+**Purpose:** Complete endpoint specifications with request/response examples.
+
+```markdown
+### POST /api/v1/items
+
+Create a new item.
+
+**Request:**
+```json
+{
+ "name": "Example",
+ "type": "standard",
+ "options": {
+ "auto_process": true
+ }
+}
+```
+
+**Response (201 Created):**
+```json
+{
+ "id": 123,
+ "name": "Example",
+ "status": "pending",
+ "created_at": "2025-01-15T10:30:00Z"
+}
+```
+
+**Error Responses:**
+- `400` - Invalid request body
+- `401` - Unauthorized
+- `409` - Duplicate item
+- `422` - Validation failed
+```
+
+**Error Code Table:**
+
+| Code | HTTP | Description |
+|------|------|-------------|
+| VALIDATION_FAILED | 422 | Input validation error |
+| DUPLICATE_ITEM | 409 | Item already exists |
+
+### User Journey Document
+
+**Purpose:** User personas, step-by-step flows, edge cases.
+
+**Persona Template:**
+```markdown
+### Persona: Power User
+
+**Background:** Experienced with similar tools, uses features daily
+**Goals:**
+- Complete tasks quickly with minimal clicks
+- Access advanced options when needed
+**Pain Points:**
+- Frustrated by unnecessary confirmations
+- Needs keyboard shortcuts
+```
+
+**Journey Map:**
+```markdown
+### Journey: Create New Item
+
+**Duration:** 30-60 seconds
+**Steps:**
+
+1. **Navigate** → User clicks "New Item" button
+ - System displays creation form
+
+2. **Configure** → User fills required fields
+ - System validates in real-time
+
+3. **Submit** → User clicks "Create"
+ - System shows progress indicator
+
+4. **Complete** → System shows success
+ - User redirected to item detail page
+```
+
+**Edge Case Pattern:**
+```markdown
+### Edge Case: Network Interruption During Processing
+
+**Scenario:** User loses connection mid-process
+**Expected Behavior:**
+1. System retries automatically (3 attempts)
+2. If still failing, shows "Processing paused" status
+3. User can retry manually when connection restored
+**Recovery:** Resume button triggers retry from last checkpoint
+```
+
+### UI Wireframes Document
+
+**Purpose:** Page layouts, component specifications, responsive design.
+
+**ASCII Wireframe:**
+```
+### Item List Page
+
+┌─────────────────────────────────────────────────┐
+│ [Logo] Dashboard Items Settings [User] │
+├─────────────────────────────────────────────────┤
+│ │
+│ Items [+ New Item] │
+│ ───────────────────────────────────────────── │
+│ │
+│ [Search... ] [Filter ▼] [Sort ▼] │
+│ │
+│ ┌─────────────────────────────────────────┐ │
+│ │ ○ Item Name Status Created │ │
+│ ├─────────────────────────────────────────┤ │
+│ │ ○ Example Item 1 ● Active Jan 15 │ │
+│ │ ○ Example Item 2 ○ Draft Jan 14 │ │
+│ └─────────────────────────────────────────┘ │
+│ │
+│ Showing 1-10 of 45 [< 1 2 3 4 5 >] │
+│ │
+└─────────────────────────────────────────────────┘
+```
+
+**Component Specification:**
+```markdown
+### StatusBadge Component
+
+**Props:**
+| Prop | Type | Required | Description |
+|------|------|----------|-------------|
+| status | string | Yes | 'pending' | 'active' | 'failed' |
+| size | string | No | 'sm' | 'md' | 'lg' (default: 'md') |
+```
+
+---
+
+## Cross-Referencing Pattern
+
+All feature documents should reference each other for easy navigation:
+
+```markdown
+## Related Documentation
+
+| Document | Description |
+|----------|-------------|
+| [Planning](../planning/features/item-management.md) | Timeline and decisions |
+| [Architecture](../architecture/item-architecture.md) | Technical design |
+| [API Contracts](./api-contracts.md) | Endpoint specifications |
+| [User Journey](./user-journey.md) | User flows |
+| [UI Wireframes](./ui-wireframes.md) | Visual layouts |
+```
+
+---
+
+## Feature Documentation Checklist
+
+Before implementation begins, verify all documentation is complete:
+
+### Planning Document
+- [ ] Key decisions documented with rationale
+- [ ] Implementation phases defined
+- [ ] Critical files listed
+- [ ] Success criteria measurable
+
+### Architecture Document
+- [ ] System diagram shows all components
+- [ ] Database schema complete with indexes
+- [ ] API endpoint summary table
+- [ ] Error handling strategy defined
+
+### API Contracts
+- [ ] All endpoints documented
+- [ ] Request/response examples provided
+- [ ] Error codes defined
+- [ ] Authentication requirements clear
+
+### User Journey
+- [ ] Personas identified
+- [ ] Happy path documented
+- [ ] Edge cases considered
+- [ ] Error UX defined
+
+### UI Wireframes
+- [ ] All pages wireframed
+- [ ] Component props specified
+- [ ] Responsive breakpoints defined
+- [ ] Navigation integration shown
+
+---
+
+## Design Review Process
+
+Design reviews validate specifications before implementation, catching issues early when changes are cheap.
+
+### Review Stages
+
+```
+┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
+│ Draft │────▶│ Review │────▶│ Approved │────▶│ Implement │
+│ (Author) │ │ (Team) │ │ (Sign-off) │ │ (Dev) │
+└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
+ │ │
+ │ Iterate │ Request
+ └───────────────────┘ Changes
+```
+
+### Stage 1: Self-Review (Author)
+
+Before sharing, the author verifies:
+- [ ] All five document types are complete
+- [ ] Cross-references link correctly
+- [ ] No placeholder text remains
+- [ ] Examples are realistic and consistent
+
+### Stage 2: Technical Review (Peers)
+
+**Participants:** 2-3 engineers familiar with affected systems
+
+**Focus Areas:**
+
+| Focus | Questions to Answer |
+|-------|---------------------|
+| Architecture | Does this integrate cleanly? Any conflicts? |
+| API Design | Are endpoints RESTful? Consistent patterns? |
+| Database | Are indexes sufficient? Migration concerns? |
+| Security | Authentication handled? Input validation complete? |
+| Performance | Any N+1 queries? Caching strategy needed? |
+
+### Stage 3: Approval and Sign-off
+
+**Requirements:**
+- All blocking comments resolved
+- At least 2 technical approvals
+- Stakeholder approval (if applicable)
+
+**Sign-off Format:**
+```markdown
+## Approvals
+
+| Role | Name | Date | Status |
+|------|------|------|--------|
+| Tech Lead | {Name} | YYYY-MM-DD | Approved |
+| Senior Dev | {Name} | YYYY-MM-DD | Approved |
+```
+
+---
+
+## Spec Versioning and Change Management
+
+### Version Header
+
+Every spec document should include:
+
+```markdown
+# Feature: Item Management
+
+**Version:** 1.2.0
+**Status:** Approved
+**Last Updated:** 2025-01-15
+**Author:** {Name}
+
+## Change History
+
+| Version | Date | Author | Changes |
+|---------|------|--------|---------|
+| 1.2.0 | 2025-01-15 | {Name} | Added batch processing endpoint |
+| 1.1.0 | 2025-01-10 | {Name} | Updated validation rules |
+| 1.0.0 | 2025-01-05 | {Name} | Initial approved version |
+```
+
+### Semantic Versioning for Specs
+
+| Version Bump | When to Use | Example |
+|--------------|-------------|---------|
+| **Major (X.0.0)** | Breaking changes | Removing endpoint, changing auth model |
+| **Minor (1.X.0)** | Additive changes | New endpoint, new optional field |
+| **Patch (1.0.X)** | Clarifications | Better examples, formatting fixes |
+
+### Change Request Process
+
+When specs need to change during implementation:
+
+```
+┌─────────────┐ ┌─────────────┐ ┌─────────────┐
+│ Change │────▶│ Impact │────▶│ Review │
+│ Identified │ │ Analysis │ │ & Approve │
+└─────────────┘ └─────────────┘ └─────────────┘
+ │
+ ┌─────────────────────────┘
+ ▼
+ ┌─────────────┐ ┌─────────────┐
+ │ Update │────▶│ Notify │
+ │ Specs │ │ Team │
+ └─────────────┘ └─────────────┘
+```
+
+### Document Lifecycle States
+
+| Status | Meaning | Can Edit? |
+|--------|---------|-----------|
+| **Draft** | Initial writing | Yes, freely |
+| **In Review** | Under team review | Yes, based on feedback |
+| **Approved** | Ready for implementation | Only via change request |
+| **In Progress** | Implementation underway | Only via change request |
+| **Implemented** | Feature shipped | Archive only |
+| **Deprecated** | Replaced by newer spec | No changes |
+
+---
+
+## Anti-Patterns to Avoid
+
+| Anti-Pattern | Problem | Solution |
+|--------------|---------|----------|
+| Writing docs after implementation | Docs become stale/incomplete | Document during planning phase |
+| Single monolithic spec | Hard to navigate and update | Split into focused documents |
+| No cross-references | Readers can't find related info | Add Related Documentation section |
+| Missing error scenarios | Edge cases discovered in production | Document error handling explicitly |
+| Vague success criteria | No way to verify completion | Use measurable, specific goals |
+| No file list | Code reviews miss scope | List all files to create/modify |
+
+---
+
+## Quick Reference Card
+
+### Flat Structure Checklist
+- [ ] CLAUDE.md - Project configuration
+- [ ] README.md - Quick start and overview
+- [ ] plan.md - Tasks and progress
+- [ ] architecture.md - System design
+- [ ] requirements.md - Feature requirements
+- [ ] ui-specs.md - UI specifications (if applicable)
+
+### Nested Structure Checklist
+- [ ] CLAUDE.md - Project configuration
+- [ ] README.md - Quick start and overview
+- [ ] project/planning/devplan.md - Master plan
+- [ ] project/planning/devprogress.md - Progress tracker
+- [ ] project/planning/database.md - Schema documentation
+- [ ] project/specs/*.md - Feature specifications
+- [ ] project/architecture/*.md - Architecture documents
+- [ ] project/sessions/*.md - Session summaries
+
+### File Update Frequency
+
+| File | Update Frequency |
+|------|------------------|
+| CLAUDE.md | When conventions change |
+| README.md | When setup changes |
+| plan.md / devplan.md | Start of each phase |
+| devprogress.md | After each task |
+| architecture.md | When design changes |
+| specs/*.md | Before implementing feature |
+| sessions/*.md | End of each session |
+
+---
+
+**Prev:** [Git Workflow](./11-git-workflow.md) | **Next:** [Documentation Writing](./13-documentation-writing.md)
diff --git a/docs/13-documentation-writing.md b/docs/13-documentation-writing.md
new file mode 100644
index 0000000..f080cd4
--- /dev/null
+++ b/docs/13-documentation-writing.md
@@ -0,0 +1,556 @@
+# Documentation Writing
+
+How to write effective documentation for AI-first development projects.
+
+## Why Documentation Writing Matters
+
+In AI-first development, documentation serves as:
+- **AI context** - Claude reads your docs to understand patterns
+- **Team knowledge** - Shared understanding across developers
+- **Decision history** - Why choices were made
+- **Onboarding material** - New team members get up to speed
+
+Good documentation is precise, scannable, and actionable.
+
+## Types of Documentation
+
+| Type | Purpose | Audience | Update Frequency |
+|------|---------|----------|------------------|
+| API Documentation | Endpoint contracts | Frontend devs, integrators | Per API change |
+| Code Comments | Logic explanation | Future maintainers | With code changes |
+| ADRs | Decision rationale | Team, future devs | Per major decision |
+| README | Project entry point | All developers | Setup changes |
+| Inline Types | Type contracts | All developers | With code changes |
+
+---
+
+## API Documentation
+
+### OpenAPI/Swagger
+
+For REST APIs, use OpenAPI specification:
+
+```yaml
+openapi: 3.0.0
+info:
+ title: My API
+ version: 1.0.0
+ description: User authentication and management API
+
+paths:
+ /api/auth/register:
+ post:
+ summary: Register a new user
+ tags:
+ - Authentication
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ required:
+ - email
+ - password
+ properties:
+ email:
+ type: string
+ format: email
+ example: user@example.com
+ password:
+ type: string
+ minLength: 8
+ example: securepassword123
+ responses:
+ '201':
+ description: User created successfully
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/User'
+ '400':
+ description: Invalid input
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ '409':
+ description: Email already exists
+
+components:
+ schemas:
+ User:
+ type: object
+ properties:
+ id:
+ type: integer
+ email:
+ type: string
+ created_at:
+ type: string
+ format: date-time
+ Error:
+ type: object
+ properties:
+ error:
+ type: string
+ code:
+ type: string
+```
+
+### Markdown API Docs
+
+For simpler projects, markdown tables work well:
+
+```markdown
+## POST /api/auth/register
+
+Register a new user account.
+
+### Request
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| email | string | Yes | Valid email address |
+| password | string | Yes | Min 8 characters |
+
+### Response
+
+**201 Created**
+```json
+{
+ "id": 1,
+ "email": "user@example.com",
+ "created_at": "2025-01-15T10:00:00Z"
+}
+```
+
+**400 Bad Request**
+```json
+{
+ "error": "invalid email format",
+ "code": "VALIDATION_ERROR"
+}
+```
+
+### Example
+
+```bash
+curl -X POST http://localhost:8080/api/auth/register \
+ -H "Content-Type: application/json" \
+ -d '{"email": "user@example.com", "password": "securepass123"}'
+```
+```
+
+### Best Practices for API Docs
+
+**Do:**
+- Include request and response examples
+- Document all error codes
+- Show authentication requirements
+- Provide cURL examples
+- Keep examples up-to-date
+
+**Don't:**
+- Document internal-only endpoints publicly
+- Include sensitive data in examples
+- Forget to update after API changes
+- Use placeholder values without explaining
+
+---
+
+## Code Comments
+
+### When to Comment
+
+**Comment when:**
+- Logic is non-obvious
+- Business rules are embedded
+- Workarounds exist for known issues
+- Complex algorithms are used
+- External dependencies have quirks
+
+**Don't comment:**
+- Obvious code (`i++ // increment i`)
+- Self-explanatory function names
+- Every line or function
+- Commented-out code (delete it)
+
+### Comment Patterns
+
+**Function documentation (Go):**
+```go
+// CreateUser creates a new user with the given email and password.
+// The password is hashed using bcrypt before storage.
+// Returns ErrDuplicateEmail if the email already exists.
+func (r *UserRepository) CreateUser(ctx context.Context, email, password string) (*User, error) {
+ // ...
+}
+```
+
+**Function documentation (TypeScript):**
+```typescript
+/**
+ * Creates a new user with the given email and password.
+ * @param email - User's email address (must be unique)
+ * @param password - Plain text password (will be hashed)
+ * @returns The created user object
+ * @throws {DuplicateEmailError} If email already exists
+ */
+async function createUser(email: string, password: string): Promise {
+ // ...
+}
+```
+
+**Inline comments for complex logic:**
+```go
+func calculateDiscount(order Order) float64 {
+ discount := 0.0
+
+ // Apply volume discount: 10% off for orders over $100
+ if order.Total > 100 {
+ discount += 0.10
+ }
+
+ // Loyalty discount: additional 5% for customers with 10+ orders
+ // Note: This stacks with volume discount per business requirement #42
+ if order.Customer.OrderCount >= 10 {
+ discount += 0.05
+ }
+
+ // Cap total discount at 20% per finance policy
+ if discount > 0.20 {
+ discount = 0.20
+ }
+
+ return discount
+}
+```
+
+**TODO comments:**
+```go
+// TODO(username): Implement retry logic for transient failures
+// See: https://github.com/org/repo/issues/123
+
+// FIXME: This query is slow for large datasets, needs optimization
+// Tracked in JIRA-456
+
+// HACK: Workaround for library bug, remove after upgrading to v2.0
+// See: https://github.com/lib/issues/789
+```
+
+---
+
+## Architecture Decision Records (ADRs)
+
+ADRs document significant technical decisions and their rationale.
+
+### ADR Template
+
+```markdown
+# ADR-001: Use PostgreSQL for Primary Database
+
+## Status
+Accepted
+
+## Date
+2025-01-15
+
+## Context
+We need to choose a primary database for our application. The application
+requires:
+- ACID transactions for financial data
+- JSON storage for flexible schemas
+- Full-text search capabilities
+- Horizontal read scaling
+
+## Options Considered
+
+### Option 1: PostgreSQL
+**Pros:**
+- ACID compliant
+- Native JSON/JSONB support
+- Full-text search built-in
+- Read replicas for scaling
+- Mature ecosystem
+
+**Cons:**
+- More complex than SQLite for small projects
+- Requires separate server process
+
+### Option 2: MongoDB
+**Pros:**
+- Flexible schema
+- Built-in horizontal scaling
+- Good for document-heavy workloads
+
+**Cons:**
+- No true ACID transactions (until v4.0)
+- Different query paradigm
+- Less mature tooling for our stack
+
+### Option 3: MySQL
+**Pros:**
+- Widely used
+- Good performance
+- Simple replication
+
+**Cons:**
+- JSON support less mature than PostgreSQL
+- Full-text search requires separate engine
+
+## Decision
+We will use **PostgreSQL** as our primary database.
+
+## Rationale
+PostgreSQL best meets our requirements:
+1. ACID transactions are critical for financial data
+2. JSONB allows flexible schemas without sacrificing query performance
+3. Built-in full-text search avoids additional infrastructure
+4. The team has PostgreSQL experience
+
+## Consequences
+
+### Positive
+- Strong data integrity guarantees
+- Single database handles JSON and relational data
+- Proven scaling patterns available
+
+### Negative
+- Requires PostgreSQL expertise for optimization
+- More operational overhead than SQLite
+- Team needs to learn PostgreSQL-specific features
+
+## Related
+- ADR-002: Use TimescaleDB extension for time-series data
+- ADR-003: Database backup and recovery strategy
+```
+
+### When to Write ADRs
+
+Write an ADR when:
+- Choosing between technologies (database, framework, library)
+- Defining architectural patterns (microservices, monolith)
+- Setting standards (API versioning, error handling)
+- Making trade-offs (performance vs. simplicity)
+- Changing existing patterns
+
+### ADR File Organization
+
+```
+docs/
+└── adr/
+ ├── README.md # Index of all ADRs
+ ├── 001-database.md
+ ├── 002-authentication.md
+ ├── 003-api-versioning.md
+ └── template.md # ADR template
+```
+
+---
+
+## Living Documentation
+
+Documentation that stays in sync with code.
+
+### Documentation as Code
+
+**Generate docs from code:**
+```bash
+# Go - godoc
+godoc -http=:6060
+
+# TypeScript - TypeDoc
+npx typedoc --out docs src/
+
+# Python - Sphinx
+sphinx-build -b html docs/ docs/_build/
+
+# OpenAPI - Generate from annotations
+swag init # Go
+```
+
+**Test documentation examples:**
+```go
+// Example code in Go tests becomes documentation
+func ExampleCreateUser() {
+ user, err := CreateUser("test@example.com", "password123")
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Println(user.Email)
+ // Output: test@example.com
+}
+```
+
+### Documentation Testing
+
+Ensure documentation stays accurate:
+
+```yaml
+# GitHub Actions workflow
+name: Docs
+on: [push]
+jobs:
+ test-docs:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ # Test code examples in markdown
+ - name: Test markdown code blocks
+ run: npx markdown-doctest
+
+ # Verify links aren't broken
+ - name: Check links
+ run: npx markdown-link-check **/*.md
+
+ # Ensure OpenAPI spec is valid
+ - name: Validate OpenAPI
+ run: npx @redocly/cli lint openapi.yaml
+```
+
+### AI-Assisted Documentation Updates
+
+Ask Claude to help maintain docs:
+
+```
+I've added a new endpoint POST /api/orders. Please:
+1. Update the API documentation in docs/api.md
+2. Add the endpoint to the OpenAPI spec
+3. Create a code example for the README
+
+Here's the handler code:
+[paste code]
+```
+
+---
+
+## README Best Practices
+
+### Essential Sections
+
+Every README should have:
+
+1. **Title and description** - What is this?
+2. **Quick start** - How to run it?
+3. **Prerequisites** - What's needed?
+4. **Installation** - Step-by-step setup
+5. **Usage** - Basic examples
+6. **Documentation links** - Where to learn more
+
+### README vs Other Docs
+
+| README | Other Docs |
+|--------|------------|
+| Quick start | Detailed guides |
+| Overview | Deep dives |
+| Basic examples | All examples |
+| Setup steps | Troubleshooting |
+| Links to more | Full content |
+
+### Keep README Fresh
+
+```markdown
+
+## Quick Start
+
+
+```bash
+npm install
+npm run dev
+```
+
+Last verified: 2025-01-15
+```
+
+---
+
+## Documentation Style Guide
+
+### Writing Style
+
+**Be direct:**
+```markdown
+❌ "You might want to consider running the tests"
+✅ "Run the tests"
+
+❌ "It is recommended that users should..."
+✅ "Users should..."
+```
+
+**Use active voice:**
+```markdown
+❌ "The configuration file is read by the server"
+✅ "The server reads the configuration file"
+```
+
+**Be specific:**
+```markdown
+❌ "Set the timeout to an appropriate value"
+✅ "Set the timeout to 30 seconds"
+```
+
+### Formatting Conventions
+
+**Headings:**
+- `#` for page title (one per doc)
+- `##` for main sections
+- `###` for subsections
+- Don't skip levels
+
+**Code blocks:**
+- Always specify language
+- Keep examples runnable
+- Show expected output
+
+**Lists:**
+- Use bullets for unordered items
+- Use numbers for sequences
+- Keep items parallel in structure
+
+---
+
+## Prompting Claude for Documentation
+
+### Generating API Docs
+```
+Generate OpenAPI 3.0 documentation for this Go handler:
+[paste handler code]
+
+Include:
+- All request parameters
+- All response codes
+- Example requests and responses
+- Authentication requirements
+```
+
+### Updating Documentation
+```
+The codebase has changed. Please update the documentation:
+
+Changes made:
+- Added rate limiting to /api/auth endpoints
+- Changed password minimum from 6 to 8 characters
+- Added new field 'phone' to user registration
+
+Files to update:
+- docs/api.md
+- README.md
+```
+
+### Creating ADRs
+```
+I need to write an ADR for choosing between REST and GraphQL for our API.
+
+Context:
+- Team has REST experience
+- Frontend needs flexible queries
+- Performance is important
+
+Please write a complete ADR evaluating both options.
+```
+
+---
+
+**Prev:** [Documentation Organization](./12-documentation-organization.md) | **Next:** [Code Review](./14-code-review.md)
diff --git a/docs/14-code-review.md b/docs/14-code-review.md
new file mode 100644
index 0000000..cd94893
--- /dev/null
+++ b/docs/14-code-review.md
@@ -0,0 +1,475 @@
+# Code Review Best Practices
+
+How to effectively review code in AI-first development where AI generates code and humans validate.
+
+## The Three-Layer Review Model
+
+In AI-first development, code passes through three review layers:
+
+```
+┌─────────────────────────────────────────┐
+│ Layer 1: Self-Review (Developer) │
+│ - Read what AI generated │
+│ - Check it matches requirements │
+│ - Verify tests pass │
+└─────────────────┬───────────────────────┘
+ ▼
+┌─────────────────────────────────────────┐
+│ Layer 2: Automated Review (CI) │
+│ - Linting and formatting │
+│ - Test execution │
+│ - Security scanning │
+│ - Coverage thresholds │
+└─────────────────┬───────────────────────┘
+ ▼
+┌─────────────────────────────────────────┐
+│ Layer 3: Peer Review (Team) │
+│ - Architecture alignment │
+│ - Business logic correctness │
+│ - Edge cases and error handling │
+│ - Knowledge sharing │
+└─────────────────────────────────────────┘
+```
+
+## Layer 1: Self-Review
+
+Before submitting any PR, the developer (human) must review AI-generated code.
+
+### Self-Review Checklist
+
+**Understanding:**
+- [ ] I understand what every line does
+- [ ] I can explain the logic to someone else
+- [ ] The code matches the specification
+
+**Correctness:**
+- [ ] The code does what was requested
+- [ ] Edge cases are handled
+- [ ] Error handling is appropriate
+- [ ] No obvious bugs
+
+**Quality:**
+- [ ] Code follows project conventions
+- [ ] No unnecessary complexity
+- [ ] No hardcoded values that should be configurable
+- [ ] Tests are meaningful (not just for coverage)
+
+**Security:**
+- [ ] No secrets in code
+- [ ] Input is validated
+- [ ] No SQL injection vulnerabilities
+- [ ] Authentication/authorization is correct
+
+### Common AI Code Issues to Catch
+
+**1. Over-engineering:**
+```go
+// AI sometimes creates unnecessary abstractions
+// ❌ Over-engineered
+type UserServiceInterface interface {
+ CreateUser(ctx context.Context, req CreateUserRequest) (*CreateUserResponse, error)
+}
+
+type UserServiceImpl struct {
+ repo UserRepositoryInterface
+}
+
+func NewUserService(repo UserRepositoryInterface) UserServiceInterface {
+ return &UserServiceImpl{repo: repo}
+}
+
+// ✅ Simpler when you only have one implementation
+type UserService struct {
+ repo *UserRepository
+}
+
+func NewUserService(repo *UserRepository) *UserService {
+ return &UserService{repo: repo}
+}
+```
+
+**2. Missing error context:**
+```go
+// ❌ AI might return bare errors
+if err != nil {
+ return err
+}
+
+// ✅ Add context
+if err != nil {
+ return fmt.Errorf("failed to create user: %w", err)
+}
+```
+
+**3. Incomplete validation:**
+```go
+// ❌ AI might miss edge cases
+func CreateUser(email string, password string) error {
+ // Missing: email format validation
+ // Missing: password strength validation
+ // Missing: duplicate email check
+}
+
+// ✅ Complete validation
+func CreateUser(email string, password string) error {
+ if !isValidEmail(email) {
+ return ErrInvalidEmail
+ }
+ if len(password) < 8 {
+ return ErrWeakPassword
+ }
+ if exists, _ := userExists(email); exists {
+ return ErrDuplicateEmail
+ }
+ // ...
+}
+```
+
+**4. Hardcoded values:**
+```go
+// ❌ Hardcoded configuration
+token, _ := jwt.Sign(claims, "my-secret-key")
+time.Sleep(5 * time.Second)
+
+// ✅ Configurable
+token, _ := jwt.Sign(claims, config.JWTSecret)
+time.Sleep(config.RetryDelay)
+```
+
+---
+
+## Layer 2: Automated Review
+
+Automated checks catch issues before human review.
+
+### Essential Automated Checks
+
+**Linting:**
+```yaml
+# .github/workflows/ci.yml
+- name: Lint Go
+ run: golangci-lint run
+
+- name: Lint TypeScript
+ run: npm run lint
+
+- name: Lint Python
+ run: ruff check .
+```
+
+**Formatting:**
+```yaml
+- name: Check formatting
+ run: |
+ go fmt ./...
+ git diff --exit-code # Fail if changes
+```
+
+**Tests:**
+```yaml
+- name: Run tests
+ run: go test -race -coverprofile=coverage.out ./...
+
+- name: Check coverage
+ run: |
+ coverage=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
+ if (( $(echo "$coverage < 70" | bc -l) )); then
+ echo "Coverage $coverage% is below 70% threshold"
+ exit 1
+ fi
+```
+
+**Security scanning:**
+```yaml
+- name: Security scan
+ run: gosec ./...
+
+- name: Dependency audit
+ run: npm audit --audit-level=high
+```
+
+### Pre-commit Hooks
+
+Run checks locally before pushing:
+
+```yaml
+# .pre-commit-config.yaml
+repos:
+ - repo: local
+ hooks:
+ - id: go-fmt
+ name: Go format
+ entry: go fmt ./...
+ language: system
+ pass_filenames: false
+
+ - id: go-test
+ name: Go test
+ entry: go test ./...
+ language: system
+ pass_filenames: false
+
+ - id: go-vet
+ name: Go vet
+ entry: go vet ./...
+ language: system
+ pass_filenames: false
+```
+
+---
+
+## Layer 3: Peer Review
+
+Human review focuses on what automation can't catch.
+
+### What Reviewers Should Check
+
+**1. Architecture alignment:**
+- Does this follow our established patterns?
+- Is this the right place for this code?
+- Does it fit with our overall design?
+
+**2. Business logic:**
+- Does this correctly implement the requirements?
+- Are there business edge cases not covered?
+- Is the behavior correct for all user types?
+
+**3. Maintainability:**
+- Will future developers understand this?
+- Is there unnecessary complexity?
+- Are there opportunities to reuse existing code?
+
+**4. Performance implications:**
+- Are there N+1 query issues?
+- Is there unnecessary data loading?
+- Could this become slow at scale?
+
+### Review Comment Guidelines
+
+**Be specific:**
+```markdown
+❌ "This could be better"
+✅ "Consider using a map here instead of a slice for O(1) lookup"
+```
+
+**Explain why:**
+```markdown
+❌ "Don't use string concatenation in a loop"
+✅ "String concatenation in a loop creates many allocations.
+ Use strings.Builder for better performance."
+```
+
+**Suggest solutions:**
+```markdown
+❌ "This validation is incomplete"
+✅ "This validation is missing the case where email is empty.
+ Consider: `if email == "" { return ErrEmptyEmail }`"
+```
+
+**Distinguish severity:**
+```markdown
+🔴 BLOCKER: Security issue - user input not sanitized
+🟡 SHOULD FIX: Performance issue - N+1 queries
+🟢 SUGGESTION: Consider extracting this to a helper function
+❓ QUESTION: Why did we choose this approach over X?
+```
+
+### PR Size Guidelines
+
+| Size | Lines Changed | Review Time | Guidance |
+|------|--------------|-------------|----------|
+| XS | < 50 | 5-10 min | Quick review |
+| S | 50-200 | 15-30 min | Standard review |
+| M | 200-500 | 30-60 min | Detailed review |
+| L | 500-1000 | 1-2 hours | Consider splitting |
+| XL | > 1000 | Too long | Must split |
+
+**Large PRs should be split by:**
+- Layer (database, API, tests separately)
+- Feature (one PR per sub-feature)
+- Refactor vs. feature (separate PRs)
+
+---
+
+## AI-Generated Code Review Checklist
+
+Use this checklist specifically for AI-generated code:
+
+### Functionality
+- [ ] Code implements the requested feature correctly
+- [ ] All acceptance criteria are met
+- [ ] Edge cases are handled (empty inputs, nulls, boundaries)
+- [ ] Error messages are helpful and user-friendly
+
+### Code Quality
+- [ ] Code follows project style guidelines
+- [ ] Variable names are descriptive and consistent
+- [ ] No dead code or commented-out code
+- [ ] Functions are focused and not too long (< 50 lines)
+- [ ] No unnecessary abstractions
+
+### Testing
+- [ ] Tests exist and are meaningful
+- [ ] Tests cover happy path and error cases
+- [ ] Tests are not just achieving coverage numbers
+- [ ] Test names describe what they test
+
+### Security
+- [ ] No hardcoded secrets or credentials
+- [ ] User input is validated and sanitized
+- [ ] SQL queries use parameterized statements
+- [ ] Authentication is checked where needed
+- [ ] Sensitive data is not logged
+
+### Performance
+- [ ] No obvious N+1 query problems
+- [ ] Database queries are efficient (indexes used)
+- [ ] No unnecessary memory allocations
+- [ ] Pagination is used for large datasets
+
+### Documentation
+- [ ] Public APIs are documented
+- [ ] Complex logic has explanatory comments
+- [ ] README is updated if needed
+- [ ] CHANGELOG is updated
+
+---
+
+## Review Workflow
+
+### Standard PR Flow
+
+```
+1. Developer creates PR
+ ↓
+2. Automated checks run (CI)
+ ↓ (pass)
+3. Request review from team member
+ ↓
+4. Reviewer examines code
+ ↓
+5. Reviewer leaves comments
+ ↓ (if changes needed)
+6. Developer addresses feedback
+ ↓ (loop until approved)
+7. Reviewer approves
+ ↓
+8. Developer merges (squash)
+```
+
+### Review Response Time
+
+| Priority | Response Time | Merge Time |
+|----------|--------------|------------|
+| Critical hotfix | < 1 hour | Same day |
+| Normal feature | < 24 hours | 2-3 days |
+| Refactoring | < 48 hours | 1 week |
+| Documentation | < 48 hours | 1 week |
+
+### Handling Review Feedback
+
+**As the author:**
+- Respond to all comments
+- Don't take feedback personally
+- Ask for clarification if unclear
+- Mark resolved comments as resolved
+
+**As the reviewer:**
+- Be constructive, not critical
+- Acknowledge good work
+- Approve when ready, don't delay
+- Follow up on your comments
+
+---
+
+## Reviewing AI-Generated Tests
+
+Tests from AI need special attention:
+
+### Watch for Weak Tests
+
+```javascript
+// ❌ Test that always passes
+test('user is created', () => {
+ const user = createUser('test@example.com');
+ expect(user).toBeDefined(); // Too weak
+});
+
+// ✅ Test with meaningful assertions
+test('user is created with correct properties', () => {
+ const user = createUser('test@example.com', 'password123');
+ expect(user.email).toBe('test@example.com');
+ expect(user.passwordHash).not.toBe('password123');
+ expect(user.createdAt).toBeInstanceOf(Date);
+});
+```
+
+### Watch for Missing Error Tests
+
+```javascript
+// AI often forgets error cases
+describe('createUser', () => {
+ test('creates user successfully', () => { /* ... */ });
+
+ // ❌ Missing error tests
+ // ✅ Add these:
+ test('rejects invalid email', () => { /* ... */ });
+ test('rejects weak password', () => { /* ... */ });
+ test('rejects duplicate email', () => { /* ... */ });
+});
+```
+
+### Watch for Hardcoded Test Data
+
+```javascript
+// ❌ Hardcoded IDs that might conflict
+test('gets user by id', async () => {
+ const user = await getUserById(1); // ID 1 might not exist
+ expect(user).toBeDefined();
+});
+
+// ✅ Create test data
+test('gets user by id', async () => {
+ const created = await createUser('test@example.com');
+ const user = await getUserById(created.id);
+ expect(user.email).toBe('test@example.com');
+});
+```
+
+---
+
+## Code Review Tools
+
+### GitHub Features
+
+- **Required reviews:** Enforce minimum reviewers
+- **Code owners:** Auto-assign relevant reviewers
+- **Branch protection:** Require CI pass and reviews
+- **Review comments:** Inline code discussions
+
+### Additional Tools
+
+| Tool | Purpose |
+|------|---------|
+| `danger` | Automated PR checks and comments |
+| `reviewdog` | Post linter results as PR comments |
+| `codecov` | Coverage tracking and PR comments |
+| `sonarqube` | Code quality and security analysis |
+
+---
+
+## Summary
+
+**Key Principles:**
+- Three layers: Self, Automated, Peer
+- AI code needs extra scrutiny
+- Keep PRs small and focused
+- Be constructive in feedback
+- Reviewers catch what automation can't
+
+**Self-Review First:**
+Always review AI-generated code yourself before requesting peer review. You're responsible for understanding and vouching for the code.
+
+---
+
+**Prev:** [Documentation Writing](./13-documentation-writing.md) | **Next:** [Security Practices](./15-security.md)
diff --git a/docs/15-security.md b/docs/15-security.md
new file mode 100644
index 0000000..469e835
--- /dev/null
+++ b/docs/15-security.md
@@ -0,0 +1,540 @@
+# Security Practices
+
+Security considerations for AI-first development and protecting code generated by AI.
+
+## Why AI Code Needs Security Review
+
+AI-generated code can have security blind spots:
+- May not know your specific security requirements
+- Can introduce common vulnerabilities if not prompted correctly
+- Might use outdated security patterns
+- May not consider your deployment environment
+
+**Every piece of AI-generated code should be reviewed for security.**
+
+---
+
+## Authentication & Authorization
+
+### JWT Best Practices
+
+**Token structure:**
+```go
+type Claims struct {
+ UserID int `json:"user_id"`
+ Email string `json:"email"`
+ Role string `json:"role"`
+ jwt.RegisteredClaims
+}
+
+func GenerateToken(user *User) (string, error) {
+ claims := Claims{
+ UserID: user.ID,
+ Email: user.Email,
+ Role: user.Role,
+ RegisteredClaims: jwt.RegisteredClaims{
+ ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
+ IssuedAt: jwt.NewNumericDate(time.Now()),
+ NotBefore: jwt.NewNumericDate(time.Now()),
+ Issuer: "my-api",
+ Subject: strconv.Itoa(user.ID),
+ },
+ }
+
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+ return token.SignedString([]byte(os.Getenv("JWT_SECRET")))
+}
+```
+
+**Token validation:**
+```go
+func ValidateToken(tokenString string) (*Claims, error) {
+ token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
+ // Verify signing method
+ if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
+ return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
+ }
+ return []byte(os.Getenv("JWT_SECRET")), nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ if claims, ok := token.Claims.(*Claims); ok && token.Valid {
+ return claims, nil
+ }
+
+ return nil, ErrInvalidToken
+}
+```
+
+**Security checklist for JWT:**
+- [ ] Use strong secret (256+ bits)
+- [ ] Set reasonable expiration (hours, not days)
+- [ ] Validate signing algorithm
+- [ ] Include user ID, not sensitive data
+- [ ] Use HTTPS only
+- [ ] Implement token refresh
+- [ ] Consider token revocation strategy
+
+### Password Handling
+
+**Hashing:**
+```go
+import "golang.org/x/crypto/bcrypt"
+
+const bcryptCost = 12 // Adjust based on your server capacity
+
+func HashPassword(password string) (string, error) {
+ bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcryptCost)
+ return string(bytes), err
+}
+
+func CheckPassword(password, hash string) bool {
+ err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
+ return err == nil
+}
+```
+
+**Password requirements:**
+```go
+func ValidatePassword(password string) error {
+ if len(password) < 8 {
+ return errors.New("password must be at least 8 characters")
+ }
+
+ hasUpper := regexp.MustCompile(`[A-Z]`).MatchString(password)
+ hasLower := regexp.MustCompile(`[a-z]`).MatchString(password)
+ hasNumber := regexp.MustCompile(`[0-9]`).MatchString(password)
+
+ if !hasUpper || !hasLower || !hasNumber {
+ return errors.New("password must contain uppercase, lowercase, and number")
+ }
+
+ return nil
+}
+```
+
+### Role-Based Access Control (RBAC)
+
+**Define permissions:**
+```go
+type Permission string
+
+const (
+ PermUserRead Permission = "user:read"
+ PermUserWrite Permission = "user:write"
+ PermAdminAll Permission = "admin:*"
+)
+
+type Role struct {
+ Name string
+ Permissions []Permission
+}
+
+var Roles = map[string]Role{
+ "user": {
+ Name: "user",
+ Permissions: []Permission{PermUserRead},
+ },
+ "admin": {
+ Name: "admin",
+ Permissions: []Permission{PermUserRead, PermUserWrite, PermAdminAll},
+ },
+}
+```
+
+**Middleware:**
+```go
+func RequirePermission(required Permission) func(http.Handler) http.Handler {
+ return func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ claims := r.Context().Value("claims").(*Claims)
+ role := Roles[claims.Role]
+
+ if !hasPermission(role.Permissions, required) {
+ http.Error(w, "forbidden", http.StatusForbidden)
+ return
+ }
+
+ next.ServeHTTP(w, r)
+ })
+ }
+}
+```
+
+---
+
+## Input Validation & Sanitization
+
+### SQL Injection Prevention
+
+**Always use parameterized queries:**
+```go
+// ❌ NEVER do this - SQL injection vulnerability
+query := fmt.Sprintf("SELECT * FROM users WHERE email = '%s'", email)
+rows, err := db.Query(query)
+
+// ✅ Always use parameterized queries
+query := "SELECT * FROM users WHERE email = $1"
+rows, err := db.Query(query, email)
+
+// ✅ Or use query builder
+user, err := db.User.
+ Query().
+ Where(user.EmailEQ(email)).
+ Only(ctx)
+```
+
+### XSS Prevention
+
+**Escape output:**
+```go
+import "html"
+
+// In templates, use auto-escaping
+// Go's html/template does this automatically
+
+// For manual escaping:
+safeHTML := html.EscapeString(userInput)
+```
+
+**Content Security Policy:**
+```go
+func SecurityHeaders(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Security-Policy",
+ "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'")
+ w.Header().Set("X-Content-Type-Options", "nosniff")
+ w.Header().Set("X-Frame-Options", "DENY")
+ w.Header().Set("X-XSS-Protection", "1; mode=block")
+ next.ServeHTTP(w, r)
+ })
+}
+```
+
+### Request Validation
+
+**Validate all inputs:**
+```go
+type CreateUserRequest struct {
+ Email string `json:"email" validate:"required,email"`
+ Password string `json:"password" validate:"required,min=8"`
+ Name string `json:"name" validate:"required,max=100"`
+}
+
+func (h *Handler) CreateUser(w http.ResponseWriter, r *http.Request) {
+ var req CreateUserRequest
+ if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+ respondError(w, http.StatusBadRequest, "invalid JSON")
+ return
+ }
+
+ // Validate struct
+ if err := h.validator.Struct(req); err != nil {
+ respondError(w, http.StatusBadRequest, formatValidationErrors(err))
+ return
+ }
+
+ // Sanitize inputs
+ req.Email = strings.ToLower(strings.TrimSpace(req.Email))
+ req.Name = strings.TrimSpace(req.Name)
+
+ // ... proceed with validated, sanitized data
+}
+```
+
+---
+
+## Secrets Management
+
+### Environment Variables
+
+**Never commit secrets:**
+```bash
+# .gitignore
+.env
+.env.local
+.env.*.local
+*.pem
+*.key
+credentials.json
+```
+
+**Use .env.example:**
+```bash
+# .env.example (commit this)
+DATABASE_URL=postgres://user:pass@localhost:5432/dbname
+JWT_SECRET=your-secret-here-min-32-chars
+API_KEY=your-api-key
+```
+
+**Load securely:**
+```go
+func LoadConfig() (*Config, error) {
+ // In development, load from .env
+ if os.Getenv("ENV") != "production" {
+ godotenv.Load()
+ }
+
+ config := &Config{
+ DatabaseURL: os.Getenv("DATABASE_URL"),
+ JWTSecret: os.Getenv("JWT_SECRET"),
+ }
+
+ // Validate required config
+ if config.JWTSecret == "" {
+ return nil, errors.New("JWT_SECRET is required")
+ }
+ if len(config.JWTSecret) < 32 {
+ return nil, errors.New("JWT_SECRET must be at least 32 characters")
+ }
+
+ return config, nil
+}
+```
+
+### Secret Scanning
+
+**Pre-commit hook:**
+```yaml
+# .pre-commit-config.yaml
+repos:
+ - repo: https://github.com/Yelp/detect-secrets
+ rev: v1.4.0
+ hooks:
+ - id: detect-secrets
+ args: ['--baseline', '.secrets.baseline']
+```
+
+**CI scanning:**
+```yaml
+# GitHub Actions
+- name: Scan for secrets
+ uses: trufflesecurity/trufflehog@main
+ with:
+ path: ./
+ base: ${{ github.event.repository.default_branch }}
+```
+
+### Production Secrets
+
+**Use secret management services:**
+- AWS Secrets Manager
+- Google Secret Manager
+- HashiCorp Vault
+- Kubernetes Secrets
+
+```go
+// Example: AWS Secrets Manager
+func GetSecret(secretName string) (string, error) {
+ cfg, _ := config.LoadDefaultConfig(context.TODO())
+ client := secretsmanager.NewFromConfig(cfg)
+
+ result, err := client.GetSecretValue(context.TODO(), &secretsmanager.GetSecretValueInput{
+ SecretId: aws.String(secretName),
+ })
+ if err != nil {
+ return "", err
+ }
+
+ return *result.SecretString, nil
+}
+```
+
+---
+
+## API Security
+
+### Rate Limiting
+
+```go
+import "golang.org/x/time/rate"
+
+type RateLimiter struct {
+ visitors map[string]*rate.Limiter
+ mu sync.RWMutex
+ rate rate.Limit
+ burst int
+}
+
+func NewRateLimiter(r rate.Limit, b int) *RateLimiter {
+ return &RateLimiter{
+ visitors: make(map[string]*rate.Limiter),
+ rate: r,
+ burst: b,
+ }
+}
+
+func (rl *RateLimiter) GetLimiter(ip string) *rate.Limiter {
+ rl.mu.Lock()
+ defer rl.mu.Unlock()
+
+ limiter, exists := rl.visitors[ip]
+ if !exists {
+ limiter = rate.NewLimiter(rl.rate, rl.burst)
+ rl.visitors[ip] = limiter
+ }
+
+ return limiter
+}
+
+func RateLimitMiddleware(rl *RateLimiter) func(http.Handler) http.Handler {
+ return func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ ip := getIP(r)
+ limiter := rl.GetLimiter(ip)
+
+ if !limiter.Allow() {
+ http.Error(w, "rate limit exceeded", http.StatusTooManyRequests)
+ return
+ }
+
+ next.ServeHTTP(w, r)
+ })
+ }
+}
+```
+
+### CORS Configuration
+
+```go
+func CORSMiddleware(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ // Only allow specific origins in production
+ allowedOrigins := map[string]bool{
+ "https://myapp.com": true,
+ "https://www.myapp.com": true,
+ }
+
+ origin := r.Header.Get("Origin")
+ if allowedOrigins[origin] {
+ w.Header().Set("Access-Control-Allow-Origin", origin)
+ }
+
+ w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
+ w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
+ w.Header().Set("Access-Control-Max-Age", "86400")
+
+ if r.Method == "OPTIONS" {
+ w.WriteHeader(http.StatusNoContent)
+ return
+ }
+
+ next.ServeHTTP(w, r)
+ })
+}
+```
+
+### Error Message Security
+
+```go
+// ❌ Don't leak internal details
+func handleError(w http.ResponseWriter, err error) {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ // Exposes: "pq: duplicate key value violates unique constraint"
+}
+
+// ✅ Return safe error messages
+func handleError(w http.ResponseWriter, err error) {
+ // Log the real error internally
+ log.Printf("error: %v", err)
+
+ // Return generic message to client
+ var apiErr *APIError
+ if errors.As(err, &apiErr) {
+ respondJSON(w, apiErr.StatusCode, map[string]string{
+ "error": apiErr.Message,
+ "code": apiErr.Code,
+ })
+ return
+ }
+
+ respondJSON(w, http.StatusInternalServerError, map[string]string{
+ "error": "internal server error",
+ "code": "INTERNAL_ERROR",
+ })
+}
+```
+
+---
+
+## Security Checklist for PRs
+
+Use this checklist when reviewing AI-generated code:
+
+### Authentication
+- [ ] No hardcoded credentials
+- [ ] Passwords are hashed (bcrypt, argon2)
+- [ ] JWT tokens expire appropriately
+- [ ] Token validation checks algorithm
+- [ ] Session tokens are invalidated on logout
+
+### Authorization
+- [ ] All endpoints check permissions
+- [ ] Users can only access their own data
+- [ ] Admin functions require admin role
+- [ ] API keys have appropriate scopes
+
+### Input Validation
+- [ ] All user input is validated
+- [ ] SQL queries are parameterized
+- [ ] File uploads are restricted
+- [ ] JSON parsing has limits
+- [ ] Path traversal is prevented
+
+### Output
+- [ ] HTML is escaped
+- [ ] Errors don't leak internal info
+- [ ] Security headers are set
+- [ ] Sensitive data isn't logged
+
+### Secrets
+- [ ] No secrets in code or commits
+- [ ] Secrets loaded from environment
+- [ ] .env files are gitignored
+- [ ] Production uses secret manager
+
+### Dependencies
+- [ ] Dependencies are from trusted sources
+- [ ] No known vulnerable versions
+- [ ] Lock files are committed
+
+---
+
+## Prompting Claude for Secure Code
+
+**When requesting authentication:**
+```
+Implement user authentication with:
+- Password hashing using bcrypt (cost factor 12)
+- JWT tokens with 24-hour expiry
+- Token refresh mechanism
+- Rate limiting on auth endpoints (10 requests/minute)
+- Secure password requirements (min 8 chars, mixed case, numbers)
+
+Do NOT:
+- Store plain text passwords
+- Use hardcoded secrets
+- Return detailed error messages to clients
+```
+
+**When requesting API endpoints:**
+```
+Create a CRUD API for [resource] with:
+- Input validation for all fields
+- Parameterized SQL queries only
+- Permission checks on each endpoint
+- Rate limiting
+- Pagination for list endpoints
+
+Security requirements:
+- Sanitize all string inputs
+- Validate IDs are integers
+- Check user owns the resource before update/delete
+```
+
+---
+
+**Prev:** [Code Review](./14-code-review.md) | **Next:** [Performance Optimization](./16-performance.md)
diff --git a/docs/16-performance.md b/docs/16-performance.md
new file mode 100644
index 0000000..3b38417
--- /dev/null
+++ b/docs/16-performance.md
@@ -0,0 +1,601 @@
+# Performance Optimization
+
+How to identify and resolve performance issues in AI-first development.
+
+## Performance-First Mindset
+
+**Core principle:** Measure before optimizing.
+
+```
+1. Define performance goals
+2. Measure current state
+3. Identify bottlenecks
+4. Optimize the bottleneck
+5. Measure again
+6. Repeat
+```
+
+**Don't:**
+- Optimize without measuring
+- Assume you know where the problem is
+- Optimize everything at once
+- Sacrifice readability for micro-optimizations
+
+---
+
+## Performance Budgets
+
+Set clear targets before implementation:
+
+| Metric | Target | Measurement |
+|--------|--------|-------------|
+| API response (p50) | < 100ms | Server-side |
+| API response (p95) | < 500ms | Server-side |
+| Page load (FCP) | < 1.5s | Lighthouse |
+| Page load (LCP) | < 2.5s | Lighthouse |
+| Time to Interactive | < 3.5s | Lighthouse |
+| Bundle size (JS) | < 200KB gzip | Build output |
+
+---
+
+## Database Performance
+
+### Query Optimization
+
+**Identify slow queries:**
+```sql
+-- PostgreSQL: Find slow queries
+SELECT query, calls, mean_time, total_time
+FROM pg_stat_statements
+ORDER BY mean_time DESC
+LIMIT 10;
+
+-- Enable slow query logging
+ALTER SYSTEM SET log_min_duration_statement = 1000; -- Log queries > 1s
+```
+
+**Common optimizations:**
+
+**1. Add indexes:**
+```sql
+-- Before: Full table scan
+SELECT * FROM users WHERE email = 'user@example.com';
+-- Query time: 500ms (1M rows)
+
+-- After: Index scan
+CREATE INDEX idx_users_email ON users(email);
+-- Query time: 1ms
+```
+
+**2. Use composite indexes for multi-column queries:**
+```sql
+-- Query pattern
+SELECT * FROM orders WHERE user_id = 1 AND status = 'pending';
+
+-- Single column index - partially effective
+CREATE INDEX idx_orders_user_id ON orders(user_id);
+
+-- Composite index - optimal for this query
+CREATE INDEX idx_orders_user_status ON orders(user_id, status);
+```
+
+**3. Avoid SELECT *:**
+```go
+// ❌ Fetches all columns
+rows, _ := db.Query("SELECT * FROM users WHERE id = $1", id)
+
+// ✅ Fetch only needed columns
+rows, _ := db.Query("SELECT id, email, name FROM users WHERE id = $1", id)
+```
+
+### N+1 Query Problem
+
+The most common performance issue in AI-generated code.
+
+**Problem:**
+```go
+// Fetches all orders
+orders, _ := db.Query("SELECT * FROM orders")
+
+for orders.Next() {
+ var order Order
+ orders.Scan(&order.ID, &order.UserID, ...)
+
+ // N additional queries!
+ user, _ := db.QueryRow("SELECT * FROM users WHERE id = $1", order.UserID)
+}
+// 1 + N queries total
+```
+
+**Solution - JOIN:**
+```go
+query := `
+ SELECT o.id, o.total, u.id, u.name, u.email
+ FROM orders o
+ JOIN users u ON u.id = o.user_id
+`
+rows, _ := db.Query(query)
+// 1 query total
+```
+
+**Solution - Batch load:**
+```go
+// Get all orders
+orders, _ := getOrders()
+
+// Collect unique user IDs
+userIDs := make(map[int]bool)
+for _, o := range orders {
+ userIDs[o.UserID] = true
+}
+
+// Single query for all users
+users, _ := getUsersByIDs(keys(userIDs))
+// 2 queries total (regardless of order count)
+```
+
+### Connection Pooling
+
+```go
+import "database/sql"
+
+func SetupDB() *sql.DB {
+ db, _ := sql.Open("postgres", connectionString)
+
+ // Configure pool
+ db.SetMaxOpenConns(25) // Max concurrent connections
+ db.SetMaxIdleConns(5) // Idle connections to keep
+ db.SetConnMaxLifetime(5 * time.Minute) // Recycle connections
+
+ return db
+}
+```
+
+### Caching Strategies
+
+**Application-level cache:**
+```go
+import "github.com/patrickmn/go-cache"
+
+var userCache = cache.New(5*time.Minute, 10*time.Minute)
+
+func GetUser(id int) (*User, error) {
+ // Check cache first
+ key := fmt.Sprintf("user:%d", id)
+ if cached, found := userCache.Get(key); found {
+ return cached.(*User), nil
+ }
+
+ // Cache miss - fetch from DB
+ user, err := db.GetUser(id)
+ if err != nil {
+ return nil, err
+ }
+
+ // Store in cache
+ userCache.Set(key, user, cache.DefaultExpiration)
+ return user, nil
+}
+```
+
+**Redis cache:**
+```go
+func GetUser(ctx context.Context, id int) (*User, error) {
+ key := fmt.Sprintf("user:%d", id)
+
+ // Try cache
+ data, err := redis.Get(ctx, key).Bytes()
+ if err == nil {
+ var user User
+ json.Unmarshal(data, &user)
+ return &user, nil
+ }
+
+ // Cache miss
+ user, err := db.GetUser(id)
+ if err != nil {
+ return nil, err
+ }
+
+ // Cache for 5 minutes
+ data, _ := json.Marshal(user)
+ redis.Set(ctx, key, data, 5*time.Minute)
+
+ return user, nil
+}
+```
+
+**Cache invalidation:**
+```go
+func UpdateUser(ctx context.Context, user *User) error {
+ // Update database
+ if err := db.UpdateUser(user); err != nil {
+ return err
+ }
+
+ // Invalidate cache
+ key := fmt.Sprintf("user:%d", user.ID)
+ redis.Del(ctx, key)
+
+ return nil
+}
+```
+
+---
+
+## API Performance
+
+### Response Time Optimization
+
+**1. Pagination:**
+```go
+type PaginatedResponse struct {
+ Data []Item `json:"data"`
+ Meta Meta `json:"meta"`
+}
+
+type Meta struct {
+ Page int `json:"page"`
+ PerPage int `json:"per_page"`
+ TotalItems int `json:"total_items"`
+ TotalPages int `json:"total_pages"`
+}
+
+func GetItems(page, perPage int) (*PaginatedResponse, error) {
+ // Limit per_page to prevent abuse
+ if perPage > 100 {
+ perPage = 100
+ }
+
+ offset := (page - 1) * perPage
+
+ items, _ := db.Query(`
+ SELECT * FROM items
+ ORDER BY created_at DESC
+ LIMIT $1 OFFSET $2
+ `, perPage, offset)
+
+ total, _ := db.QueryRow("SELECT COUNT(*) FROM items")
+
+ return &PaginatedResponse{
+ Data: items,
+ Meta: Meta{
+ Page: page,
+ PerPage: perPage,
+ TotalItems: total,
+ TotalPages: (total + perPage - 1) / perPage,
+ },
+ }, nil
+}
+```
+
+**2. Field selection:**
+```go
+// Allow clients to request specific fields
+// GET /api/users?fields=id,name,email
+
+func GetUsers(fields []string) ([]map[string]interface{}, error) {
+ allowedFields := map[string]bool{
+ "id": true, "name": true, "email": true, "created_at": true,
+ }
+
+ // Validate and build SELECT clause
+ selectFields := []string{}
+ for _, f := range fields {
+ if allowedFields[f] {
+ selectFields = append(selectFields, f)
+ }
+ }
+
+ if len(selectFields) == 0 {
+ selectFields = []string{"id", "name", "email"} // Default
+ }
+
+ query := fmt.Sprintf("SELECT %s FROM users", strings.Join(selectFields, ", "))
+ // ...
+}
+```
+
+**3. Compression:**
+```go
+import "github.com/go-chi/chi/middleware"
+
+router := chi.NewRouter()
+router.Use(middleware.Compress(5)) // gzip compression level 5
+```
+
+### Async Processing
+
+Move slow operations out of the request cycle:
+
+```go
+// ❌ Synchronous - slow response
+func CreateOrder(w http.ResponseWriter, r *http.Request) {
+ order := createOrder(r)
+
+ sendConfirmationEmail(order) // 500ms
+ updateInventory(order) // 200ms
+ notifyWarehouse(order) // 300ms
+
+ respondJSON(w, http.StatusCreated, order)
+ // Total: 1000ms+
+}
+
+// ✅ Async - fast response
+func CreateOrder(w http.ResponseWriter, r *http.Request) {
+ order := createOrder(r)
+
+ // Queue background tasks
+ queue.Publish("order.created", order)
+
+ respondJSON(w, http.StatusCreated, order)
+ // Total: ~100ms
+}
+
+// Background worker handles slow tasks
+func ProcessOrderCreated(order Order) {
+ sendConfirmationEmail(order)
+ updateInventory(order)
+ notifyWarehouse(order)
+}
+```
+
+---
+
+## Frontend Performance
+
+### Bundle Size Optimization
+
+**1. Code splitting:**
+```javascript
+// ❌ Everything in one bundle
+import { Dashboard } from './Dashboard';
+import { Settings } from './Settings';
+import { Admin } from './Admin';
+
+// ✅ Lazy load routes
+const Dashboard = React.lazy(() => import('./Dashboard'));
+const Settings = React.lazy(() => import('./Settings'));
+const Admin = React.lazy(() => import('./Admin'));
+
+function App() {
+ return (
+ }>
+
+ } />
+ } />
+ } />
+
+
+ );
+}
+```
+
+**2. Tree shaking:**
+```javascript
+// ❌ Import entire library
+import _ from 'lodash';
+const result = _.map(items, 'name');
+
+// ✅ Import only what you need
+import map from 'lodash/map';
+const result = map(items, 'name');
+```
+
+**3. Analyze bundle:**
+```bash
+# Webpack bundle analyzer
+npm install webpack-bundle-analyzer
+npx webpack-bundle-analyzer dist/stats.json
+
+# Vite
+npm run build -- --stats
+```
+
+### Image Optimization
+
+```javascript
+// Use responsive images
+
+
+// Or use Next.js Image component
+import Image from 'next/image';
+
+
+```
+
+### Virtual Scrolling
+
+For long lists (100+ items):
+
+```javascript
+import { FixedSizeList } from 'react-window';
+
+function VirtualList({ items }) {
+ const Row = ({ index, style }) => (
+
+ {items[index].name}
+
+ );
+
+ return (
+
+ {Row}
+
+ );
+}
+```
+
+---
+
+## Monitoring & Profiling
+
+### Application Metrics
+
+```go
+import "github.com/prometheus/client_golang/prometheus"
+
+var (
+ requestDuration = prometheus.NewHistogramVec(
+ prometheus.HistogramOpts{
+ Name: "http_request_duration_seconds",
+ Help: "HTTP request duration",
+ Buckets: []float64{.01, .05, .1, .25, .5, 1, 2.5, 5},
+ },
+ []string{"method", "path", "status"},
+ )
+
+ requestCount = prometheus.NewCounterVec(
+ prometheus.CounterOpts{
+ Name: "http_requests_total",
+ Help: "Total HTTP requests",
+ },
+ []string{"method", "path", "status"},
+ )
+)
+
+func MetricsMiddleware(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ start := time.Now()
+
+ // Wrap response writer to capture status
+ ww := &responseWriter{ResponseWriter: w, status: 200}
+ next.ServeHTTP(ww, r)
+
+ duration := time.Since(start).Seconds()
+ labels := prometheus.Labels{
+ "method": r.Method,
+ "path": r.URL.Path,
+ "status": strconv.Itoa(ww.status),
+ }
+
+ requestDuration.With(labels).Observe(duration)
+ requestCount.With(labels).Inc()
+ })
+}
+```
+
+### Profiling Go Applications
+
+```go
+import _ "net/http/pprof"
+
+func main() {
+ // pprof endpoints available at /debug/pprof/
+ go http.ListenAndServe(":6060", nil)
+
+ // Your application
+ startServer()
+}
+```
+
+```bash
+# CPU profile
+go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
+
+# Memory profile
+go tool pprof http://localhost:6060/debug/pprof/heap
+
+# Goroutine profile
+go tool pprof http://localhost:6060/debug/pprof/goroutine
+```
+
+### Performance Testing
+
+```bash
+# Load testing with hey
+hey -n 10000 -c 100 http://localhost:8080/api/users
+
+# Output:
+# Summary:
+# Total: 5.2341 secs
+# Slowest: 0.5234 secs
+# Fastest: 0.0012 secs
+# Average: 0.0523 secs
+# Requests/sec: 1910.5234
+```
+
+---
+
+## Prompting Claude for Performance
+
+**For database optimization:**
+```
+Optimize this database query for performance:
+[paste query]
+
+Context:
+- Table has 1M+ rows
+- Query runs frequently (100+ times/minute)
+- Current execution time: 500ms
+
+Please:
+1. Analyze the query plan
+2. Suggest appropriate indexes
+3. Rewrite the query if needed
+4. Estimate improvement
+```
+
+**For API performance:**
+```
+This API endpoint is slow (2s average response):
+[paste handler code]
+
+Please:
+1. Identify performance bottlenecks
+2. Suggest N+1 query fixes
+3. Add caching where appropriate
+4. Consider async processing for slow operations
+
+Target: < 200ms response time
+```
+
+---
+
+## Performance Checklist
+
+### Database
+- [ ] Queries have appropriate indexes
+- [ ] No N+1 query patterns
+- [ ] Large result sets are paginated
+- [ ] Connection pooling is configured
+- [ ] Slow queries are logged and monitored
+
+### API
+- [ ] Response times are monitored
+- [ ] Large responses use pagination
+- [ ] Compression is enabled
+- [ ] Slow operations are async
+- [ ] Caching is used for frequent reads
+
+### Frontend
+- [ ] Bundle size is monitored
+- [ ] Routes are code-split
+- [ ] Images are optimized and lazy-loaded
+- [ ] Long lists use virtualization
+- [ ] Core Web Vitals meet targets
+
+---
+
+**Prev:** [Security Practices](./15-security.md) | **Next:** [CI/CD and Deployment](./17-ci-cd.md)
diff --git a/docs/17-ci-cd.md b/docs/17-ci-cd.md
new file mode 100644
index 0000000..559d5bc
--- /dev/null
+++ b/docs/17-ci-cd.md
@@ -0,0 +1,715 @@
+# CI/CD and Deployment
+
+Setting up continuous integration and deployment pipelines for AI-first development.
+
+## CI/CD Philosophy
+
+In AI-first development, automated pipelines are essential:
+- **Every commit is tested** - Catch issues early
+- **Fast feedback** - Know within minutes if something is broken
+- **Consistent quality** - Same checks every time
+- **Safe deployment** - Automated, repeatable process
+
+---
+
+## GitHub Actions Setup
+
+### Basic Workflow Structure
+
+```yaml
+# .github/workflows/ci.yml
+name: CI
+
+on:
+ push:
+ branches: [main, develop]
+ pull_request:
+ branches: [main]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup Go
+ uses: actions/setup-go@v5
+ with:
+ go-version: '1.21'
+
+ - name: Install dependencies
+ run: go mod download
+
+ - name: Run tests
+ run: go test -v ./...
+```
+
+### Complete Go CI Pipeline
+
+```yaml
+# .github/workflows/ci.yml
+name: CI
+
+on:
+ push:
+ branches: [main, develop]
+ pull_request:
+ branches: [main]
+
+env:
+ GO_VERSION: '1.21'
+
+jobs:
+ lint:
+ name: Lint
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup Go
+ uses: actions/setup-go@v5
+ with:
+ go-version: ${{ env.GO_VERSION }}
+
+ - name: Run golangci-lint
+ uses: golangci/golangci-lint-action@v4
+ with:
+ version: latest
+
+ test:
+ name: Test
+ runs-on: ubuntu-latest
+ services:
+ postgres:
+ image: postgres:16
+ env:
+ POSTGRES_USER: test
+ POSTGRES_PASSWORD: test
+ POSTGRES_DB: testdb
+ ports:
+ - 5432:5432
+ options: >-
+ --health-cmd pg_isready
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup Go
+ uses: actions/setup-go@v5
+ with:
+ go-version: ${{ env.GO_VERSION }}
+
+ - name: Run tests with coverage
+ env:
+ DATABASE_URL: postgres://test:test@localhost:5432/testdb?sslmode=disable
+ run: |
+ go test -race -coverprofile=coverage.out -covermode=atomic ./...
+
+ - name: Check coverage threshold
+ run: |
+ coverage=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
+ echo "Coverage: $coverage%"
+ if (( $(echo "$coverage < 70" | bc -l) )); then
+ echo "Coverage $coverage% is below 70% threshold"
+ exit 1
+ fi
+
+ - name: Upload coverage
+ uses: codecov/codecov-action@v4
+ with:
+ files: coverage.out
+
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ needs: [lint, test]
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup Go
+ uses: actions/setup-go@v5
+ with:
+ go-version: ${{ env.GO_VERSION }}
+
+ - name: Build
+ run: go build -o bin/server ./cmd/server
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: server
+ path: bin/server
+
+ security:
+ name: Security Scan
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Run Gosec
+ uses: securego/gosec@master
+ with:
+ args: ./...
+
+ - name: Run Trivy
+ uses: aquasecurity/trivy-action@master
+ with:
+ scan-type: 'fs'
+ scan-ref: '.'
+```
+
+### Node.js/TypeScript CI Pipeline
+
+```yaml
+# .github/workflows/ci.yml
+name: CI
+
+on:
+ push:
+ branches: [main, develop]
+ pull_request:
+ branches: [main]
+
+jobs:
+ lint-and-test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Lint
+ run: npm run lint
+
+ - name: Type check
+ run: npm run type-check
+
+ - name: Run tests
+ run: npm test -- --coverage
+
+ - name: Check coverage
+ run: |
+ coverage=$(cat coverage/coverage-summary.json | jq '.total.lines.pct')
+ echo "Coverage: $coverage%"
+ if (( $(echo "$coverage < 70" | bc -l) )); then
+ echo "Coverage below threshold"
+ exit 1
+ fi
+
+ e2e:
+ runs-on: ubuntu-latest
+ needs: lint-and-test
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Install Playwright
+ run: npx playwright install --with-deps
+
+ - name: Run E2E tests
+ run: npm run test:e2e
+
+ - name: Upload test results
+ if: failure()
+ uses: actions/upload-artifact@v4
+ with:
+ name: playwright-report
+ path: playwright-report/
+
+ build:
+ runs-on: ubuntu-latest
+ needs: [lint-and-test, e2e]
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Build
+ run: npm run build
+
+ - name: Upload build
+ uses: actions/upload-artifact@v4
+ with:
+ name: build
+ path: dist/
+```
+
+---
+
+## Pre-Commit Hooks
+
+Run checks locally before pushing.
+
+### Husky Setup (Node.js)
+
+```bash
+# Install
+npm install husky lint-staged --save-dev
+npx husky init
+```
+
+```json
+// package.json
+{
+ "scripts": {
+ "prepare": "husky"
+ },
+ "lint-staged": {
+ "*.{js,ts,tsx}": [
+ "eslint --fix",
+ "prettier --write"
+ ],
+ "*.{json,md}": [
+ "prettier --write"
+ ]
+ }
+}
+```
+
+```bash
+# .husky/pre-commit
+npm run lint-staged
+npm test
+```
+
+### Pre-commit Framework (Python/Multi-language)
+
+```yaml
+# .pre-commit-config.yaml
+repos:
+ # Go
+ - repo: local
+ hooks:
+ - id: go-fmt
+ name: Go Format
+ entry: go fmt ./...
+ language: system
+ types: [go]
+ pass_filenames: false
+
+ - id: go-vet
+ name: Go Vet
+ entry: go vet ./...
+ language: system
+ types: [go]
+ pass_filenames: false
+
+ - id: go-test
+ name: Go Test
+ entry: go test ./...
+ language: system
+ types: [go]
+ pass_filenames: false
+
+ # General
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v4.5.0
+ hooks:
+ - id: trailing-whitespace
+ - id: end-of-file-fixer
+ - id: check-yaml
+ - id: check-json
+ - id: check-merge-conflict
+
+ # Secrets
+ - repo: https://github.com/Yelp/detect-secrets
+ rev: v1.4.0
+ hooks:
+ - id: detect-secrets
+```
+
+```bash
+# Install
+pip install pre-commit
+pre-commit install
+
+# Run manually
+pre-commit run --all-files
+```
+
+---
+
+## Testing in CI
+
+### Running Tests with Services
+
+```yaml
+# PostgreSQL service
+services:
+ postgres:
+ image: postgres:16
+ env:
+ POSTGRES_PASSWORD: test
+ ports:
+ - 5432:5432
+ options: >-
+ --health-cmd pg_isready
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
+
+# Redis service
+ redis:
+ image: redis:7
+ ports:
+ - 6379:6379
+ options: >-
+ --health-cmd "redis-cli ping"
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
+```
+
+### E2E Tests with Cypress
+
+```yaml
+e2e:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Start application
+ run: npm run start &
+ env:
+ DATABASE_URL: ${{ secrets.TEST_DATABASE_URL }}
+
+ - name: Wait for server
+ run: npx wait-on http://localhost:3000
+
+ - name: Run Cypress
+ uses: cypress-io/github-action@v6
+ with:
+ wait-on: http://localhost:3000
+
+ - name: Upload screenshots on failure
+ if: failure()
+ uses: actions/upload-artifact@v4
+ with:
+ name: cypress-screenshots
+ path: cypress/screenshots
+```
+
+### Test Containers
+
+```go
+// For integration tests with real databases
+import (
+ "github.com/testcontainers/testcontainers-go"
+ "github.com/testcontainers/testcontainers-go/modules/postgres"
+)
+
+func setupTestDB(t *testing.T) *sql.DB {
+ ctx := context.Background()
+
+ container, err := postgres.RunContainer(ctx,
+ testcontainers.WithImage("postgres:16"),
+ postgres.WithDatabase("testdb"),
+ postgres.WithUsername("test"),
+ postgres.WithPassword("test"),
+ )
+ require.NoError(t, err)
+
+ t.Cleanup(func() { container.Terminate(ctx) })
+
+ connStr, _ := container.ConnectionString(ctx, "sslmode=disable")
+ db, _ := sql.Open("postgres", connStr)
+
+ return db
+}
+```
+
+---
+
+## Deployment Pipelines
+
+### Deploy to Staging on Push
+
+```yaml
+# .github/workflows/deploy-staging.yml
+name: Deploy Staging
+
+on:
+ push:
+ branches: [develop]
+
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ environment: staging
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Build Docker image
+ run: |
+ docker build -t myapp:${{ github.sha }} .
+
+ - name: Push to registry
+ run: |
+ echo ${{ secrets.REGISTRY_PASSWORD }} | docker login -u ${{ secrets.REGISTRY_USER }} --password-stdin
+ docker tag myapp:${{ github.sha }} registry.example.com/myapp:staging
+ docker push registry.example.com/myapp:staging
+
+ - name: Deploy to staging
+ run: |
+ kubectl set image deployment/myapp myapp=registry.example.com/myapp:staging
+ env:
+ KUBECONFIG: ${{ secrets.STAGING_KUBECONFIG }}
+```
+
+### Deploy to Production on Release
+
+```yaml
+# .github/workflows/deploy-production.yml
+name: Deploy Production
+
+on:
+ release:
+ types: [published]
+
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ environment: production
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Build Docker image
+ run: |
+ docker build -t myapp:${{ github.event.release.tag_name }} .
+
+ - name: Push to registry
+ run: |
+ docker tag myapp:${{ github.event.release.tag_name }} registry.example.com/myapp:${{ github.event.release.tag_name }}
+ docker tag myapp:${{ github.event.release.tag_name }} registry.example.com/myapp:latest
+ docker push registry.example.com/myapp:${{ github.event.release.tag_name }}
+ docker push registry.example.com/myapp:latest
+
+ - name: Deploy to production
+ run: |
+ kubectl set image deployment/myapp myapp=registry.example.com/myapp:${{ github.event.release.tag_name }}
+ env:
+ KUBECONFIG: ${{ secrets.PROD_KUBECONFIG }}
+
+ - name: Verify deployment
+ run: |
+ kubectl rollout status deployment/myapp --timeout=5m
+```
+
+### Database Migrations in CI
+
+```yaml
+migrate:
+ runs-on: ubuntu-latest
+ needs: [test]
+ if: github.ref == 'refs/heads/main'
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Run migrations
+ run: |
+ migrate -path ./migrations -database ${{ secrets.DATABASE_URL }} up
+ env:
+ DATABASE_URL: ${{ secrets.PROD_DATABASE_URL }}
+```
+
+---
+
+## Rollback Strategies
+
+### Kubernetes Rollback
+
+```yaml
+# In deployment workflow
+- name: Deploy
+ id: deploy
+ run: |
+ kubectl set image deployment/myapp myapp=$IMAGE
+ kubectl rollout status deployment/myapp --timeout=5m
+ continue-on-error: true
+
+- name: Rollback on failure
+ if: steps.deploy.outcome == 'failure'
+ run: |
+ kubectl rollout undo deployment/myapp
+ echo "::error::Deployment failed, rolled back to previous version"
+ exit 1
+```
+
+### Blue-Green Deployment
+
+```yaml
+# Deploy to green environment
+- name: Deploy to green
+ run: |
+ kubectl apply -f k8s/deployment-green.yaml
+ kubectl rollout status deployment/myapp-green
+
+# Health check
+- name: Health check green
+ run: |
+ curl -f http://myapp-green.internal/health
+
+# Switch traffic
+- name: Switch traffic to green
+ run: |
+ kubectl patch service myapp -p '{"spec":{"selector":{"version":"green"}}}'
+
+# Cleanup old deployment
+- name: Remove blue
+ run: |
+ kubectl delete deployment myapp-blue
+```
+
+---
+
+## Environment Management
+
+### GitHub Environments
+
+```yaml
+jobs:
+ deploy-staging:
+ environment: staging # Requires approval if configured
+ env:
+ API_URL: ${{ vars.API_URL }} # Environment-specific variable
+ API_KEY: ${{ secrets.API_KEY }} # Environment-specific secret
+```
+
+### Environment-Specific Configs
+
+```yaml
+# config/staging.yaml
+database:
+ host: staging-db.example.com
+ pool_size: 5
+
+# config/production.yaml
+database:
+ host: prod-db.example.com
+ pool_size: 25
+```
+
+```go
+func LoadConfig() *Config {
+ env := os.Getenv("ENV") // staging, production
+ configFile := fmt.Sprintf("config/%s.yaml", env)
+ // Load config...
+}
+```
+
+---
+
+## Example Complete Workflows
+
+### Monorepo with Multiple Services
+
+```yaml
+name: CI
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+jobs:
+ detect-changes:
+ runs-on: ubuntu-latest
+ outputs:
+ api: ${{ steps.filter.outputs.api }}
+ web: ${{ steps.filter.outputs.web }}
+ steps:
+ - uses: actions/checkout@v4
+ - uses: dorny/paths-filter@v3
+ id: filter
+ with:
+ filters: |
+ api:
+ - 'services/api/**'
+ web:
+ - 'services/web/**'
+
+ test-api:
+ needs: detect-changes
+ if: needs.detect-changes.outputs.api == 'true'
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: services/api
+ steps:
+ - uses: actions/checkout@v4
+ - run: go test ./...
+
+ test-web:
+ needs: detect-changes
+ if: needs.detect-changes.outputs.web == 'true'
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: services/web
+ steps:
+ - uses: actions/checkout@v4
+ - run: npm ci && npm test
+```
+
+---
+
+## CI/CD Checklist
+
+### Pre-Merge Checks
+- [ ] All tests pass (unit + E2E)
+- [ ] Linting passes
+- [ ] Type checking passes
+- [ ] Coverage meets threshold
+- [ ] Security scan clean
+- [ ] Build succeeds
+
+### Deployment Checks
+- [ ] Migrations run successfully
+- [ ] Health checks pass
+- [ ] Smoke tests pass
+- [ ] Monitoring alerts clear
+- [ ] Rollback tested
+
+### Secrets Management
+- [ ] Secrets in GitHub Secrets
+- [ ] No secrets in code
+- [ ] Secrets rotated regularly
+- [ ] Minimal access scope
+
+---
+
+**Prev:** [Performance Optimization](./16-performance.md) | **Next:** [Advanced Topics](./18-advanced-topics.md)
diff --git a/docs/18-advanced-topics.md b/docs/18-advanced-topics.md
new file mode 100644
index 0000000..be06473
--- /dev/null
+++ b/docs/18-advanced-topics.md
@@ -0,0 +1,571 @@
+# Advanced Topics
+
+Advanced techniques for experienced Claude Code users.
+
+## MCP (Model Context Protocol) Servers
+
+MCP servers extend Claude Code's capabilities with custom tools.
+
+### What Are MCP Servers?
+
+MCP servers provide:
+- Custom tools for specific domains (databases, APIs, services)
+- Access to local resources (files, processes)
+- Integration with external services
+- Specialized functionality beyond built-in tools
+
+### Common MCP Servers
+
+| Server | Purpose | Use Case |
+|--------|---------|----------|
+| filesystem | File operations | Read/write files outside workspace |
+| postgres | Database queries | Direct database access |
+| github | GitHub API | PR management, issues |
+| slack | Messaging | Team notifications |
+| puppeteer | Browser automation | Web scraping, testing |
+
+### Setting Up MCP Servers
+
+**Configuration file:**
+```json
+// ~/.claude/mcp_servers.json
+{
+ "servers": {
+ "postgres": {
+ "command": "npx",
+ "args": ["-y", "@modelcontextprotocol/server-postgres"],
+ "env": {
+ "POSTGRES_URL": "postgres://user:pass@localhost:5432/db"
+ }
+ },
+ "filesystem": {
+ "command": "npx",
+ "args": ["-y", "@modelcontextprotocol/server-filesystem"],
+ "env": {
+ "ALLOWED_PATHS": "/home/user/projects,/tmp"
+ }
+ }
+ }
+}
+```
+
+### Creating Custom MCP Servers
+
+**Basic structure (TypeScript):**
+```typescript
+import { Server } from "@modelcontextprotocol/sdk/server/index.js";
+import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
+
+const server = new Server({
+ name: "my-custom-server",
+ version: "1.0.0"
+}, {
+ capabilities: {
+ tools: {}
+ }
+});
+
+// Define a tool
+server.setRequestHandler("tools/list", async () => ({
+ tools: [{
+ name: "my_tool",
+ description: "Does something useful",
+ inputSchema: {
+ type: "object",
+ properties: {
+ param: { type: "string", description: "Input parameter" }
+ },
+ required: ["param"]
+ }
+ }]
+}));
+
+// Handle tool calls
+server.setRequestHandler("tools/call", async (request) => {
+ if (request.params.name === "my_tool") {
+ const result = await doSomething(request.params.arguments.param);
+ return { content: [{ type: "text", text: result }] };
+ }
+});
+
+// Start server
+const transport = new StdioServerTransport();
+await server.connect(transport);
+```
+
+**Using your custom server:**
+```
+// Tell Claude to use your MCP tool
+Use the my_tool to process "input data"
+```
+
+---
+
+## Multi-Repository Projects
+
+Managing multiple repositories with Claude Code.
+
+### Workspace Setup
+
+**VS Code multi-root workspace:**
+```json
+// project.code-workspace
+{
+ "folders": [
+ { "path": "service-api" },
+ { "path": "service-web" },
+ { "path": "service-worker" },
+ { "path": "infrastructure" }
+ ],
+ "settings": {
+ "files.exclude": {
+ "**/node_modules": true
+ }
+ }
+}
+```
+
+### Cross-Repo Context
+
+**Share context with Claude:**
+```
+I'm working on a microservices project with multiple repos:
+
+1. service-api/ - Go REST API
+ - CLAUDE.md defines API conventions
+ - Endpoints in internal/handlers/
+
+2. service-web/ - React frontend
+ - CLAUDE.md defines component patterns
+ - API client in src/api/
+
+3. infrastructure/ - Docker, Kubernetes
+ - CLAUDE.md defines deployment patterns
+ - Shared types in proto/
+
+When making changes, ensure consistency across repos.
+Current task: Add a new "orders" endpoint...
+```
+
+### Shared Types Between Services
+
+**Protocol Buffers for shared types:**
+```protobuf
+// proto/order.proto
+syntax = "proto3";
+
+message Order {
+ int64 id = 1;
+ int64 user_id = 2;
+ repeated OrderItem items = 3;
+ string status = 4;
+ double total = 5;
+}
+
+message OrderItem {
+ int64 product_id = 1;
+ int32 quantity = 2;
+ double price = 3;
+}
+```
+
+**Generate for each language:**
+```bash
+# Go
+protoc --go_out=service-api/pkg/proto order.proto
+
+# TypeScript
+protoc --ts_out=service-web/src/proto order.proto
+```
+
+### Coordinated Changes
+
+**Multi-repo PR workflow:**
+```
+Making a change that affects multiple repos:
+
+1. API changes (service-api)
+ - New endpoint: POST /api/orders
+ - PR: api-repo#123
+
+2. Frontend changes (service-web)
+ - New OrderForm component
+ - API client update
+ - PR: web-repo#456
+
+3. Infrastructure changes (infrastructure)
+ - Update API deployment
+ - PR: infra-repo#789
+
+Merge order: API → Infrastructure → Frontend
+```
+
+---
+
+## Advanced CLAUDE.md Patterns
+
+### Context Optimization
+
+**Structured sections for large projects:**
+```markdown
+# CLAUDE.md
+
+## Quick Reference
+[Most frequently needed info - always read this]
+
+## Architecture Overview
+[High-level system design]
+
+## Current Sprint Context
+[What we're working on now - update weekly]
+
+## Deep Dive Sections
+### Database Schema
+[Link to separate file: docs/database.md]
+
+### API Reference
+[Link to separate file: docs/api.md]
+
+## Historical Decisions
+[Link to ADR folder: docs/adr/]
+```
+
+### Project-Specific Commands
+
+**Define common workflows:**
+```markdown
+## Common Prompts
+
+### Adding a New API Endpoint
+```
+Add a new endpoint for [resource]:
+1. Create migration in migrations/
+2. Add repository methods in internal/repository/
+3. Create handler in internal/handlers/
+4. Add routes in cmd/server/routes.go
+5. Write E2E tests in tests/e2e/
+6. Update API documentation
+
+Follow existing patterns from the users endpoint.
+```
+
+### Debugging a Test Failure
+```
+Debug the failing test:
+1. Read the test file
+2. Identify the assertion that fails
+3. Check the handler/repository being tested
+4. Add debug logging if needed
+5. Fix the issue
+6. Verify all tests pass
+```
+```
+
+### Dynamic Context
+
+**Include current state:**
+```markdown
+## Current Development State
+
+**Last Updated:** 2025-01-15
+
+### In Progress
+- Feature: Order management (branch: feature/orders)
+- Blocked: Waiting for payment gateway access
+
+### Recently Completed
+- User authentication (merged: 2025-01-10)
+- Product catalog (merged: 2025-01-12)
+
+### Known Issues
+- Performance issue on /api/products with large datasets (#123)
+- Flaky test in auth_test.go (#124)
+```
+
+---
+
+## Complex Refactoring
+
+### Large-Scale Codebase Changes
+
+**Incremental migration strategy:**
+```
+We need to migrate from REST to GraphQL. Plan:
+
+Phase 1: Add GraphQL alongside REST
+- Set up GraphQL server
+- Create schemas for existing models
+- Add resolvers that call existing services
+- Both REST and GraphQL work
+
+Phase 2: Migrate high-traffic endpoints
+- Orders API → GraphQL
+- Products API → GraphQL
+- Update frontend to use GraphQL for these
+
+Phase 3: Migrate remaining endpoints
+- Users API → GraphQL
+- Admin API → GraphQL
+
+Phase 4: Deprecate REST
+- Add deprecation warnings
+- Set sunset date
+- Remove REST endpoints
+
+Each phase is a separate PR. Tests must pass at each phase.
+```
+
+### Maintaining Tests During Refactoring
+
+```
+Refactoring the repository layer:
+
+Rules:
+1. Tests must pass before AND after each change
+2. Run tests after every file change
+3. If tests fail, fix before continuing
+4. Don't change tests and implementation in same commit
+
+Process:
+1. Create new implementation alongside old
+2. Add tests for new implementation
+3. Migrate callers one at a time
+4. Remove old implementation when unused
+5. Clean up
+
+Current step: [specify which step]
+```
+
+### Safe Renaming
+
+```
+Rename UserService to AccountService across codebase:
+
+Steps:
+1. Create AccountService as alias to UserService
+2. Update all imports to use AccountService
+3. Run tests - must pass
+4. Update internal implementation
+5. Remove UserService alias
+6. Update documentation
+
+Do NOT:
+- Rename and update usages in same commit
+- Skip test runs between steps
+- Update tests before implementation
+```
+
+---
+
+## Working with Legacy Code
+
+### Understanding Undocumented Code
+
+```
+I need to understand this legacy code:
+
+File: src/legacy/processor.go
+
+Please:
+1. Read the file and all related files it imports
+2. Trace the data flow from input to output
+3. Identify side effects (database, external APIs)
+4. Document assumptions and magic numbers
+5. Create a summary of what this code does
+
+Don't modify anything yet - just document.
+```
+
+### Adding Tests to Legacy Code
+
+```
+Add tests to legacy code without modifying it:
+
+File: src/legacy/calculator.go
+
+Approach:
+1. Read and understand the code
+2. Identify public functions to test
+3. Create test file: calculator_test.go
+4. Write tests for current behavior (not ideal behavior)
+5. Tests should pass with existing code
+6. Document any bugs found (don't fix yet)
+
+Goal: Establish a safety net before refactoring.
+```
+
+### Incremental Modernization
+
+```
+Modernize legacy authentication module:
+
+Current state:
+- Uses deprecated crypto library
+- No tests
+- Mixed concerns (auth + session + user)
+
+Target state:
+- Modern crypto (bcrypt)
+- 80% test coverage
+- Separated concerns
+
+Plan:
+Phase 1: Add tests for current behavior
+Phase 2: Extract session management
+Phase 3: Extract user management
+Phase 4: Update crypto library
+Phase 5: Add integration tests
+
+We're on Phase 1. Add tests without changing code.
+```
+
+---
+
+## Context Window Optimization
+
+### Managing Large Codebases
+
+**Strategies for staying within context limits:**
+
+1. **Reference, don't repeat:**
+```
+See the pattern in src/handlers/users.go lines 50-80.
+Apply the same pattern to the new orders handler.
+```
+
+2. **Summarize large files:**
+```
+The database schema has 30 tables. Relevant ones for this task:
+- users (id, email, password_hash)
+- orders (id, user_id, total, status)
+- order_items (id, order_id, product_id, quantity)
+```
+
+3. **Focus on diff:**
+```
+Only these files need changes:
+1. src/handlers/orders.go - Add CreateOrder handler
+2. src/repository/orders.go - Add Create method
+3. tests/orders_test.go - Add tests
+
+Other files are stable - don't read unless needed.
+```
+
+### Efficient File Reading
+
+```
+Read only what's needed:
+
+For this task (adding order validation):
+1. Read: src/handlers/orders.go (need to see current handler)
+2. Read: src/validation/rules.go (need existing patterns)
+3. Skip: src/repository/* (not changing data layer)
+4. Skip: tests/* (will update after implementation)
+
+Start with handlers/orders.go
+```
+
+---
+
+## Extending Claude Code
+
+### Custom Slash Commands
+
+Create project-specific commands:
+
+```markdown
+
+# New Endpoint Command
+
+Create a new API endpoint with:
+- Handler in internal/handlers/
+- Repository method in internal/repository/
+- Migration if needed
+- E2E tests in tests/e2e/
+- Unit tests for business logic
+
+Arguments:
+- $RESOURCE: The resource name (e.g., "orders")
+- $METHODS: HTTP methods to support (e.g., "GET,POST,PUT,DELETE")
+
+Follow patterns from existing endpoints.
+Start with the database migration.
+```
+
+**Usage:**
+```
+/project:new-endpoint orders GET,POST,PUT,DELETE
+```
+
+### Automation Scripts
+
+**Git hooks integration:**
+```bash
+#!/bin/bash
+# .git/hooks/prepare-commit-msg
+
+# Auto-generate commit message suggestion
+if [ -z "$2" ]; then
+ # Get changed files
+ FILES=$(git diff --cached --name-only)
+
+ # Create prompt for Claude
+ echo "Based on these changed files, suggest a commit message:" > /tmp/commit-prompt
+ echo "$FILES" >> /tmp/commit-prompt
+ git diff --cached >> /tmp/commit-prompt
+
+ # Could integrate with Claude API here
+ # For now, just remind the developer
+ echo "# Changed files:" >> "$1"
+ echo "$FILES" | sed 's/^/# /' >> "$1"
+fi
+```
+
+### Integration with Other Tools
+
+**VS Code tasks:**
+```json
+// .vscode/tasks.json
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "Run Tests for Current File",
+ "type": "shell",
+ "command": "go test -v ./${relativeFileDirname}/...",
+ "group": "test",
+ "presentation": {
+ "reveal": "always"
+ }
+ },
+ {
+ "label": "Generate Mocks",
+ "type": "shell",
+ "command": "mockgen -source=${relativeFile} -destination=mocks/${fileBasenameNoExtension}_mock.go",
+ "group": "build"
+ }
+ ]
+}
+```
+
+---
+
+## Summary
+
+**Key Advanced Techniques:**
+- MCP servers extend Claude's capabilities
+- Multi-repo projects need coordinated context
+- CLAUDE.md can include dynamic state
+- Refactoring requires incremental, tested steps
+- Legacy code needs tests before changes
+- Optimize context usage for large codebases
+
+**When to Use Advanced Techniques:**
+- Project complexity exceeds basic patterns
+- Standard approaches don't fit your needs
+- Performance or scale requires optimization
+- Legacy systems need careful handling
+
+---
+
+**Prev:** [CI/CD and Deployment](./17-ci-cd.md) | **Next:** [Troubleshooting](./19-troubleshooting.md)
diff --git a/examples/my-api-project/CLAUDE.md b/examples/my-api-project/CLAUDE.md
new file mode 100644
index 0000000..e013fbf
--- /dev/null
+++ b/examples/my-api-project/CLAUDE.md
@@ -0,0 +1,277 @@
+# CLAUDE.md - my-api-project
+
+## Overview
+
+Go REST API with JWT authentication and PostgreSQL database. This is a reference implementation for the Claude Code workshop.
+
+## Architecture
+
+```
+┌─────────────┐ ┌─────────────┐ ┌─────────────┐
+│ Client │────▶│ API │────▶│ Database │
+│ │ │ (Go) │ │ (PostgreSQL)│
+└─────────────┘ └─────────────┘ └─────────────┘
+ │
+ ┌──────┴──────┐
+ │ │
+ ┌─────▼─────┐ ┌─────▼─────┐
+ │ Handlers │ │ Middleware│
+ └─────┬─────┘ └───────────┘
+ │
+ ┌─────▼─────┐
+ │Repository │
+ └─────┬─────┘
+ │
+ ┌─────▼─────┐
+ │ Models │
+ └───────────┘
+```
+
+## Tech Stack
+
+- **Language:** Go 1.21+
+- **Framework:** gorilla/mux (routing)
+- **Database:** PostgreSQL 16
+- **Authentication:** JWT (golang-jwt/jwt)
+- **Password Hashing:** bcrypt
+- **Container:** Docker + Docker Compose
+
+## Project Structure
+
+```
+my-api-project/
+├── cmd/
+│ └── server/
+│ └── main.go # Application entry point
+├── internal/
+│ ├── handlers/ # HTTP handlers
+│ │ ├── auth.go # Auth handlers (register, login, refresh)
+│ │ └── user.go # User handlers
+│ ├── middleware/ # HTTP middleware
+│ │ └── auth.go # JWT authentication middleware
+│ ├── models/ # Data models
+│ │ └── user.go # User model
+│ └── repository/ # Database operations
+│ └── user.go # User repository
+├── migrations/ # Database migrations
+│ ├── 001_create_users.up.sql
+│ └── 001_create_users.down.sql
+├── tests/ # Test files
+│ ├── e2e/ # E2E tests
+│ └── unit/ # Unit tests
+├── docker-compose.yml
+├── Dockerfile
+├── go.mod
+├── go.sum
+└── CLAUDE.md
+```
+
+## API Endpoints
+
+### Authentication
+
+| Method | Endpoint | Description | Auth Required |
+|--------|----------|-------------|---------------|
+| POST | `/api/auth/register` | Register new user | No |
+| POST | `/api/auth/login` | Login, returns JWT | No |
+| POST | `/api/auth/refresh` | Refresh JWT token | Yes |
+| POST | `/api/auth/logout` | Invalidate token | Yes |
+
+### Users
+
+| Method | Endpoint | Description | Auth Required |
+|--------|----------|-------------|---------------|
+| GET | `/api/users/me` | Get current user | Yes |
+| PUT | `/api/users/me` | Update current user | Yes |
+
+### Request/Response Format
+
+**Register Request:**
+```json
+{
+ "email": "user@example.com",
+ "password": "securepassword123"
+}
+```
+
+**Login Response:**
+```json
+{
+ "token": "eyJhbGciOiJIUzI1NiIs...",
+ "expires_at": "2025-01-16T10:00:00Z"
+}
+```
+
+**Error Response:**
+```json
+{
+ "error": "invalid credentials",
+ "code": "AUTH_INVALID_CREDENTIALS"
+}
+```
+
+## Git Workflow
+
+### Branch Naming
+```
+feature/ - New features (feature/user-auth)
+fix/ - Bug fixes (fix/login-validation)
+refactor/ - Code refactoring (refactor/repository-layer)
+test/ - Test additions (test/auth-e2e)
+docs/ - Documentation (docs/api-readme)
+```
+
+### Commit Messages
+
+Use conventional commits:
+```
+feat(auth): add JWT token refresh endpoint
+fix(user): validate email format on registration
+test(auth): add E2E tests for login flow
+docs(api): update endpoint documentation
+```
+
+### Pre-Commit Checklist
+
+Before every commit, ensure:
+- [ ] `go fmt ./...` - Code is formatted
+- [ ] `go vet ./...` - No suspicious constructs
+- [ ] `go test ./...` - All tests pass
+- [ ] `go build ./...` - Code compiles
+- [ ] Coverage meets minimum threshold (70%)
+
+## Testing Strategy
+
+### E2E Tests (Mandatory)
+Test complete user journeys:
+- Registration flow
+- Login flow
+- Protected endpoint access
+- Token refresh
+- Error scenarios
+
+### Unit Tests (Mandatory)
+Test business logic:
+- Password hashing/verification
+- JWT generation/validation
+- Email validation
+- Repository methods (with mocks)
+
+### Coverage Targets
+- Overall: 70% minimum
+- Handlers: 80% minimum
+- Repository: 70% minimum
+
+### Running Tests
+```bash
+# All tests
+go test ./...
+
+# With coverage
+go test -cover ./...
+
+# E2E tests only
+go test ./tests/e2e/...
+
+# Unit tests only
+go test ./tests/unit/...
+```
+
+## Environment Variables
+
+| Variable | Description | Required | Default |
+|----------|-------------|----------|---------|
+| `DATABASE_URL` | PostgreSQL connection string | Yes | - |
+| `JWT_SECRET` | Secret for JWT signing | Yes | - |
+| `JWT_EXPIRY` | Token expiry duration | No | 24h |
+| `PORT` | Server port | No | 8080 |
+| `ENV` | Environment (dev/prod) | No | dev |
+
+### Example .env
+```bash
+DATABASE_URL=postgres://user:pass@localhost:5432/myapi?sslmode=disable
+JWT_SECRET=your-256-bit-secret-key-here
+JWT_EXPIRY=24h
+PORT=8080
+ENV=dev
+```
+
+## Common Commands
+
+```bash
+# Development
+go run cmd/server/main.go # Start server
+go build -o bin/server ./cmd/server # Build binary
+
+# Database
+psql -d myapi -f migrations/001_create_users.up.sql # Run migration
+psql -d myapi -f migrations/001_create_users.down.sql # Rollback
+
+# Docker
+docker-compose up -d # Start all services
+docker-compose down # Stop all services
+docker-compose logs -f api # View API logs
+
+# Testing
+go test ./... -v # Verbose test output
+go test -coverprofile=coverage.out ./... # Generate coverage
+go tool cover -html=coverage.out # View coverage report
+```
+
+## Code Patterns
+
+### Handler Pattern
+```go
+func (h *AuthHandler) Register(w http.ResponseWriter, r *http.Request) {
+ var req RegisterRequest
+ if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+ respondError(w, http.StatusBadRequest, "invalid request body")
+ return
+ }
+
+ // Validate
+ if err := validateEmail(req.Email); err != nil {
+ respondError(w, http.StatusBadRequest, err.Error())
+ return
+ }
+
+ // Process
+ user, err := h.userRepo.Create(r.Context(), req.Email, req.Password)
+ if err != nil {
+ respondError(w, http.StatusInternalServerError, "failed to create user")
+ return
+ }
+
+ respondJSON(w, http.StatusCreated, user)
+}
+```
+
+### Repository Pattern
+```go
+type UserRepository interface {
+ Create(ctx context.Context, email, password string) (*User, error)
+ GetByEmail(ctx context.Context, email string) (*User, error)
+ GetByID(ctx context.Context, id int) (*User, error)
+ Update(ctx context.Context, user *User) error
+}
+```
+
+## Security Considerations
+
+- Passwords hashed with bcrypt (cost factor 12)
+- JWT tokens expire after 24 hours
+- Rate limiting on auth endpoints (10 requests/minute)
+- Input validation on all endpoints
+- SQL injection prevented via parameterized queries
+- CORS configured for allowed origins only
+
+## Development Workflow
+
+1. **Read the spec** - Understand what you're building
+2. **Write migration** - Database schema first
+3. **Implement repository** - Data access layer
+4. **Build handlers** - HTTP endpoints
+5. **Add middleware** - Authentication, logging
+6. **Write tests** - E2E then unit
+7. **Run pre-commit checks** - Format, lint, test
+8. **Commit and push** - Small, focused commits
diff --git a/examples/my-api-project/README.md b/examples/my-api-project/README.md
new file mode 100644
index 0000000..b19877e
--- /dev/null
+++ b/examples/my-api-project/README.md
@@ -0,0 +1,74 @@
+# my-api-project Reference Example
+
+This is a reference implementation for the Claude Code workshop exercises (Pages 9-19).
+
+## Purpose
+
+This example shows what a completed Go API project looks like after following the workshop exercises. Use it to:
+
+- **Compare** your generated CLAUDE.md against a production-ready version
+- **Reference** proper migration structure with up/down files
+- **Understand** trigger patterns for automatic timestamp updates
+
+> **Important:** This is a reference for comparison, not copy-paste. Complete the exercises yourself first, then compare your output.
+
+## What's Included
+
+```
+my-api-project/
+├── README.md # This file
+├── CLAUDE.md # Complete project configuration
+└── migrations/
+ ├── 001_create_users.up.sql # User table creation
+ └── 001_create_users.down.sql # Rollback migration
+```
+
+## How to Use
+
+### During Workshop
+
+1. Complete each exercise independently
+2. After finishing, compare your output to these files
+3. Note differences - different approaches are OK if they work!
+
+### After Workshop
+
+- Use as a template for starting new Go API projects
+- Reference the patterns used (indexes, triggers, conventions)
+- Adapt the CLAUDE.md structure for your own projects
+
+## Key Patterns Demonstrated
+
+### CLAUDE.md
+
+- Project overview and architecture
+- Tech stack with specific versions (Go 1.21+, PostgreSQL 16)
+- Git workflow conventions matching workshop teachings
+- Testing strategy with coverage targets
+- Environment configuration
+- Pre-commit checklist
+
+### Database Migration
+
+- Serial primary key pattern
+- Email uniqueness constraint with index
+- Automatic `updated_at` trigger
+- Proper up/down migration pair for rollback support
+- Index on frequently-queried columns
+
+## Workshop Exercise Reference
+
+| Workshop Page | This Example |
+|---------------|--------------|
+| Page 9: Create CLAUDE.md | See `CLAUDE.md` |
+| Page 14-15: Database Schema | See `migrations/001_create_users.up.sql` |
+
+## Note
+
+This is a minimal example focused on the workshop exercises. For a comprehensive CLAUDE.md template covering all aspects of a production project, see [`../claude-md-template.md`](../claude-md-template.md).
+
+## Related Documentation
+
+- [Documentation Organization](../../docs/12-documentation-organization.md) - How to structure project documentation
+- [Git Workflow](../../docs/11-git-workflow.md) - Branch and commit conventions
+- [Testing Strategy](../../docs/06-testing-strategy.md) - E2E and unit testing approach
diff --git a/examples/my-api-project/migrations/001_create_users.down.sql b/examples/my-api-project/migrations/001_create_users.down.sql
new file mode 100644
index 0000000..14ca04f
--- /dev/null
+++ b/examples/my-api-project/migrations/001_create_users.down.sql
@@ -0,0 +1,15 @@
+-- Migration: Rollback users table
+-- Version: 001
+-- Description: Remove user table and related objects
+
+-- Drop trigger first (depends on function)
+DROP TRIGGER IF EXISTS update_users_updated_at ON users;
+
+-- Drop function
+DROP FUNCTION IF EXISTS update_updated_at_column();
+
+-- Drop index
+DROP INDEX IF EXISTS idx_users_email;
+
+-- Drop table
+DROP TABLE IF EXISTS users;
diff --git a/examples/my-api-project/migrations/001_create_users.up.sql b/examples/my-api-project/migrations/001_create_users.up.sql
new file mode 100644
index 0000000..4c1bd67
--- /dev/null
+++ b/examples/my-api-project/migrations/001_create_users.up.sql
@@ -0,0 +1,35 @@
+-- Migration: Create users table
+-- Version: 001
+-- Description: Initial user table for authentication
+
+-- Create users table
+CREATE TABLE IF NOT EXISTS users (
+ id SERIAL PRIMARY KEY,
+ email VARCHAR(255) UNIQUE NOT NULL,
+ password_hash VARCHAR(255) NOT NULL,
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
+);
+
+-- Create index on email for faster lookups during login
+CREATE INDEX idx_users_email ON users(email);
+
+-- Create function to automatically update updated_at timestamp
+CREATE OR REPLACE FUNCTION update_updated_at_column()
+RETURNS TRIGGER AS $$
+BEGIN
+ NEW.updated_at = CURRENT_TIMESTAMP;
+ RETURN NEW;
+END;
+$$ LANGUAGE plpgsql;
+
+-- Create trigger to call the function before any update
+CREATE TRIGGER update_users_updated_at
+ BEFORE UPDATE ON users
+ FOR EACH ROW
+ EXECUTE FUNCTION update_updated_at_column();
+
+-- Add comment for documentation
+COMMENT ON TABLE users IS 'User accounts for authentication';
+COMMENT ON COLUMN users.email IS 'Unique email address for login';
+COMMENT ON COLUMN users.password_hash IS 'bcrypt hashed password';
diff --git a/openended-workshop-prompts.md b/openended-workshop-prompts.md
new file mode 100644
index 0000000..b2dab87
--- /dev/null
+++ b/openended-workshop-prompts.md
@@ -0,0 +1,182 @@
+# AI-First Open-Ended Workshop Prompts
+
+Copy and paste these prompts during the workshop exercises.
+
+---
+
+## Page 14: Exercise 1: Browse & Choose Your Project
+
+**PROMPT:**
+```
+Go to: github.com/emmanuelandre/unveiling-claude
+
+Browse the available projects:
+- manu-code/ - AI CLI assistant (High complexity)
+- task-manager/ - Task management API (Medium)
+- my-api-project/ - Simple API starter (Low)
+- prompt-ops/ - Prompt operations (Medium)
+- ui-to-test/ - UI testing (Medium)
+
+Read the specs and choose ONE project.
+
+OR: Come up with your own idea!
+
+When ready, raise your hand to share your choice.
+```
+
+**EXPECTED RESULT:**
+You've chosen a project and have a rough idea of what to build
+
+---
+
+## Page 16: Exercise 2: Initial Setup
+
+**PROMPT:**
+```
+Choose ONE option:
+
+OPTION A: Fork unveiling-claude (if using sample project)
+1. Go to github.com/emmanuelandre/unveiling-claude
+2. Click "Fork" to create your copy
+3. Clone your fork:
+ git clone https://github.com/[YOUR-USERNAME]/unveiling-claude.git
+ cd unveiling-claude/[your-project]
+
+OPTION B: Create new repo (if using own idea)
+1. Create new repo on GitHub
+2. Clone it locally:
+ git clone https://github.com/[YOUR-USERNAME]/[your-repo].git
+ cd [your-repo]
+ git checkout -b feature/initial-setup
+
+Open your AI assistant and get ready!
+```
+
+**EXPECTED RESULT:**
+Repository set up and ready to work
+
+---
+
+## Page 20: Exercise 3: Create Your Plan with AI
+
+**PROMPT:**
+```
+Tell your AI assistant:
+
+I want to build [PROJECT NAME].
+
+Project context: [Brief description or link to spec]
+
+Help me create:
+1. A CLAUDE.md (or project rules file) with:
+ - Project overview
+ - Tech stack
+ - Project structure
+ - Commands (build, test, run)
+ - Testing requirements
+
+2. A specification for the FIRST feature I should build
+ - Keep it scoped for ~60 min implementation
+ - Include success criteria
+
+3. A rough implementation plan
+
+My tech stack preference: [Go/Node/Python/TypeScript]
+```
+
+**EXPECTED RESULT:**
+CLAUDE.md created and first feature specified
+
+---
+
+## Page 26: Exercise 4: Implementation Sprint 1
+
+**PROMPT:**
+```
+Time to build! Follow your plan.
+
+Suggested approach:
+1. Start with data layer (database schema, models)
+2. Then business logic (repository, handlers)
+3. Then tests
+
+Example prompt to start:
+"Based on our spec, let's start implementing.
+First, create the database schema for [your feature].
+Include proper types, indexes, and constraints."
+
+Continue from there. Work at your own pace.
+
+Checkpoint in 35 minutes!
+```
+
+**EXPECTED RESULT:**
+Core feature partially or fully implemented
+
+---
+
+## Page 30: Exercise 5: Implementation Sprint 2
+
+**PROMPT:**
+```
+Continue building your feature.
+
+Focus on:
+- Completing what you started
+- Adding tests for what works
+- Making it demo-able
+
+If you finished early:
+- Add another small feature
+- Improve tests
+- Clean up code
+- Help a neighbor
+
+Remember: Something working > Something perfect
+
+Checkpoint in 25 minutes - prepare for demo!
+```
+
+**EXPECTED RESULT:**
+Feature implemented and ready to demo
+
+---
+
+## Page 34: Exercise 6: Commit and Push
+
+**PROMPT:**
+```
+Commit and push your work:
+
+1. Review changes:
+ git status
+ git diff
+
+2. Stage and commit:
+ git add .
+ git commit -m "feat([scope]): [what you built]
+
+ - [Key thing 1]
+ - [Key thing 2]
+ - [Key thing 3]"
+
+3. Push:
+ git push origin [your-branch]
+
+4. (Optional) Create PR:
+ gh pr create --title "feat: [your feature]" \
+ --body "## What I Built
+ [Description]
+
+ ## What Works
+ - [Feature 1]
+ - [Feature 2]"
+
+Or create PR through GitHub web interface.
+```
+
+**EXPECTED RESULT:**
+Code committed and pushed to GitHub
+
+---
+
diff --git a/presentation_utils.py b/presentation_utils.py
new file mode 100644
index 0000000..692ef2b
--- /dev/null
+++ b/presentation_utils.py
@@ -0,0 +1,283 @@
+#!/usr/bin/env python3
+"""
+Shared utilities for generating AI-First Development presentations.
+Extracted from create_interactive_presentation_v2.py for reuse across presentations.
+"""
+
+from reportlab.lib.pagesizes import landscape
+from reportlab.lib.units import inch
+from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak, Table, TableStyle
+from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
+from reportlab.lib.enums import TA_LEFT, TA_CENTER
+from reportlab.pdfgen import canvas
+from reportlab.lib.colors import HexColor
+
+# 16:9 aspect ratio
+PAGESIZE = (11.0 * inch, 6.1875 * inch)
+
+# Color scheme
+PRIMARY_BLUE = HexColor('#0076CE')
+DARK_BLUE = HexColor('#003E7E')
+LIGHT_BLUE = HexColor('#48B9E8')
+DARK_GRAY = HexColor('#5B5B5B')
+MED_GRAY = HexColor('#999999')
+LIGHT_GRAY = HexColor('#E5E5E5')
+WHITE = HexColor('#FFFFFF')
+SUCCESS_GREEN = HexColor('#00B388')
+WARNING_ORANGE = HexColor('#FF8300')
+
+
+class NumberedCanvas(canvas.Canvas):
+ """Custom canvas that adds page numbers to each page."""
+
+ def __init__(self, *args, **kwargs):
+ canvas.Canvas.__init__(self, *args, **kwargs)
+ self._saved_page_states = []
+
+ def showPage(self):
+ self._saved_page_states.append(dict(self.__dict__))
+ self._startPage()
+
+ def save(self):
+ num_pages = len(self._saved_page_states)
+ for state in self._saved_page_states:
+ self.__dict__.update(state)
+ self.draw_page_number(num_pages)
+ canvas.Canvas.showPage(self)
+ canvas.Canvas.save(self)
+
+ def draw_page_number(self, page_count):
+ self.setStrokeColor(PRIMARY_BLUE)
+ self.setLineWidth(2)
+ self.line(0.5*inch, 0.4*inch, PAGESIZE[0] - 0.5*inch, 0.4*inch)
+
+ self.setFont("Helvetica", 9)
+ self.setFillColor(MED_GRAY)
+ page = "Page %d of %d" % (self._pageNumber, page_count)
+ self.drawRightString(PAGESIZE[0] - 0.5*inch, 0.25*inch, page)
+
+
+def create_document(output_filename):
+ """Create a SimpleDocTemplate with standard settings."""
+ return SimpleDocTemplate(
+ output_filename,
+ pagesize=PAGESIZE,
+ rightMargin=0.5*inch,
+ leftMargin=0.5*inch,
+ topMargin=0.7*inch,
+ bottomMargin=0.7*inch
+ )
+
+
+def create_title_slide(story, styles, title, subtitle, description=None):
+ """Create a title slide with centered content."""
+ story.append(Spacer(1, 1.5*inch))
+
+ title_para = Paragraph(f'{title}', styles['Title'])
+ story.append(title_para)
+ story.append(Spacer(1, 0.2*inch))
+
+ subtitle_para = Paragraph(f'{subtitle}', styles['Title'])
+ story.append(subtitle_para)
+
+ if description:
+ story.append(Spacer(1, 0.2*inch))
+ desc_para = Paragraph(f'{description}', styles['Title'])
+ story.append(desc_para)
+
+ story.append(PageBreak())
+
+
+def create_section_slide(story, styles, title):
+ """Create a section divider slide with blue background."""
+ story.append(Spacer(1, 1.8*inch))
+
+ section_text = Paragraph(
+ f'{title}',
+ ParagraphStyle('SectionContent', parent=styles['Normal'], fontSize=38,
+ textColor=WHITE, alignment=TA_CENTER, leading=48,
+ spaceAfter=30, spaceBefore=30)
+ )
+
+ data = [[section_text]]
+ table = Table(data, colWidths=[9.5*inch])
+ table.setStyle(TableStyle([
+ ('BACKGROUND', (0, 0), (-1, -1), PRIMARY_BLUE),
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
+ ('TOPPADDING', (0, 0), (-1, -1), 40),
+ ('BOTTOMPADDING', (0, 0), (-1, -1), 40),
+ ]))
+
+ story.append(table)
+ story.append(PageBreak())
+
+
+def create_content_slide(story, styles, title, content_items):
+ """
+ Create a standard content slide with bullets.
+
+ content_items can be:
+ - A string: Creates a bullet point
+ - A tuple (header, list): Creates a header with sub-bullets
+ """
+ slide_title = Paragraph(f'{title}', styles['Heading1'])
+ story.append(slide_title)
+ story.append(Spacer(1, 0.3*inch))
+
+ for item in content_items:
+ if isinstance(item, str):
+ p = Paragraph(f'• {item}', styles['BodyText'])
+ story.append(p)
+ story.append(Spacer(1, 0.15*inch))
+ elif isinstance(item, tuple):
+ p = Paragraph(f'{item[0]}', styles['BodyText'])
+ story.append(p)
+ story.append(Spacer(1, 0.1*inch))
+ for sub in item[1]:
+ sp = Paragraph(f' ◦ {sub}', styles['BodyText'])
+ story.append(sp)
+ story.append(Spacer(1, 0.08*inch))
+ story.append(Spacer(1, 0.1*inch))
+
+ story.append(PageBreak())
+
+
+def create_two_column_slide(story, styles, title, left_title, left_items, right_title, right_items):
+ """Create a two-column comparison slide."""
+ slide_title = Paragraph(f'{title}', styles['Heading1'])
+ story.append(slide_title)
+ story.append(Spacer(1, 0.3*inch))
+
+ # Build left column content
+ left_content = [Paragraph(f'{left_title}', styles['BodyText'])]
+ for item in left_items:
+ left_content.append(Spacer(1, 0.1*inch))
+ left_content.append(Paragraph(f'• {item}', styles['BodyText']))
+
+ # Build right column content
+ right_content = [Paragraph(f'{right_title}', styles['BodyText'])]
+ for item in right_items:
+ right_content.append(Spacer(1, 0.1*inch))
+ right_content.append(Paragraph(f'• {item}', styles['BodyText']))
+
+ # Create table
+ data = [[left_content, right_content]]
+ table = Table(data, colWidths=[4.5*inch, 4.5*inch])
+ table.setStyle(TableStyle([
+ ('VALIGN', (0, 0), (-1, -1), 'TOP'),
+ ('LEFTPADDING', (0, 0), (-1, -1), 10),
+ ('RIGHTPADDING', (0, 0), (-1, -1), 10),
+ ]))
+
+ story.append(table)
+ story.append(PageBreak())
+
+
+def create_hands_on_slide(story, styles, title, prompt, expected_result, page_num, prompts_list=None):
+ """
+ Create a hands-on exercise slide with prompt and expected result.
+
+ If prompts_list is provided, appends the prompt to it for export.
+ """
+ # Store prompt for export if list provided
+ if prompts_list is not None:
+ prompts_list.append({
+ 'page': page_num,
+ 'title': title,
+ 'prompt': prompt,
+ 'expected': expected_result
+ })
+
+ slide_title = Paragraph(f'🔨 Hands-On: {title}', styles['Heading1'])
+ story.append(slide_title)
+ story.append(Spacer(1, 0.2*inch))
+
+ # Instruction
+ instruction = Paragraph('YOUR PROMPT:', styles['BodyText'])
+ story.append(instruction)
+ story.append(Spacer(1, 0.15*inch))
+
+ # Format prompt with line breaks preserved
+ prompt_html = prompt.replace('\n', '
')
+
+ # Prompt box with preformatted style
+ prompt_para = Paragraph(
+ f'{prompt_html}',
+ ParagraphStyle('PromptBox',
+ parent=styles['BodyText'],
+ leftIndent=20,
+ rightIndent=20,
+ backColor=LIGHT_GRAY,
+ spaceBefore=5,
+ spaceAfter=5,
+ leading=14)
+ )
+ story.append(prompt_para)
+ story.append(Spacer(1, 0.2*inch))
+
+ # Expected result
+ result = Paragraph('What You Should See:', styles['BodyText'])
+ story.append(result)
+ story.append(Spacer(1, 0.1*inch))
+
+ result_text = Paragraph(f'• {expected_result}', styles['BodyText'])
+ story.append(result_text)
+
+ story.append(PageBreak())
+
+
+def create_code_slide(story, styles, title, language, code):
+ """Create a code example slide."""
+ slide_title = Paragraph(f'{title}', styles['Heading1'])
+ story.append(slide_title)
+ story.append(Spacer(1, 0.25*inch))
+
+ # Language label
+ lang_label = Paragraph(f'{language.upper()}', styles['BodyText'])
+ story.append(lang_label)
+ story.append(Spacer(1, 0.1*inch))
+
+ # Code with line breaks preserved
+ code_html = code.replace('\n', '
').replace(' ', ' ')
+ code_para = Paragraph(
+ f'{code_html}',
+ ParagraphStyle('CodeBox',
+ parent=styles['BodyText'],
+ leftIndent=15,
+ rightIndent=15,
+ backColor=LIGHT_GRAY,
+ spaceBefore=5,
+ spaceAfter=5,
+ leading=12)
+ )
+ story.append(code_para)
+ story.append(PageBreak())
+
+
+def create_thank_you_slide(story, styles, title="Thank You!", subtitle="Questions?"):
+ """Create a thank you/closing slide."""
+ story.append(Spacer(1, 2*inch))
+ thank_you = Paragraph(f'{title}', styles['Title'])
+ story.append(thank_you)
+ story.append(Spacer(1, 0.4*inch))
+
+ questions = Paragraph(f'{subtitle}', styles['Title'])
+ story.append(questions)
+
+
+def export_prompts_to_markdown(prompts_list, output_filename, title="Workshop Prompts"):
+ """Export collected prompts to a markdown file."""
+ with open(output_filename, 'w') as f:
+ f.write(f'# {title}\n\n')
+ f.write('Copy and paste these prompts during the workshop exercises.\n\n')
+ f.write('---\n\n')
+
+ for item in prompts_list:
+ f.write(f'## Page {item["page"]}: {item["title"]}\n\n')
+ f.write('**PROMPT:**\n```\n')
+ f.write(item['prompt'])
+ f.write('\n```\n\n')
+ f.write(f'**EXPECTED RESULT:**\n')
+ f.write(f'{item["expected"]}\n\n')
+ f.write('---\n\n')
diff --git a/prompts.md b/prompts.md
index 4d5e049..2a7133d 100644
--- a/prompts.md
+++ b/prompts.md
@@ -4,7 +4,7 @@ Copy and paste these prompts during the workshop exercises.
---
-## Page 9: Create Your First Project
+## Page 24: Create Your First Project
**PROMPT:**
```
@@ -27,7 +27,7 @@ Claude creates a comprehensive CLAUDE.md with architecture, commands, and conven
---
-## Page 10: Initialize Git Workflow
+## Page 25: Initialize Git Workflow
**PROMPT:**
```
@@ -44,7 +44,7 @@ Git repository with proper branch structure and commit conventions
---
-## Page 13: Step 1 - Write Specification
+## Page 28: Step 1 - Write Specification
**PROMPT:**
```
@@ -74,7 +74,7 @@ Claude asks clarifying questions and confirms the specification
---
-## Page 15: Step 2 - Review Schema
+## Page 30: Step 2 - Review Schema
**PROMPT:**
```
@@ -97,7 +97,7 @@ Database table created successfully with proper indexes
---
-## Page 17: Step 4 - Request API Implementation
+## Page 32: Step 4 - Request API Implementation
**PROMPT:**
```
@@ -127,7 +127,7 @@ Claude creates handler files with validation and error handling
---
-## Page 19: Step 5 - Request API Tests
+## Page 34: Step 5 - Request API Tests
**PROMPT:**
```
@@ -152,7 +152,7 @@ Cypress test file created with all test cases
---
-## Page 21: Run API Tests
+## Page 36: Run API Tests
**PROMPT:**
```
@@ -171,7 +171,7 @@ All API tests pass (green checkmarks in terminal)
---
-## Page 22: Step 6 - Request Frontend
+## Page 37: Step 6 - Request Frontend
**PROMPT:**
```
@@ -198,7 +198,7 @@ React components created with forms and state management
---
-## Page 24: Step 7 - Request UI Tests
+## Page 39: Step 7 - Request UI Tests
**PROMPT:**
```
@@ -220,7 +220,7 @@ Cypress UI test file created with user journey tests
---
-## Page 28: Practice: Write E2E Test
+## Page 43: Practice: Write E2E Test
**PROMPT:**
```
@@ -242,7 +242,7 @@ Complete password reset feature with passing E2E tests
---
-## Page 32: Practice: Proper Git Workflow
+## Page 47: Practice: Proper Git Workflow
**PROMPT:**
```
@@ -267,7 +267,7 @@ PR created with passing CI checks and proper commit messages
---
-## Page 34: Practice: Better Prompts
+## Page 49: Practice: Better Prompts
**PROMPT:**
```
@@ -296,7 +296,7 @@ You create a comprehensive, specific prompt with clear requirements
---
-## Page 38: Final Exercise: Complete Feature
+## Page 53: Final Exercise: Complete Feature
**PROMPT:**
```
@@ -328,7 +328,7 @@ Complete profile feature with passing tests and PR ready for review
---
-## Page 44: EXERCISE: Multi-Phase Task Manager (Phase 0)
+## Page 59: EXERCISE: Multi-Phase Task Manager (Phase 0)
**PROMPT:**
```
@@ -371,7 +371,7 @@ devplan.md created with 4 phases and dependency mapping
---
-## Page 45: EXERCISE: Create Progress Tracker
+## Page 60: EXERCISE: Create Progress Tracker
**PROMPT:**
```
@@ -406,7 +406,7 @@ devprogress.md and database.md created
---
-## Page 46: EXERCISE: Implement Phase 0 Database
+## Page 61: EXERCISE: Implement Phase 0 Database
**PROMPT:**
```
@@ -444,7 +444,7 @@ Migrations created and progress updated
---
-## Page 47: EXERCISE: Implement Auth System
+## Page 62: EXERCISE: Implement Auth System
**PROMPT:**
```
@@ -478,3 +478,58 @@ Auth implemented and progress updated
---
+## NEW: Documentation Organization Exercise
+
+**PROMPT:**
+```
+I'm starting a new project. Help me decide on documentation structure.
+
+Project details:
+- Solo developer
+- 3-month project
+- Single Go API service
+- ~40 tasks estimated
+
+Based on these factors, should I use:
+A) Simple flat structure (plan.md, architecture.md at root)
+B) Nested structure (project/planning/, project/specs/)
+
+Create the appropriate documentation files for my choice.
+Include:
+- plan.md or devplan.md with milestones
+- architecture.md with system design
+- requirements.md with key features
+```
+
+**EXPECTED RESULT:**
+Claude recommends nested structure (40 tasks, 3 months) and creates starter files
+
+**REFERENCE:**
+See [docs/12-documentation-organization.md](docs/12-documentation-organization.md) for decision criteria and templates.
+
+---
+
+## NEW: Migrate Flat to Nested Structure
+
+**PROMPT:**
+```
+My project has grown. I started with simple flat docs:
+- plan.md
+- architecture.md
+- requirements.md
+
+Now I have 50+ tasks across 5 features. Help me migrate to
+the nested structure:
+- Move plan.md content to project/planning/devplan.md
+- Create project/planning/devprogress.md for tracking
+- Split requirements into project/specs/ by feature
+- Keep architecture.md updated
+
+Preserve all existing content during migration.
+```
+
+**EXPECTED RESULT:**
+Documentation migrated to nested structure with content preserved
+
+---
+
diff --git a/workshop-prompts.md b/workshop-prompts.md
new file mode 100644
index 0000000..7bbf4f4
--- /dev/null
+++ b/workshop-prompts.md
@@ -0,0 +1,451 @@
+# AI-First Workshop Prompts
+
+Copy and paste these prompts during the workshop exercises.
+
+---
+
+## Page 9: Exercise 1: Create Your Repository
+
+**PROMPT:**
+```
+Create a new GitHub repository for your project:
+
+1. Go to github.com and create a new PRIVATE repository
+ Name: my-ai-project (or your preferred name)
+
+2. Clone it locally:
+ git clone https://github.com/[YOUR-USERNAME]/my-ai-project.git
+ cd my-ai-project
+
+3. Verify:
+ git status
+ Should show: "On branch main, nothing to commit"
+
+Reference: Check unveiling-claude repo structure for ideas
+```
+
+**EXPECTED RESULT:**
+Local repository initialized and connected to GitHub
+
+---
+
+## Page 10: Exercise 2: Create Project Rules File
+
+**PROMPT:**
+```
+Ask your AI assistant:
+
+Help me create a project rules file for my project.
+
+Project details:
+- Language: [Go/Node/Python]
+- Type: REST API with database
+- Database: PostgreSQL (or SQLite for simplicity)
+- Testing: E2E with [Cypress/Go test/pytest]
+
+Include these sections:
+1. Project Overview (what this project does)
+2. Tech Stack (language, framework, database)
+3. Project Structure (recommended directories)
+4. Commands (build, test, run)
+5. Git Workflow (branch naming, commit format)
+6. Testing Requirements (E2E mandatory)
+
+Save as CLAUDE.md (or .windsurfrules for Windsurf)
+```
+
+**EXPECTED RESULT:**
+Project rules file created with all sections
+
+---
+
+## Page 12: Exercise 3: Initialize Git Workflow
+
+**PROMPT:**
+```
+Ask your AI assistant:
+
+Set up the git workflow for my project:
+
+1. Create .gitignore for [Go/Node/Python] project
+ Include: build outputs, dependencies, IDE files, .env
+
+2. Create initial directory structure:
+ - cmd/ or src/ for source code
+ - tests/ or test/ for tests
+ - migrations/ for database migrations
+ - docs/ for documentation
+
+3. Create initial commit:
+ git add .
+ git commit -m "chore: initial project setup"
+
+4. Create feature branch for our first feature:
+ git checkout -b feature/user-auth
+```
+
+**EXPECTED RESULT:**
+Git initialized with proper structure and on feature branch
+
+---
+
+## Page 16: Step 1: Write Feature Specification
+
+**PROMPT:**
+```
+Ask your AI assistant:
+
+I need to implement user authentication for my API.
+
+Requirements:
+- Users register with email and password
+- Users login with email and password
+- JWT tokens for authentication
+- Password hashing (never store plain text)
+
+Database Schema Needed:
+- users table: id, email, password_hash, created_at, updated_at
+
+API Endpoints:
+POST /api/auth/register - Register new user
+ Request: { email, password }
+ Response: { user_id, email, token }
+
+POST /api/auth/login - Login existing user
+ Request: { email, password }
+ Response: { user_id, email, token }
+
+Success Criteria:
+- Passwords hashed with bcrypt
+- JWT expires after 1 hour
+- Proper HTTP status codes (201, 200, 400, 401)
+- E2E tests cover happy path and errors
+
+Please confirm you understand before we proceed.
+```
+
+**EXPECTED RESULT:**
+AI confirms understanding, may ask clarifying questions
+
+---
+
+## Page 18: Step 2: Create Database Schema
+
+**PROMPT:**
+```
+Ask your AI assistant:
+
+Create the database migration for the users table.
+
+Requirements:
+- Table name: users
+- Columns: id (primary key), email (unique), password_hash, created_at, updated_at
+- Add index on email column for fast lookups
+
+For Go: Create migrations/001_create_users.up.sql and .down.sql
+For Node: Create migrations/001_create_users.js
+For Python: Create migrations/001_create_users.py
+
+Use appropriate types for your database:
+- PostgreSQL: SERIAL, VARCHAR, TIMESTAMP
+- SQLite: INTEGER PRIMARY KEY, TEXT
+
+Include both up (create) and down (drop) migrations.
+```
+
+**EXPECTED RESULT:**
+Migration file(s) created with proper schema
+
+---
+
+## Page 21: Step 3: Implement Repository Layer
+
+**PROMPT:**
+```
+Ask your AI assistant:
+
+Implement the repository layer for user operations.
+
+Create a UserRepository with these methods:
+- Create(email, passwordHash) -> User
+- FindByEmail(email) -> User or null
+- FindByID(id) -> User or null
+
+Requirements:
+- Use prepared statements (prevent SQL injection)
+- Handle database errors gracefully
+- Return appropriate errors (not found, duplicate, etc.)
+
+Place in:
+- Go: internal/repository/user_repository.go
+- Node: src/repositories/userRepository.js
+- Python: app/repositories/user_repository.py
+
+Follow patterns from the project rules file.
+```
+
+**EXPECTED RESULT:**
+Repository file created with all methods
+
+---
+
+## Page 22: Step 4: Implement API Handlers
+
+**PROMPT:**
+```
+Ask your AI assistant:
+
+Implement the API handlers for authentication.
+
+Create handlers for:
+1. POST /api/auth/register
+ - Validate email format
+ - Validate password (minimum 8 characters)
+ - Hash password with bcrypt
+ - Create user in database
+ - Generate and return JWT token
+ - Return 400 for validation errors
+ - Return 409 for duplicate email
+
+2. POST /api/auth/login
+ - Find user by email
+ - Verify password against hash
+ - Generate and return JWT token
+ - Return 401 for invalid credentials
+
+Include:
+- Input validation
+- Proper HTTP status codes
+- JSON response format: { success: true/false, data/error }
+- Wire up routes to main application
+```
+
+**EXPECTED RESULT:**
+Handler files created and routes configured
+
+---
+
+## Page 25: Step 5: Write E2E API Tests
+
+**PROMPT:**
+```
+Ask your AI assistant:
+
+Create E2E tests for the authentication endpoints.
+
+Test cases needed:
+1. Register - Happy path (201)
+ - New user can register
+ - Response includes token
+
+2. Register - Duplicate email (409)
+ - Cannot register same email twice
+
+3. Register - Invalid email (400)
+ - Rejects malformed email
+
+4. Register - Weak password (400)
+ - Rejects password < 8 chars
+
+5. Login - Valid credentials (200)
+ - Returns token
+
+6. Login - Invalid password (401)
+ - Wrong password rejected
+
+7. Login - Non-existent user (401)
+ - Unknown email rejected
+
+Use your testing framework:
+- Go: internal/handlers/auth_test.go
+- Node: tests/api/auth.test.js (Jest/Vitest)
+- Python: tests/test_auth.py (pytest)
+
+Include setup and teardown for test database.
+```
+
+**EXPECTED RESULT:**
+Test file created with all test cases
+
+---
+
+## Page 27: Run and Verify Tests
+
+**PROMPT:**
+```
+Run your E2E tests:
+
+For Go:
+ go test -v ./internal/handlers/...
+
+For Node:
+ npm test -- --grep "Auth API"
+
+For Python:
+ pytest tests/test_auth.py -v
+
+Expected: All 7 test cases pass (green)
+
+If tests fail, share the error with your AI assistant:
+"Test [name] is failing with this error:
+[paste error output]
+
+Please analyze the failure and suggest a fix."
+
+Continue until ALL tests pass!
+```
+
+**EXPECTED RESULT:**
+All E2E tests passing (7/7 green)
+
+---
+
+## Page 31: Exercise: Add Unit Tests
+
+**PROMPT:**
+```
+Ask your AI assistant:
+
+Add unit tests for the authentication logic.
+
+Create unit tests for:
+1. Password validation function
+ - Test: 8+ chars passes
+ - Test: < 8 chars fails
+ - Test: Empty string fails
+
+2. Email validation function
+ - Test: valid@email.com passes
+ - Test: invalid-email fails
+ - Test: Empty string fails
+
+3. JWT token generation
+ - Test: Token contains user ID
+ - Test: Token has correct expiration
+
+4. Password hashing
+ - Test: Same password produces different hashes (salt)
+ - Test: Verify function works
+
+Place in appropriate test file:
+- Go: internal/auth/auth_test.go
+- Node: tests/unit/auth.test.js
+- Python: tests/unit/test_auth.py
+```
+
+**EXPECTED RESULT:**
+Unit tests created and passing
+
+---
+
+## Page 35: Exercise: Create Proper Commits
+
+**PROMPT:**
+```
+Ask your AI assistant:
+
+Help me commit my authentication feature properly.
+
+My changes include:
+- Database migration for users table
+- Repository layer
+- API handlers
+- E2E tests
+- Unit tests
+
+Steps:
+1. Review what's changed: git status
+2. Stage all changes: git add .
+3. Create commit with conventional format
+
+Suggested commit message:
+feat(auth): add user registration and login
+
+- Add users table migration
+- Implement user repository with CRUD
+- Create register and login endpoints
+- Add E2E tests for all auth endpoints
+- Add unit tests for validation logic
+
+After committing, verify with: git log --oneline -1
+```
+
+**EXPECTED RESULT:**
+Commit created with proper conventional commit message
+
+---
+
+## Page 36: Exercise: Create Pull Request
+
+**PROMPT:**
+```
+Ask your AI assistant:
+
+Help me push my branch and create a pull request.
+
+Steps:
+1. Push branch to remote:
+ git push -u origin feature/user-auth
+
+2. Create PR (with GitHub CLI):
+ gh pr create --title "feat: Add user authentication" \
+ --body "## Summary
+ - User registration endpoint
+ - User login endpoint
+ - JWT token authentication
+ - E2E tests (7 passing)
+ - Unit tests for validation
+
+ ## Testing
+ - All E2E tests pass
+ - All unit tests pass
+ - Manual testing completed
+
+ ## Checklist
+ - [x] Code follows project conventions
+ - [x] Tests added
+ - [x] Documentation updated"
+
+Or create PR through GitHub web interface.
+```
+
+**EXPECTED RESULT:**
+PR created on GitHub with description
+
+---
+
+## Page 41: Final Challenge: Your Feature
+
+**PROMPT:**
+```
+Choose ONE feature and implement it fully:
+
+OPTION A: GET /api/auth/me
+- Returns current user info from JWT token
+- Response: { id, email, created_at }
+- Tests: valid token returns user, invalid token returns 401
+
+OPTION B: PUT /api/auth/password
+- Request: { current_password, new_password }
+- Verify current password, update to new
+- Tests: success, wrong current password, weak new password
+
+OPTION C: POST /api/auth/logout
+- Invalidate current token (add to blacklist)
+- Tests: logout succeeds, token no longer works
+
+Steps:
+1. Tell AI which feature you chose
+2. Have AI implement it
+3. Review the code
+4. Run tests
+5. Commit with conventional format
+
+Time limit: 25 minutes
+```
+
+**EXPECTED RESULT:**
+New feature implemented with passing tests and committed
+
+---
+