# Low-Level Design (LLD)

# Low-Level Design Document

> **Project:** {{PROJECT_NAME}}
> **Module/Component:** {{MODULE_NAME}}
> **Version:** {{VERSION}}
> **Date:** {{DATE}}
> **Author:** {{AUTHOR}}
> **Status:** Draft | In Review | Approved
> **Reviewers:** {{REVIEWERS}}
> **Related HLD:** [HLD Document](./hld.md)

## Document History
| Version | Date | Author | Changes |
|---------|------|--------|---------|
| 0.1     | {{DATE}} | {{AUTHOR}} | Initial draft |

---

## 1. Module Overview

<!-- GUIDANCE: Clearly state what this module/component is responsible for. What business function does it serve? What are its boundaries — what does it own and what does it NOT own? -->

**Module:** `{{MODULE_NAME}}`
**Service/Repo:** `{{REPO_NAME}}`
**Team Owner:** {{TEAM_NAME}}

**Single Responsibility:** {{ONE_SENTENCE_WHAT_THIS_MODULE_DOES}}

**Boundaries:**
- **Owns:** {{WHAT_THIS_MODULE_OWNS}}
- **Does NOT own:** {{WHAT_THIS_MODULE_DOES_NOT_OWN}}
- **Delegates to:** {{WHAT_IT_DELEGATES}}

**Key Business Rules:**
1. {{BUSINESS_RULE_1}}
2. {{BUSINESS_RULE_2}}
3. {{BUSINESS_RULE_3}}

---

## 2. Class / Module Diagram

<!-- GUIDANCE: Show the internal structure of this module. Include classes, interfaces, enums, and their relationships. Use classDiagram notation. -->

```mermaid
classDiagram
    class {{ServiceClassName}} {
        -repository: {{RepositoryInterface}}
        -eventBus: EventBus
        -logger: Logger
        +create(dto: Create{{Entity}}Dto): Promise~{{Entity}}~
        +findById(id: string): Promise~{{Entity}} | null~
        +findAll(filter: {{Filter}}Dto): Promise~PaginatedResult~{{Entity}}~~
        +update(id: string, dto: Update{{Entity}}Dto): Promise~{{Entity}}~
        +delete(id: string): Promise~void~
        -validate(dto: unknown): void
        -publishEvent(event: {{DomainEvent}}): Promise~void~
    }

    class {{RepositoryInterface}} {
        <<interface>>
        +findById(id: string): Promise~{{Entity}} | null~
        +findMany(filter: {{Filter}}): Promise~{{Entity}}[]~
        +create(data: Partial~{{Entity}}~): Promise~{{Entity}}~
        +update(id: string, data: Partial~{{Entity}}~): Promise~{{Entity}}~
        +delete(id: string): Promise~void~
        +count(filter: {{Filter}}): Promise~number~
    }

    class {{Entity}} {
        +id: string
        +createdAt: Date
        +updatedAt: Date
        +deletedAt: Date | null
        {{FIELD_1}}: {{TYPE_1}}
        {{FIELD_2}}: {{TYPE_2}}
        +isDeleted(): boolean
        +toJSON(): {{EntityJSON}}
    }

    class Create{{Entity}}Dto {
        {{FIELD_1}}: {{TYPE_1}}
        {{FIELD_2}}: {{TYPE_2}}
    }

    class {{Controller}} {
        -service: {{ServiceClassName}}
        +POST /{{resource}}(body: Create{{Entity}}Dto): Response
        +GET /{{resource}}/:id(): Response
        +GET /{{resource}}(query: {{Filter}}Dto): Response
        +PUT /{{resource}}/:id(body: Update{{Entity}}Dto): Response
        +DELETE /{{resource}}/:id(): Response
    }

    {{ServiceClassName}} --> {{RepositoryInterface}}
    {{ServiceClassName}} --> {{Entity}}
    {{Controller}} --> {{ServiceClassName}}
    {{RepositoryInterface}} ..> {{Entity}}
```

---

## 3. Database Schema

<!-- GUIDANCE: Define every table/collection this module owns. Be precise about types, nullability, defaults, constraints. Include all indexes with rationale. -->

### 3.1 Tables

#### `{{TABLE_NAME_1}}`

