---
title: Target Architecture
---

# Target Architecture - Clean Architecture

## Layer Overview

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                              FRAMEWORKS & DRIVERS                           │
│                                                                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐        │
│  │   Fastify   │  │   p-queue   │  │  Claude CLI │  │  glab / gh  │        │
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘        │
│                                                                             │
│  src/frameworks/                                                            │
│  ├── claude/         # Claude CLI wrapper                                   │
│  ├── queue/          # p-queue adapter                                      │
│  ├── config/         # Config loader                                        │
│  ├── logging/        # Log buffer                                           │
│  └── settings/       # Runtime settings                                     │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                            INTERFACE ADAPTERS                               │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                          CONTROLLERS                                 │   │
│  │  webhook/           http/              websocket/                    │   │
│  │  ├── gitlab         ├── health         └── progress                  │   │
│  │  └── github         ├── reviews                                      │   │
│  │                     ├── stats                                        │   │
│  │                     ├── insights                                     │   │
│  │                     ├── version                                      │   │
│  │                     └── mrTracking                                   │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                           PRESENTERS                                 │   │
│  │  reviewAction.presenter.ts      # stdout → ReviewAction[]            │   │
│  │  reviewOutput.presenter.ts      # stdout → ReviewStats               │   │
│  │  statsSummary.presenter.ts      # ProjectStats → ViewModel           │   │
│  │  insights.presenter.ts          # DeveloperInsight[] → ViewModel     │   │
│  │  jobStatus.presenter.ts         # Job → ViewModel                    │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                            GATEWAYS                                  │   │
│  │                                                                      │   │
│  │  cli/                          fileSystem/                           │   │
│  │  ├── command.cli.gateway       ├── reviewStats.fileSystem            │   │
│  │  ├── reviewAction.cli.gateway  ├── reviewFile.fileSystem             │   │
│  │  └── selfUpdate.cli.gateway    ├── reviewRequestTracking.fileSystem  │   │
│  │                                └── insights.fileSystem               │   │
│  │                                                                      │   │
│  │  api/                                                                │   │
│  │  ├── threadFetch.gitlab.gateway                                      │   │
│  │  └── threadFetch.github.gateway                                      │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                            ADAPTERS (ACL)                            │   │
│  │  reviewAction.gitlab.adapter   # ReviewAction → glab command         │   │
│  │  reviewAction.github.adapter   # ReviewAction → gh command           │   │
│  │  gitlabMergeRequest.adapter    # GitLab MR → ReviewRequest           │   │
│  │  githubPullRequest.adapter     # GitHub PR → ReviewRequest           │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                            SERVICES                                  │   │
│  │  reviewContextWatcher.service.ts  # Polling service                  │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                              USE CASES                                      │
│                                                                             │
│  src/usecases/                                                              │
│  ├── triggerReview.usecase.ts           # Trigger a review                  │
│  ├── executeInitialReview.usecase.ts    # Execute initial review            │
│  ├── executeFollowUpReview.usecase.ts   # Execute follow-up review          │
│  ├── addReviewStats.usecase.ts          # Add stats after review            │
│  ├── cancelReview.usecase.ts            # Cancel a review                   │
│  ├── handleReviewRequestPush.usecase.ts # Handle push on MR                 │
│  │                                                                          │
│  ├── insights/                                                              │
│  │   ├── computeDeveloperInsights      # Compute per-developer analysis     │
│  │   ├── computeTeamInsights           # Compute team-level analysis        │
│  │   ├── computeInsightsWithPersistence # Incremental insight persistence   │
│  │   ├── generateAiInsights            # AI-powered narrative insights      │
│  │   ├── getInsightsWithAiStatus       # Load insights + AI freshness      │
│  │   └── insightLevelComputation       # Metric normalization & levels      │
│  │                                                                          │
│  ├── stats/                                                                 │
│  │   ├── recalculateProjectStats       # Recalculate from review array      │
│  │   ├── backfillDiffStats             # Backfill missing diff stats        │
│  │   └── recalculateWithBackfill       # Recalculate + backfill orchestration │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                               ENTITIES                                      │
│                                                                             │
│  src/entities/    Each: types + schema + guard + gateway (port)              │
│  ├── reviewAction/       # Actions on MR (ReviewAction union)               │
│  ├── reviewStats/        # Statistics (ReviewStats, ProjectStats)            │
│  ├── insight/            # Developer & team insights, AI insights           │
│  ├── actionExecution/    # ExecutionContext, ExecutionResult                 │
│  ├── reviewContext/      # Review context                                   │
│  ├── reviewRequest/      # Abstract MR/PR                                   │
│  ├── review/             # Review and scoring                               │
│  └── threadFetch/        # Fetch threads                                    │
└─────────────────────────────────────────────────────────────────────────────┘
```

## Data Flow: Initial Review

```
┌──────────────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   GitLab     │     │  Controller  │     │   Use Case   │     │   Gateway    │
│   Webhook    │────►│  (gitlab)    │────►│  trigger     │────►│  (queue)     │
└──────────────┘     └──────────────┘     │  Review      │     └──────────────┘
                                          └──────────────┘
                                                 │
                                                 ▼
