Skip to main content

Overview

Architecture artifacts in the SDD framework document the system’s structure, decomposition, and deployment strategy. They are generated by the plan-architect skill and stored in plan/.

Location

plan/
├── PLAN.md                        # Master implementation plan
├── ARCHITECTURE.md                # Architecture views (C4, deployment, data)
├── CLARIFY-LOG.md                 # Implementation decision log
├── RESEARCH.md                    # Technology research findings
├── fases/                         # FASE navigation indices
│   ├── README.md                  # Coverage matrices and dependency graph
│   ├── FASE-0-BOOTSTRAP.md        # Phase 0 index
│   ├── FASE-1-EXTRACTION.md       # Phase 1 index
│   └── FASE-2-ANALYSIS.md         # Phase 2 index
└── fase-plans/                    # Per-FASE implementation details
    ├── PLAN-FASE-0.md
    ├── PLAN-FASE-1.md
    └── PLAN-FASE-2.md

FASE structure (implementation phases)

FASE files are navigation indices that map specifications to incremental implementation phases. They are derived artifacts — always regenerated from specs, never patched incrementally.

FASE--.md

# FASE-1: Extraction & Upload

## Metadata
| Field | Value |
|-------|-------|
| Estado | pending |
| Dependencias | FASE-0 |
| Valor Observable | PDF files can be uploaded and stored |

## Objetivo

Implement the core PDF upload and storage functionality. Users can upload PDF files up to 50MB, which are validated and stored in object storage. A CVAnalysis entity is created with status=PENDING.

## Criterios de éxito

- [ ] POST /api/v1/pdfs accepts valid PDFs up to 50MB
- [ ] File size validation enforced (INV-EXT-005)
- [ ] CVAnalysis entity created with correct fields
- [ ] "cv.uploaded" event published to queue
- [ ] All BDD-001 scenarios pass

## Specs a leer

### Use Cases
- `spec/use-cases/UC-001-upload-pdf.md` — Main upload flow with preconditions, postconditions, and exception handling

### Workflows
None for this FASE.

### Domain Model
- `spec/domain/02-ENTITIES.md` — Section 1: CVAnalysis entity definition
- `spec/domain/05-INVARIANTS.md` — INV-EXT-001 through INV-EXT-010

### Contracts
- `spec/contracts/API-pdf-upload.md` — POST /api/v1/pdfs request/response schema
- `spec/contracts/EVENTS-domain.md` — cv.uploaded event schema
- `spec/contracts/ERROR-CODES.md` — Error responses for upload failures

### Tests
- `spec/tests/BDD-001-pdf-upload.md` — Acceptance scenarios (5 scenarios)

### NFRs
- `spec/nfr/PERFORMANCE.md` — Upload time targets (p99 < 5s for 50MB)
- `spec/nfr/LIMITS.md` — Rate limits (10 uploads/day per user)

### ADRs
- `spec/adr/ADR-001-typescript.md` — Language choice
- `spec/adr/ADR-002-cloudflare-workers.md` — Platform choice
- `spec/adr/ADR-007-r2-storage.md` — Object storage choice

### Runbooks
None for this FASE.

## Invariantes aplicables

### De esta FASE
- **INV-EXT-005**: fileSize ≤ 50MB (52,428,800 bytes)
- **INV-EXT-001**: status cannot transition from COMPLETED to PENDING
- **INV-EXT-002**: processedAt must be null when status is PENDING

### Heredados de FASE-0 (acumulativos)
- **INV-SYS-001**: All entities must have a valid UUID id
- **INV-SYS-003**: Timestamps must be in ISO-8601 format

## Contenido específico

### File size validation formula

