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 +Description + +// Or use Next.js Image component +import Image from 'next/image'; + +Description +``` + +### 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 + +--- +