<!-- GUIDANCE: Describe the purpose of this table. -->
**Purpose:** {{TABLE_PURPOSE}}

| Column | Type | Nullable | Default | Constraints | Description |
|--------|------|----------|---------|-------------|-------------|
| `id` | `UUID` | NO | `gen_random_uuid()` | PK | Primary key |
| `created_at` | `TIMESTAMPTZ` | NO | `NOW()` | | Record creation timestamp |
| `updated_at` | `TIMESTAMPTZ` | NO | `NOW()` | | Last update timestamp |
| `deleted_at` | `TIMESTAMPTZ` | YES | `NULL` | | Soft delete timestamp |
| `{{COLUMN_1}}` | `{{TYPE}}` | {{YES/NO}} | `{{DEFAULT}}` | {{CONSTRAINTS}} | {{DESCRIPTION}} |
| `{{COLUMN_2}}` | `{{TYPE}}` | {{YES/NO}} | `{{DEFAULT}}` | {{CONSTRAINTS}} | {{DESCRIPTION}} |
| `{{FK_COLUMN}}` | `UUID` | NO | | FK → `{{OTHER_TABLE}}(id)` | Reference to {{OTHER_TABLE}} |

**Indexes:**
| Index Name | Columns | Type | Rationale |
|-----------|---------|------|-----------|
| `{{TABLE_NAME_1}}_pkey` | `id` | B-tree (PK) | Primary key lookup |
| `idx_{{TABLE_NAME_1}}_{{COLUMN}}` | `{{COLUMN}}` | B-tree | {{QUERY_RATIONALE}} |
| `idx_{{TABLE_NAME_1}}_deleted_at` | `deleted_at` | Partial (WHERE deleted_at IS NULL) | Soft-delete filter performance |

#### `{{TABLE_NAME_2}}`

**Purpose:** {{TABLE_PURPOSE}}

| Column | Type | Nullable | Default | Constraints | Description |
|--------|------|----------|---------|-------------|-------------|
| `id` | `UUID` | NO | `gen_random_uuid()` | PK | Primary key |
| `{{COLUMN_1}}` | `{{TYPE}}` | {{YES/NO}} | `{{DEFAULT}}` | {{CONSTRAINTS}} | {{DESCRIPTION}} |

### 3.2 Enums

```sql
CREATE TYPE {{ENUM_NAME}} AS ENUM (
    '{{VALUE_1}}',
    '{{VALUE_2}}',
    '{{VALUE_3}}'
);
```

### 3.3 Migration Notes

<!-- GUIDANCE: Note any migration concerns — zero-downtime requirements, backfills, index creation strategy. -->

- Migration file: `{{MIGRATION_FILE_NAME}}.sql`
- Zero-downtime: {{YES_NO}} — {{NOTES}}
- Backfill required: {{YES_NO}} — {{BACKFILL_STRATEGY}}
- Estimated migration time: {{ESTIMATE}}

---

## 4. API Contract

<!-- GUIDANCE: Define every endpoint this module exposes. Be complete — include all error codes, not just success cases. -->

**Base Path:** `/api/v{{VERSION}}/{{RESOURCE}}`

### `POST /{{resource}}`

**Summary:** Create a new {{entity}}

**Authentication:** Bearer JWT required

**Request Body:**
```json
{
  "{{field1}}": "{{type_and_example}}",
  "{{field2}}": "{{type_and_example}}"
}
```

**Success Response — `201 Created`:**
```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "{{field1}}": "{{value}}",
  "createdAt": "2024-01-01T00:00:00.000Z"
}
```

**Error Responses:**
| Status | Code | Description |
|--------|------|-------------|
| `400` | `VALIDATION_ERROR` | Request body fails validation |
| `401` | `UNAUTHORIZED` | Missing or invalid JWT |
| `403` | `FORBIDDEN` | Insufficient permissions |
| `409` | `CONFLICT` | {{DUPLICATE_FIELD}} already exists |
| `422` | `BUSINESS_RULE_VIOLATION` | {{BUSINESS_RULE}} not met |
| `500` | `INTERNAL_ERROR` | Unexpected server error |

---

### `GET /{{resource}}/:id`

**Summary:** Retrieve a {{entity}} by ID

**Path Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | `UUID` | The {{entity}} identifier |

