Introduction: The Missing Bridge

You have an approved specification scoring ≥75/100 defining WHAT to build. But there's a gap before creating executable tasks. You need to answer HOW:

  • Which components are required?
  • How do they interact?
  • What database changes are needed?
  • Which existing code do we integrate with?

This is the technical plan - the bridge between specification and task decomposition.

The SDD Workflow
┌────────────────────────────────────────────────────────────────┐
│  📋 PRD → 📝 Specification (WHAT) → 🏗️ Technical Plan (HOW)     │
│  (Product Requirements Doc)          ◄── CURRENT LESSON        │
│  → ✅ Task Decomposition → 💻 Implementation        📝          │
└────────────────────────────────────────────────────────────────┘

SDD (Specification-Driven Development) is the workflow this course follows: starting from a PRD (Product Requirements Document), you produce a specification, then a technical plan, then decomposed tasks, and finally implementation.

A technical plan translates functional requirements into concrete technical decisions. It has 7 key sections.

Reference: CODEX.md

Throughout this lesson, several sections reference CODEX.md. This is a project-level conventions file that Codex reads to understand your codebase's patterns, structure, and standards. When generating a technical plan, Codex uses it to make decisions consistent with your existing project.

Here is the CODEX.md for the TaskMaster project used in all examples below:

# TaskMaster CODEX.md

## Project Overview
TaskMaster is a task management API built with Python 3.11, FastAPI,
SQLAlchemy, and PostgreSQL.

## Architecture
All features follow the layered architecture pattern:
  API Router → Service → Repository → Database

## Patterns & Conventions

### Repository Pattern
- ALL database access must go through repository classes
- Repositories live in src/repositories/
- Never access the database directly from services or API handlers

### Dependency Injection
- Use FastAPI's Depends() for all dependencies
- Standard dependencies: get_db (database session), get_current_user (auth)

### Error Handling
- Raise HTTPException with appropriate status codes
- Services raise domain exceptions; API layer converts to HTTPException
- Standard codes: 400 (validation), 401 (unauthenticated),
  403 (forbidden), 404 (not found)

### Type Hints
- All functions must have full type hints
- Use Pydantic schemas for all request/response serialization

## Directory Structure
src/
  api/           # FastAPI routers
  models/        # SQLAlchemy models
  schemas/       # Pydantic schemas
  services/      # Business logic
  repositories/  # Database access
  database.py    # Session management
tests/
  unit/          # Unit tests with mocked dependencies
  integration/   # Integration tests with TestClient

## Testing Standards
- Repositories: 95%+ coverage
- Services: 90%+ coverage
- API endpoints: 85%+ coverage
- All authorization logic must be tested

Every decision in your technical plan should be traceable back to these conventions.

1. Architecture (Component Interactions)
## Architecture: Task Comments

Component Flow:
Client → API Endpoint → CommentService → CommentRepository → Database

Data Flow:
1. Client sends POST /api/tasks/{id}/comments with JWT
2. API validates token, calls `CommentService.create_comment()`
3. Service validates: user owns task, content length valid
4. Service calls CommentRepository.create()
5. Repository persists via SQLAlchemy, returns Comment
6. API transforms to CommentSchema, returns 201

Why: Prevents conflicting assumptions about layer responsibilities, duplicate validation, and architectural drift.

Common mistakes: Reversed dependencies (Service→API), skipping layers (API→DB), ambiguous validation location.

How to decide: Start from entry point → follow data transformations → identify decision points → validate against CODEX.md.

2. Data Model (Database Schema)
## Data Model: Comment

Table: comments
- id: UUID, primary key, default=uuid4
- task_id: UUID, FK to tasks.id, NOT NULL
- user_id: UUID, FK to users.id, NOT NULL
- content: String(5000), NOT NULL
- created_at: DateTime, default=utcnow, NOT NULL

Relationships:
- task: relationship to Task (backref="comments")
- author: relationship to User (backref="comments")

Indexes:
- (task_id, created_at) for chronological listing

Why: Prevents N+1 queries, missing constraints, orphaned records, and performance issues.

Common mistakes: No indexes, missing NOT NULL, undefined relationships, ambiguous column types.

How to decide: Indexes for query patterns, NOT NULL for required data, relationships for navigation, FKs for referential integrity.

3. API Implementation (Endpoints)
## API Implementation

POST /api/tasks/{task_id}/comments
- Router: src/api/comments.py, async def create_comment()
- Dependencies: current_user, comment_service
- Response: 201 with CommentSchema
- Errors: 400/401/403/404
- Error handling: Catch service exceptions → HTTPException

GET /api/tasks/{task_id}/comments
- Query params: skip (0), limit (50)
- Response: 200 with List[CommentSchema]

DELETE /api/comments/{comment_id}
- Authorization: comment owner OR task owner
- Response: 204 No Content

Why: Prevents inconsistent error codes, missing authorization, and security vulnerabilities.

Common mistakes: No error codes specified, missing authorization, unclear dependencies, ambiguous response formats.