┌──────────────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   GitLab     │     │   Gateway    │     │   Use Case   │     │  Framework   │
│   API        │◄────│  (CLI)       │◄────│  execute     │◄────│  (Claude)    │
└──────────────┘     │  reviewAction│     │  Initial     │     └──────────────┘
                     └──────────────┘     │  Review      │
                                          └──────────────┘
                                                 │
                                                 ▼
                                          ┌──────────────┐     ┌──────────────┐
                                          │   Use Case   │     │   Gateway    │
                                          │   addReview  │────►│  (fileSystem)│
                                          │   Stats      │     └──────────────┘
                                          └──────────────┘
```

## Data Flow: Follow-Up Review

Same pattern as Initial Review, triggered by Push Event. Controller checks `state == pending-fix && openThreads > 0` before dispatching to `executeFollowUpReview` use case. Context is loaded from context file instead of being freshly created.

## ReviewAction: Unified Concept

`ReviewAction` is a discriminated union: `THREAD_REPLY` (threadId, message), `THREAD_RESOLVE` (threadId), `POST_COMMENT` (body), `ADD_LABEL` (label), `FETCH_THREADS`. Extensible by adding new types.

## ReviewAction Execution Pattern

```
ReviewActionGateway (interface)
  execute(actions: ReviewAction[], context: ExecutionContext) → ExecutionResult
        │
        ▼
ReviewActionCliGateway (implementation)
        │
   ┌────┴────┐
   ▼         ▼
PlatformAdapter (interface)    CommandExecutorGateway (interface)
  buildCommand(action,           execute(command, args, cwd)
    projectPath, mrNumber)
   │         │                            │
   ▼         ▼                            ▼
GitLab    GitHub                   CLI (execSync)
Adapter   Adapter
```

## Target Folder Structure

```
src/
├── main/                  # Composition root (server, DI, routes, websocket)
├── entities/              # Enterprise Business Rules (reviewAction, reviewStats, etc.)
├── usecases/              # Application Business Rules (trigger, execute, stats)
├── interface-adapters/    # Controllers, Presenters, Gateways, Adapters (ACL)
├── frameworks/            # Frameworks & Drivers (claude, queue, config, logging)
├── shared/                # Cross-cutting concerns (foundation)
├── config/                # (legacy, → frameworks/)
├── security/              # (legacy, → interface-adapters/)
└── server.ts              # (legacy, → main/)
```

**Dependency Rule**: Dependencies ALWAYS point inward (Frameworks → Interface Adapters → Use Cases → Entities).

## Migration Backlog

| Ticket | Description | Dependencies |
|--------|-------------|--------------|
| BACKLOG-010 | Create /frameworks/ | - |
| BACKLOG-011a | Unify ReviewAction entity | - |
| BACKLOG-011b | Create ReviewActionGateway | 011a |
| BACKLOG-011c | Split statsService | - |
| BACKLOG-011d | Migrate reviewContextWatcher | - |
| BACKLOG-011e | Delete /services/ | 010, 011a-d, 013 |
| BACKLOG-013 | Split mrTrackingService | 010 |