**Success Response — `200 OK`:**
```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "{{field1}}": "{{value}}",
  "createdAt": "2024-01-01T00:00:00.000Z"
}
```

**Error Responses:**
| Status | Code | Description |
|--------|------|-------------|
| `401` | `UNAUTHORIZED` | Missing or invalid JWT |
| `404` | `NOT_FOUND` | {{entity}} not found |

---

### `GET /{{resource}}`

**Summary:** List {{entities}} with pagination and filtering

**Query Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `page` | `integer` | `1` | Page number (1-based) |
| `limit` | `integer` | `20` | Items per page (max: 100) |
| `sort` | `string` | `createdAt:desc` | Sort field and direction |
| `{{filter1}}` | `{{type}}` | — | Filter by {{filter1}} |

**Success Response — `200 OK`:**
```json
{
  "data": [],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 0,
    "totalPages": 0
  }
}
```

---

## 5. Algorithm Specifications

<!-- GUIDANCE: For non-trivial algorithms, write pseudocode. This is critical for: pagination cursors, search ranking, pricing calculations, state machine transitions, data transformations. -->

### 5.1 {{ALGORITHM_NAME}}

**Purpose:** {{WHAT_IT_DOES}}
**Complexity:** Time O({{TIME_COMPLEXITY}}) | Space O({{SPACE_COMPLEXITY}})

```pseudocode
function {{algorithmName}}(input: {{InputType}}): {{OutputType}}
    // Step 1: Validate input
    if input is null or invalid then
        throw ValidationError("{{VALIDATION_MESSAGE}}")
    end if

    // Step 2: {{STEP_2_DESCRIPTION}}
    result = initialize()
    for each item in input.items do
        if item.satisfies({{CONDITION}}) then
            result.add(transform(item))
        end if
    end for

    // Step 3: {{STEP_3_DESCRIPTION}}
    sorted = result.sortBy({{SORT_CRITERIA}})

    // Step 4: Apply business rules
    for each rule in {{BUSINESS_RULES}} do
        sorted = rule.apply(sorted)
    end for

    return sorted
end function
```

**Edge Cases:**
- **Empty input:** Return empty result, do not throw
- **Single item:** {{SINGLE_ITEM_BEHAVIOR}}
- **Maximum items:** Limit to {{MAX_ITEMS}}, log warning if exceeded

---

## 6. Sequence Diagrams

<!-- GUIDANCE: Show the interaction between components for the key user flows. One diagram per major flow. -->

### 6.1 Create {{Entity}} Flow

```mermaid
sequenceDiagram
    autonumber
    actor Client
    participant GW as API Gateway
    participant Auth as Auth Middleware
    participant SVC as {{ServiceClassName}}
    participant DB as Database
    participant MQ as Message Queue
    participant Email as Email Service

    Client->>GW: POST /{{resource}} {body}
    GW->>Auth: Validate JWT
    Auth-->>GW: User context {userId, roles}
    GW->>SVC: create(dto, userContext)
    SVC->>SVC: validate(dto)
    alt Validation fails
        SVC-->>Client: 400 ValidationError
    end
    SVC->>DB: BEGIN TRANSACTION
    SVC->>DB: INSERT INTO {{TABLE_NAME_1}}
    DB-->>SVC: {{entity}} record
    SVC->>DB: COMMIT
    SVC->>MQ: publish("{{ENTITY_CREATED_EVENT}}", event)
    MQ->>Email: Trigger confirmation email
    Email-->>Client: Email delivered async
    SVC-->>GW: {{entity}} dto
    GW-->>Client: 201 Created
```

### 6.2 {{SECONDARY_FLOW_NAME}} Flow

```mermaid
sequenceDiagram
    autonumber
    actor Client
    participant SVC as {{ServiceClassName}}
    participant Cache as Redis
    participant DB as Database

    Client->>SVC: GET /{{resource}}/:id
    SVC->>Cache: GET {{resource}}:{{id}}
    alt Cache hit
        Cache-->>SVC: Cached {{entity}}
        SVC-->>Client: 200 OK (from cache)
    else Cache miss
        Cache-->>SVC: null
        SVC->>DB: SELECT * FROM {{TABLE_NAME_1}} WHERE id = $1
        alt Not found
            DB-->>SVC: null
            SVC-->>Client: 404 Not Found
        end
        DB-->>SVC: {{entity}} record
        SVC->>Cache: SET {{resource}}:{{id}} TTL={{CACHE_TTL}}
        SVC-->>Client: 200 OK
    end
```

---

## 7. State Diagrams

<!-- GUIDANCE: For entities with complex lifecycle states, document state transitions. Include every valid transition and the trigger. -->

```mermaid
stateDiagram-v2
    [*] --> {{STATE_DRAFT}} : Created

    {{STATE_DRAFT}} --> {{STATE_PENDING}} : submit()
    {{STATE_DRAFT}} --> [*] : delete()

    {{STATE_PENDING}} --> {{STATE_ACTIVE}} : approve()
    {{STATE_PENDING}} --> {{STATE_REJECTED}} : reject(reason)
    {{STATE_PENDING}} --> {{STATE_DRAFT}} : recall()

    {{STATE_ACTIVE}} --> {{STATE_SUSPENDED}} : suspend(reason)
    {{STATE_ACTIVE}} --> {{STATE_COMPLETED}} : complete()
    {{STATE_ACTIVE}} --> {{STATE_CANCELLED}} : cancel(reason)

    {{STATE_SUSPENDED}} --> {{STATE_ACTIVE}} : reactivate()
    {{STATE_SUSPENDED}} --> {{STATE_CANCELLED}} : cancel(reason)

    {{STATE_REJECTED}} --> {{STATE_DRAFT}} : revise()
    {{STATE_COMPLETED}} --> [*]
    {{STATE_CANCELLED}} --> [*]
```

**State Transition Rules:**
| From | To | Trigger | Guard Condition | Side Effect |
|------|-----|---------|-----------------|-------------|
| DRAFT | PENDING | `submit()` | All required fields populated | Notify reviewers |
| PENDING | ACTIVE | `approve()` | Approver has `{{PERMISSION}}` role | Send welcome email |
| ACTIVE | SUSPENDED | `suspend(reason)` | Admin only | Log audit event |

---

## 8. Error Handling Strategy

<!-- GUIDANCE: How does this module handle errors? Define error types, recovery strategies, and what gets logged/alerted. -->

### 8.1 Error Classification

| Error Type | HTTP Status | Retry? | Log Level | Alert? |
|-----------|------------|--------|-----------|--------|
| ValidationError | 400 | No | INFO | No |
| UnauthorizedError | 401 | No | WARN | No |
| ForbiddenError | 403 | No | WARN | Suspicious patterns only |
| NotFoundError | 404 | No | INFO | No |
| ConflictError | 409 | No | WARN | No |
| ExternalServiceError | 502 | Yes (3x) | ERROR | Yes (if sustained) |
| DatabaseError | 500 | Yes (1x) | ERROR | Yes |
| UnexpectedError | 500 | No | ERROR | Yes |

### 8.2 Error Response Format (RFC 7807)

```json
{
  "type": "https://api.{{DOMAIN}}/errors/{{ERROR_CODE}}",
  "title": "{{Human-readable error title}}",
  "status": 400,
  "detail": "{{Specific error message}}",
  "instance": "/{{resource}}/{{id}}",
  "traceId": "{{TRACE_ID}}"
}
```

### 8.3 Retry & Fallback Strategy

```
External API call failure:
  → Retry with exponential backoff: [1s, 2s, 4s]
  → Max retries: 3
  → Circuit breaker: Open after 5 failures in 60s window
  → Fallback: {{FALLBACK_BEHAVIOR}}
  → Alert: PagerDuty if circuit remains open > 5 minutes
```

---

## 9. Concurrency & Thread Safety

<!-- GUIDANCE: Identify any shared state, concurrent modification risks, or race conditions. Document the mitigation for each. -->

| Concern | Scenario | Mitigation |
|---------|----------|------------|
| Duplicate creation | Two requests create same {{entity}} simultaneously | Unique constraint on `{{UNIQUE_FIELD}}` + catch constraint error → 409 |
| Optimistic locking | Two updates to same record | `version` column + check-and-increment |
| Race condition in {{FLOW}} | {{RACE_CONDITION_DESCRIPTION}} | {{MITIGATION}} (e.g., DB-level lock, Redis SETNX) |