How to decide: RESTful paths, map exceptions to HTTP status, specify all dependencies, check authorization before service layer.

4. Module Structure (Files)
## Module Structure

New Files:
- src/models/comment.py
- src/repositories/comment_repository.py
- src/services/comment_service.py
- src/schemas/comment.py
- src/api/comments.py

Test Files:
- tests/unit/test_comment_{model,repository,service}.py
- tests/integration/test_comment_api.py

Modified Files:
- src/models/task.py (add comments relationship)
- src/api/__init__.py (register router)
- alembic/versions/XXXX_add_comments_table.py

Why: Prevents files in wrong directories, forgotten tests/migrations, and merge conflicts.

Common mistakes: Only listing new files, no test structure, missing migrations, incorrect paths.

How to decide: Follow existing structure, one file per concern, test mirrors production, list all modifications.

5. Integration Points (Existing Code)
## Integration Points

Use Existing Code:
1. Task Model (src/models/task.py) - validate task_id, check ownership
2. User Model (src/models/user.py) - foreign key for author
3. Authentication (src/api/auth.py) - get_current_user dependency
4. Database Session (src/database.py) - get_db dependency
5. Repository Pattern (CODEX.md) - all DB access through repositories
6. Error Handling (CODEX.md) - HTTPException with status codes

Why: Prevents reinventing functionality, breaking patterns, and import cycles.

Common mistakes: Creating new auth, direct DB access, custom error handling, ignoring CODEX.md patterns.

How to decide: Scan CODEX.md first → review existing models → check api/ for utilities → validate compliance.

6. Testing Strategy (Coverage)
## Testing Strategy

Unit Tests (Mocked):
- test_comment_repository.py: create, get, list, delete (95%+)
- test_comment_service.py: validation, authorization logic (90%+)

Integration Tests (TestClient):
- test_comment_api.py: all endpoints, auth, errors (85%+)

Overall Target: 90%+

Why: Prevents inadequate coverage, untested authorization, and missing edge cases.

Common mistakes: "Write some tests", no coverage targets, only unit OR integration, no error case testing.

How to decide: One test file per production file, repositories 95%+, services 90%+, APIs 85%+, test authorization and validation critically. (These targets come directly from CODEX.md's Testing Standards.)

7. Security Considerations
## Security

Authorization:
- Verify user owns task before comment creation
- DELETE: Allow comment owner OR task owner

Input Validation:
- Content: 1-5000 characters
- Use SQLAlchemy ORM (no raw SQL)

Data Leaks:
- Use Pydantic schemas for responses (never raw ORM)
- Only return comments for user's tasks

Why: Prevents authorization bypasses, injection attacks, and data leaks.

Common mistakes: No authorization, missing validation, raw SQL, returning ORM objects directly.

How to decide: Check authorization in service layer, validate all inputs, use ORM, always use Pydantic schemas, exclude sensitive fields.

Technical Plan vs Specification
AspectSpecificationTechnical Plan
AudienceProduct team + developersDevelopers only
FocusUser behavior, validationComponents, files, patterns
Example"Comments: 1-5000 chars""CommentService validates, raises ValidationError"
How Detailed Should It Be?

Rule: Enough to make task decomposition obvious, but not implementation code.

Too sparse: "Create comment system with FastAPI" → Can't decompose without guessing

Too verbose: Full implementation code → This IS the code, not a plan

Just right: "POST /api/tasks/{id}/comments, Router: src/api/comments.py, Dependencies: current_user + comment_service, Errors: 400/401/403/404" → Clear decisions, ready for tasks

Validation & Usage

Before task decomposition, validate:

  • ✅ Follows repository pattern (API → Service → Repository → DB)
  • ✅ Uses dependency injection
  • ✅ Uses existing models/patterns from CODEX.md
  • ✅ All components specified
  • ✅ Can decompose into clear tasks

When to skip:

  • Trivial changes (one field, simple bugs)
  • Exploratory spikes

Always create for:

  • New components/tables
  • Multi-component features
  • Architectural changes

Generating with Codex:

Given approved specification (specs/task-comments/specification.md),
generate technical plan for TaskMaster.

Context: Review CODEX.md, analyze existing code
Stack: Python 3.11, FastAPI, SQLAlchemy, PostgreSQL

Required: Architecture, Data Model, API, Module Structure, 
Integration Points, Testing, Security

Constraints: Repository pattern, DI, type hints, HTTPException
Summary

Technical plans bridge specification (WHAT) → task decomposition (executable work).

7 Required sections:

  1. Architecture - Component flow and data transformations
  2. Data Model - Schemas, constraints, indexes, relationships
  3. API - Endpoints, dependencies, errors, authorization
  4. Module Structure - New/modified files, tests, migrations
  5. Integration Points - Existing code to reuse
  6. Testing - Coverage targets by layer
  7. Security - Authorization, validation, data protection

Each section teaches:

  • What to specify
  • Why it matters
  • Common mistakes
  • Decision framework

Right detail level: Specific enough for task decomposition but not implementation code. Always validate against CODEX.md before proceeding.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal