Files
llm-wiki/templates/project-report-template.md
T

280 lines
9.5 KiB
Markdown

---
title: ""
source_type: "report"
status: "draft"
confidence: "unknown"
derived_from:
- "wiki/projects/<canonical-project-doc>"
- "raw/branch-notes/<optional-branch-note>"
related_projects:
- "ca-tmpl"
audience: "self"
purpose: "big-picture-understanding"
last_reviewed: ""
status_label: "draft"
---
# {{title}}
> 이 문서는 이해를 위한 derived report입니다.
> SSOT는 `raw/branch-notes/`와 `wiki/projects/`의 canonical 문서입니다.
> 이 문서는 ca-tmpl 전체 구조를 사람이 읽고 설명할 수 있도록 재구성합니다.
---
## 0. Reading Guide
### 이 문서는 무엇을 설명하는가
`<ca-tmpl 전체 구조, 목표, 핵심 계약, 구현 상태를 설명한다.>`
### 먼저 읽어야 할 사람
- `<ca-tmpl의 큰 그림이 아직 안 잡힌 사람>`
- `<branch-note를 읽기 전에 전체 지도가 필요한 사람>`
- `<Clean Architecture skeleton의 운영 계약이 왜 필요한지 이해하려는 사람>`
### 이 문서를 읽고 답할 수 있어야 하는 질문
- ca-tmpl은 무엇인가?
- 왜 도메인 기능을 제거했는가?
- 왜 운영 계약이 skeleton의 중심인가?
- 왜 branch-note가 많은가?
- 각 branch-note는 전체 skeleton의 어느 영역을 책임지는가?
- 현재 구현된 것과 아직 문서만 있는 것은 무엇인가?
### SSOT
- Canonical:
- `wiki/projects/<canonical-project-doc>`
- Raw / branch notes:
- `raw/branch-notes/<optional-branch-note>`
### 이 문서의 한계
- 이 문서는 SSOT가 아니다.
- 구현 상태는 작성일 기준이다.
- 세부 결정은 각 branch-note와 canonical 문서를 확인해야 한다.
---
## 1. 이 프로젝트는 무엇인가
### 한 문장 정의
> ca-tmpl은 `<새 백엔드 프로젝트를 시작할 때 반복적으로 필요한 운영 계약>`을 Clean Architecture 구조로 미리 고정해두는 skeleton이다.
### 하지 않는 것
- 특정 비즈니스 도메인을 제공하지 않는다.
- 특정 adapter를 무겁게 기본 탑재하지 않는다.
- raw branch-note에서 곧바로 blog/interview/portfolio로 파생하지 않는다.
- 운영 실패, 로그, trace, API envelope, module boundary를 프로젝트마다 임의로 재결정하지 않는다.
### 제공하는 것
- module/package boundary
- structured API response
- operational error category
- exception ownership
- boundary validation / mapper contract
- structured logging / tracing
- env-driven runtime configuration
- repository capability contract
- adapter failure mapping
- architecture test / contract test
- sample domain fixture
### 왜 skeleton인가
`<도메인 기능 자체보다, 도메인을 얹었을 때 동일한 운영 계약과 아키텍처 경계를 유지하는 구조가 목적이기 때문이다.>`
---
## 2. 이 프로젝트가 해결하는 핵심 문제
### 문제 1. 프로젝트마다 실패 처리 방식이 달라지는 문제
- 어떤 프로젝트는 validation 실패를 400으로 반환한다.
- 어떤 프로젝트는 같은 실패를 500으로 반환한다.
- 어떤 프로젝트는 raw exception message를 client에게 노출한다.
- 결과적으로 운영, 디버깅, API contract가 흔들린다.
### 문제 2. Clean Architecture 경계가 문서에만 남고 코드에서 무너지는 문제
- controller가 JPA entity를 직접 반환한다.
- application layer가 Spring/JPA 구현체를 직접 import한다.
- domain이 framework annotation을 알게 된다.
- adapter끼리 직접 참조하면서 순환 결합이 생긴다.
### 문제 3. 관측성 정보가 일관되지 않은 문제
- requestId가 없는 로그가 남는다.
- traceId와 correlationId 의미가 branch마다 다르다.
- 장애 발생 시 어떤 요청에서 어떤 dependency 실패가 났는지 추적하기 어렵다.
### 문제 4. 테스트가 구현 세부만 검증하고 계약 위반을 잡지 못하는 문제
- unit test는 통과하지만 architecture boundary가 깨진다.
- API response schema drift가 생겨도 release 전에 감지하지 못한다.
- contract violation이 warning-only로 남는다.
---
## 3. 전체 구조 요약
| 영역 | 역할 | 왜 필요한가 |
| ------------------- | --------------------------------------------------- | --------------------------------------------------- |
| domain-core | 순수 domain model, value object, domain rule | framework와 adapter로부터 business invariant를 보호 |
| application-core | use case, command/query, port, policy validation | business flow와 외부 구현체 사이의 경계 유지 |
| adapter-web | HTTP DTO, controller, validation, response mapper | 외부 HTTP 요청을 application contract로 변환 |
| adapter-persistence | JPA/RDBMS 저장소 구현, entity, mapper | persistence 기술을 application port 뒤로 숨김 |
| adapter-outbound | HTTP client, messaging, cache, notification adapter | 외부 dependency 세부 구현을 격리 |
| shared-contract | envelope, error code, header/log/metric registry | skeleton-wide operational contract 공유 |
| app-bootstrap | Spring Boot entrypoint, DI wiring, runtime config | composition root로 runtime module을 조립 |
| sample-portfolio | skeleton contract 검증용 fixture | 실제 domain 없이 contract를 검증 |
---
## 4. 핵심 흐름
### 4.1 Request 처리 흐름
```text
HTTP Request
→ adapter-web Request DTO
→ request validation
→ mapper
→ application Command/Query
→ use case
→ domain model / domain rule
→ output port
→ adapter-persistence or adapter-outbound
→ response mapper
→ structured envelope
```
### 4.2 Error 처리 흐름
```text
Exception or failure
→ layer-specific exception ownership
→ operational error mapping
→ error.code / error.category / retryable
→ structured envelope
→ structured log
→ trace correlation
```
### 4.3 Domain Feature 추가 흐름
```text
presentation request/response DTO
→ request mapper
→ application command/query
→ use case
→ input port / output port
→ domain model / value object / domain rule
→ persistence model / repository adapter
→ response mapper
→ contract test
→ architecture rule
```
---
## 5. 주요 계약 묶음
| 계약 영역 | 담당 branch | 설명 | 현재 상태 |
| ---------------------------- | -------------------------- | ---------------------------------------------- | ---------- |
| error / observability | `raw/branch-notes/<...>` | error category, envelope, log/trace 기반 | `<status>` |
| API contract | `raw/branch-notes/<...>` | versioning, pagination, headers, idempotency | `<status>` |
| boundary validation / mapper | `raw/branch-notes/<...>` | DTO → command/query → domain 변환 경계 | `<status>` |
| module/package blueprint | `raw/branch-notes/<...>` | Gradle multi-module, package responsibility | `<status>` |
| transaction / concurrency | `raw/branch-notes/<...>` | transaction boundary, lock, retry, idempotency | `<status>` |
| sample fixture | `raw/branch-notes/<...>` | skeleton contract 검증용 sample domain | `<status>` |
| architecture enforcement | `raw/branch-notes/<...>` | ArchUnit / Gradle dependency guardrail | `<status>` |
---
## 6. 현재 구현 상태
| 영역 | 상태 | 근거 | 남은 위험 |
| -------- | ------------------------------------------------------------------------ | -------------------- | --------- |
| `<영역>` | `<decision-only / documented-only / local-verified / pending / unknown>` | `<문서/코드/테스트>` | `<위험>` |
### 상태 값 정의
| 상태 | 의미 |
| --------------- | ----------------------------------- |
| decision-only | 결정은 있으나 구현/검증은 아직 없음 |
| documented-only | 문서상 계약만 있음 |
| local-verified | 로컬 코드/테스트로 검증됨 |
| pending | 아직 착수 전 또는 잔여 작업 존재 |
| unknown | 근거 부족으로 판단 불가 |
---
## 7. 큰 그림에서 가장 중요한 설계 판단
### 판단 1. `<판단 이름>`
- 결정:
- 이유:
- 대안:
- 선택하지 않은 이유:
- 근거:
- 남은 리스크:
### 판단 2. `<판단 이름>`
- 결정:
- 이유:
- 대안:
- 선택하지 않은 이유:
- 근거:
- 남은 리스크:
---
## 8. 내가 설명할 수 있어야 하는 문장
### 30초 설명
`<ca-tmpl을 30초 안에 설명하는 문장>`
### 2분 설명
`<면접/리뷰/동료 설명에서 말할 수 있는 설명>`
### 깊게 질문받았을 때
**Q. 왜 도메인 기능을 제거했나?**
A. `<답변>`
**Q. 왜 sample-portfolio가 필요한가?**
A. `<답변>`
**Q. 왜 shared-contract가 필요한가?**
A. `<답변>`
**Q. 왜 architecture test가 필요한가?**
A. `<답변>`
---
## 9. 아직 이해가 부족한 부분
| 질문 | 왜 헷갈리는가 | 확인할 문서 | 확인할 코드 |
| ---- | ------------- | ----------- | ----------- |
| | | | |
---
## 10. 다음에 읽을 문서
- `wiki/reports/ca-tmpl/01-module-boundary-report`
- `wiki/reports/ca-tmpl/02-operational-error-observability-report`
- `wiki/reports/ca-tmpl/03-api-contract-report`
- `wiki/reports/ca-tmpl/04-boundary-validation-mapper-report`