---

## 10. Performance Considerations

<!-- GUIDANCE: What are the performance targets for this module? What optimizations are in place? What are the known bottlenecks? -->

| Operation | Target (p99) | Current Baseline | Optimization |
|-----------|-------------|-----------------|--------------|
| `GET /{{resource}}/:id` | < 50ms | {{BASELINE}} | Redis cache (TTL={{TTL}}) |
| `GET /{{resource}}` (list) | < 200ms | {{BASELINE}} | Indexed query + cursor pagination |
| `POST /{{resource}}` | < 300ms | {{BASELINE}} | Async event publishing |
| Bulk import (1000 items) | < 5s | {{BASELINE}} | Batch insert in chunks of 100 |

**Known bottlenecks:**
- {{BOTTLENECK_1}}: {{MITIGATION}}
- {{BOTTLENECK_2}}: {{MITIGATION}}

---

## 11. Dependencies

<!-- GUIDANCE: List every internal and external dependency this module requires. Note the version and what happens if the dependency is unavailable. -->

### Internal Dependencies
| Dependency | Type | Purpose | Fallback if unavailable |
|-----------|------|---------|------------------------|
| `{{INTERNAL_SERVICE_1}}` | Synchronous | {{PURPOSE}} | {{FALLBACK}} |
| `{{SHARED_LIB}}` | Library | {{PURPOSE}} | N/A (required) |

### External Dependencies
| Dependency | Version | Purpose | Fallback if unavailable |
|-----------|---------|---------|------------------------|
| PostgreSQL | `{{VERSION}}` | Primary data store | None — module unavailable |
| Redis | `{{VERSION}}` | Caching + session | Degrade gracefully (skip cache) |
| `{{EXTERNAL_API}}` | `v{{VERSION}}` | {{PURPOSE}} | {{FALLBACK}} |

---

## 12. Configuration Parameters

<!-- GUIDANCE: Every environment variable or configuration value this module reads. Include type, default, and whether it's required. -->

| Variable | Type | Default | Required | Description |
|---------|------|---------|----------|-------------|
| `{{MODULE_NAME}}_MAX_PAGE_SIZE` | `integer` | `100` | No | Maximum items per page |
| `{{MODULE_NAME}}_CACHE_TTL_SECONDS` | `integer` | `300` | No | Cache TTL in seconds |
| `{{MODULE_NAME}}_RETRY_ATTEMPTS` | `integer` | `3` | No | External API retry count |
| `{{EXTERNAL_API_KEY_VAR}}` | `string` | — | Yes | API key for {{EXTERNAL_SERVICE}} |
| `{{DB_CONNECTION_VAR}}` | `string` | — | Yes | Database connection string |

---

## 13. Testing Approach

<!-- GUIDANCE: How is this module tested? List test types, tools, and coverage targets. -->

| Test Type | Tool | Coverage Target | Location |
|-----------|------|-----------------|----------|
| Unit tests | Jest / Vitest | > {{UNIT_COVERAGE}}% | `src/{{module}}/__tests__/unit/` |
| Integration tests | Supertest + TestContainers | Key flows | `src/{{module}}/__tests__/integration/` |
| Contract tests | Pact | All public APIs | `src/{{module}}/__tests__/contract/` |

**Key test scenarios:**
- [ ] Create {{entity}} — success path
- [ ] Create {{entity}} — validation error (missing required field)
- [ ] Create {{entity}} — conflict (duplicate {{UNIQUE_FIELD}})
- [ ] Get {{entity}} by ID — found
- [ ] Get {{entity}} by ID — not found (404)
- [ ] List {{entities}} — with filters, pagination, sorting
- [ ] Update {{entity}} — success
- [ ] Update {{entity}} — not found
- [ ] Delete {{entity}} — success (soft delete)
- [ ] State transition — valid transition
- [ ] State transition — invalid transition (guard fails)
- [ ] External service failure — circuit breaker triggers
- [ ] Concurrent creation — duplicate constraint handled

---

## Approval
| Role | Name | Date | Signature |
|------|------|------|-----------|
| Author | | | |
| Module Owner | | | |
| Security Review | | | |
| Tech Lead | | | |