From INV-EXT-005:
```javascript
MAX_FILE_SIZE = 50 * 1024 * 1024 = 52,428,800 bytes

if (fileSize > MAX_FILE_SIZE) {
  throw new ValidationError("FILE_TOO_LARGE", "File size exceeds 50MB limit");
}

CVAnalysis entity type

From domain/02-ENTITIES.md §1:
interface CVAnalysis {
  id: UUID;
  fileName: string;       // 1-255 chars, must end in .pdf
  fileSize: number;       // 1 ≤ size ≤ 52,428,800
  status: "PENDING" | "PROCESSING" | "COMPLETED" | "FAILED";
  uploadedAt: string;     // ISO-8601, immutable
  processedAt: string | null;
}

Contratos resultantes

API Endpoints

  • POST /api/v1/pdfs (API-pdf-upload) — Upload PDF file
  • GET /api/v1/analyses/:id (API-analysis-status) — Get analysis status

Domain Events

  • cv.uploaded — Published when upload succeeds

Verificación

Unit Tests

npm test src/domain/entities/cv-analysis.test.ts
npm test src/validation/file-size.test.ts

Integration Tests

npm test tests/integration/pdf-upload.test.ts

Manual Verification

# Valid upload
curl -X POST https://api.example.com/api/v1/pdfs \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@test-files/valid-10mb.pdf"

# Expected: 201 Created with analysisId

# File too large
curl -X POST https://api.example.com/api/v1/pdfs \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@test-files/invalid-51mb.pdf"

# Expected: 413 Payload Too Large

Alcance

Incluye

  • PDF upload endpoint
  • File size validation
  • PDF format validation
  • CVAnalysis entity creation
  • Event publishing
  • Error handling for upload failures

Excluye

  • Text extraction (FASE-2)
  • CV parsing (FASE-3)
  • Skills analysis (FASE-4)
  • Authentication implementation (FASE-0)
  • Rate limiting enforcement (FASE-0)

## FASE principles

<ResponseField name="100% Coverage" type="constraint">
  Every spec file MUST appear in at least one FASE file. No orphan specs.
</ResponseField>

<ResponseField name="No Content Duplication" type="constraint">
  FASE files ONLY reference specs by path + section. Exception: "Contenido Específico" for formulas/diagrams (max 30 lines).
</ResponseField>

<ResponseField name="Dependencies Form a DAG" type="constraint">
  No circular dependencies between phases. Topological sort must succeed.
</ResponseField>

<ResponseField name="Each Phase Independently Testable" type="constraint">
  Verifiable in isolation given its dependencies.
</ResponseField>

<ResponseField name="Ubiquitous Language" type="constraint">
  Only terms from `domain/01-GLOSSARY.md` in descriptions.
</ResponseField>

## Architecture views

### ARCHITECTURE.md

Contains multiple architecture views generated from specifications.

```markdown
# Architecture Document

> **Project:** My Project
> **Version:** 1.0
> **Generated from:** spec/ + plan/CLARIFY-LOG.md
> **SWEBOK alignment:** Ch02 — Software Design

## 1. C4 System Context (Level 1)

┌─────────────┐ │ User │ └──────┬──────┘ │ │ HTTPS ↓ ┌─────────────────────────────────┐ │ CV Analysis System │ │ │ │ - Upload PDFs │ │ - Extract text │ │ - Analyze skills │ └─────┬───────────────────┬───────┘ │ │ │ REST │ Queue ↓ ↓ ┌──────────┐ ┌──────────────┐ │ Object │ │ Processing │ │ Storage │ │ Worker │ └──────────┘ └──────────────┘

### External Systems
- **Object Storage** (Cloudflare R2) — Stores uploaded PDF files
- **Queue** (Cloudflare Queues) — Async processing

## 2. C4 Container Diagram (Level 2)

┌─────────────────────────────────────────────────────┐ │ Cloudflare Workers Platform │ ├─────────────────────────────────────────────────────┤ │ │ │ ┌──────────────┐ ┌──────────────────────┐ │ │ │ API Worker │ │ Processing Worker │ │ │ │ │ │ │ │ │ │ - Routes │ │ - Extract text │ │ │ │ - Validation│ │ - Parse data │ │ │ │ - Auth │ │ - Analyze skills │ │ │ └──────┬───────┘ └────────┬─────────────┘ │ │ │ │ │ │ │ │ │ │ ↓ ↓ │ │ ┌──────────────┐ ┌──────────────────────┐ │ │ │ D1 │ │ Cloudflare Queues │ │ │ │ (Database) │ │ │ │ │ └──────────────┘ └──────────────────────┘ │ │ │ │ ↓ │ │ ┌──────────────┐ │ │ │ R2 │ │ │ │ (Storage) │ │ │ └──────────────┘ │ └─────────────────────────────────────────────────────┘

### Technology Stack
- **Runtime:** Cloudflare Workers (ADR-002)
- **Language:** TypeScript (ADR-001)
- **Database:** Cloudflare D1 (ADR-005)
- **Object Storage:** Cloudflare R2 (ADR-007)
- **Queue:** Cloudflare Queues (ADR-008)
- **Validation:** Zod (ADR-015)

## 3. Physical Data Model

From domain/02-ENTITIES.md and CL-DATA-001:

### cv_analyses table
```sql
CREATE TABLE cv_analyses (
  id TEXT PRIMARY KEY,              -- UUID v4
  user_id TEXT NOT NULL,            -- UUID v4
  file_name TEXT NOT NULL,          -- 1-255 chars
  file_size INTEGER NOT NULL,       -- bytes, ≤ 52428800
  file_path TEXT NOT NULL,          -- R2 object key
  status TEXT NOT NULL CHECK(status IN ('PENDING', 'PROCESSING', 'COMPLETED', 'FAILED')),
  uploaded_at TEXT NOT NULL,        -- ISO-8601
  processed_at TEXT,                -- ISO-8601, nullable
  error_message TEXT,               -- nullable
  FOREIGN KEY (user_id) REFERENCES users(id)
);

CREATE INDEX idx_cv_analyses_user_id ON cv_analyses(user_id);
CREATE INDEX idx_cv_analyses_status ON cv_analyses(status);
CREATE INDEX idx_cv_analyses_uploaded_at ON cv_analyses(uploaded_at DESC);

Migration Strategy

  • Use D1 migrations directory: migrations/
  • Sequential numbering: 0001_initial.sql, 0002_add_error_tracking.sql
  • Apply via wrangler d1 execute

4. Deployment View

┌─────────────────────────────────────────────────────┐
│              Cloudflare Global Network              │
├─────────────────────────────────────────────────────┤
│                                                     │
│  ┌──────────────────────────────────────────────┐  │
│  │  Edge Locations (300+)                       │  │
│  │                                              │  │
│  │  ┌────────────┐  ┌────────────┐            │  │
│  │  │ API Worker │  │ Processing │            │  │
│  │  │ (Deployed) │  │   Worker   │            │  │
│  │  └────────────┘  └────────────┘            │  │
│  └──────────────────────────────────────────────┘  │
│                                                     │
│  Regional Resources:                               │
│  ┌────────────┐  ┌────────────┐  ┌────────────┐  │
│  │     D1     │  │     R2     │  │   Queues   │  │
│  │  (Europe)  │  │   (Auto)   │  │  (Europe)  │  │
│  └────────────┘  └────────────┘  └────────────┘  │
└─────────────────────────────────────────────────────┘

              ↑ HTTPS (TLS 1.3)

        ┌──────────┐
        │   User   │
        └──────────┘

Deployment Properties

  • Region: Europe (GDPR compliance - ADR-020)
  • TLS: 1.3 (minimum)
  • Cold start: < 5ms (Workers advantage)
  • Scaling: Automatic, per-request

5. Integration Map

From contracts/ and workflows/:

Synchronous Integrations

None (all external calls are async via queues)

Asynchronous Integrations

  • cv.uploaded event → Processing Worker
  • cv.completed event → Notification Service (future FASE)

Event Flow

POST /api/v1/pdfs → API Worker
  ↓ (creates)
CVAnalysis(PENDING)
  ↓ (publishes)
cv.uploaded event → Queue
  ↓ (consumed by)
Processing Worker
  ↓ (updates)
CVAnalysis(COMPLETED)

6. Security Architecture

From spec/nfr/SECURITY.md and ADR-003:

Authentication

  • Method: JWT Bearer tokens (ADR-003)
  • Provider: Cloudflare Access or external IdP
  • Token expiry: 15 minutes
  • Refresh: Via refresh tokens (30 days)

Authorization

  • Model: Attribute-Based Access Control (ABAC)
  • Rules: User can only access their own CVAnalysis entities
  • Enforcement: Middleware in API Worker

Data Protection

  • At rest: AES-256 (R2 default)
  • In transit: TLS 1.3 (Cloudflare edge)
  • PII: File names and content are encrypted

Audit Logging

  • Events: All API calls, state transitions
  • Storage: Cloudflare Logs (ADR-022)
  • Retention: 90 days

## C4 model levels

<ResponseField name="Level 1: System Context" type="diagram">
  Shows the system boundary, external actors, and external systems. Answers: "What does the system do and who uses it?"
</ResponseField>

<ResponseField name="Level 2: Container Diagram" type="diagram">
  Shows high-level technology choices: applications, databases, queues. Answers: "What are the major technology building blocks?"
</ResponseField>

<ResponseField name="Level 3: Component Diagram" type="diagram">
  Shows components within a container: modules, classes, bounded contexts. Answers: "How is the container structured internally?"
</ResponseField>

<ResponseField name="Level 4: Code" type="optional">
  Class diagrams, sequence diagrams. Usually generated from code, not documented in ARCHITECTURE.md.
</ResponseField>

## Tools

### Generation

```bash
# Generate all architecture artifacts
/sdd:plan-architect

# Regenerate FASEs after spec changes
/sdd:plan-architect --regenerate-fases

# Regenerate specific affected FASEs
/sdd:plan-architect --regenerate-fases --affected=1,5

# Audit FASE coverage
/sdd:plan-architect --audit-fases

Validation

The plan-architect skill runs 6 validation checks:
CheckWhatAgainst
V1: UC CoverageEvery UC in FASE files has guidance in planFASE files ↔ PLAN-FASE-*.md
V2: ADR ComplianceEvery ADR decision reflected in architecturespec/adr/ ↔ ARCHITECTURE.md
V3: NFR StrategiesEvery NFR has implementation strategyspec/nfr/ ↔ PLAN.md
V4: INV EnforcementEvery invariant has enforcement mechanismdomain/05-INVARIANTS.md ↔ PLAN.md
V5: FASE CompletenessEvery FASE has corresponding plan fileplan/fases/ ↔ plan/fase-plans/
V6: No Orphan DecisionsEvery CLARIFY-LOG decision used in planCLARIFY-LOG.md ↔ PLAN.md
  • Skills: /sdd:plan-architect, /sdd:task-generator
  • Upstream: Specifications in spec/
  • Downstream: Tasks in task/
  • SWEBOK: Chapter 02 (Software Design)
  • References: architecture-patterns.md, fase-template.md, plan-templates.md

Build docs developers (and LLMs) love