Skip to content

Commit 6ef5de1

Browse files
committed
docs(plugins): functorium-develop AI 에이전트 plugin docs 옛 명명 정리
직전 트랙(496ac90, c312930)과 동일 sed 패턴으로 plugin 디렉토리의 SKILL.md·references/*.md 옛 명명을 v1.0.0-alpha.4+ 신규 명명으로 통일. 대상 (7 파일): - skills/adapter-develop/references/repository-patterns.md - skills/application-develop/references/usecase-patterns.md - skills/domain-develop/references/pattern-catalog.md - skills/domain-develop/references/type-strategy.md - skills/domain-develop/SKILL.md - skills/domain-review/SKILL.md - skills/test-develop/references/unit-test-patterns.md 치환 패턴: - DomainErrorType / ApplicationErrorType / AdapterErrorType → *Kind - ErrorCodeExpected → ExpectedError - ErrorCodeExceptional → ExceptionalError - DomainErrors.{ClassName} → Domain.{ClassName} (출력 prefix만) 전체 잔존 grep 결과 0건. AI 에이전트는 SKILL.md 텍스트를 그대로 인용하므로 sed 갱신만으로 응답이 신규 명명과 일관됨.
1 parent 81b84cd commit 6ef5de1

11 files changed

Lines changed: 886 additions & 886 deletions

File tree

Lines changed: 124 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,124 @@
1-
---
2-
name: adapter-develop
3-
description: "Functorium 프레임워크 기반 어댑터 레이어(Repository, Query Adapter, Endpoint, DI 등록)를 구현합니다. 'Repository 구현', '어댑터 추가', '엔드포인트 만들어줘', 'DI 등록', 'EF Core 설정', 'Dapper 쿼리' 등의 요청에 반응합니다."
4-
---
5-
6-
## 선행 조건
7-
8-
`application-develop` 스킬에서 생성한 `application/03-implementation-results.md`를 읽어 Port 목록(IRepository, IQueryPort, External Service)을 확인합니다.
9-
`architecture-design` 스킬에서 생성한 `01-architecture-design.md`가 있으면 읽어 폴더 구조와 영속성 전략을 확인합니다.
10-
11-
## 후속 스킬
12-
13-
```
14-
project-spec → architecture-design → domain-develop → application-develop → **adapter-develop** → observability-develop → test-develop
15-
```
16-
17-
어댑터 구현 완료 후 `observability-develop` 스킬에서 관측성 전략(KPI→메트릭 매핑, 대시보드, 알림, ctx.* 전파)을 설계합니다.
18-
19-
# Adapter Develop Skill
20-
21-
Functorium 프레임워크 기반 어댑터 레이어를 구현하는 스킬입니다.
22-
23-
## 워크플로우
24-
25-
### Phase 1: 포트 → 어댑터 매핑
26-
27-
사용자에게 질문:
28-
- 어떤 포트를 구현할까요? (IRepository, IQueryPort, External API, Endpoint)
29-
- 영속성 전략은? (EF Core, InMemory, Dapper)
30-
- Soft Delete가 필요한가?
31-
32-
### Phase 2: 어댑터 구현
33-
34-
**Repository (Write Side):**
35-
- `[GenerateObservablePort]` 어트리뷰트 적용
36-
- `EfCoreRepositoryBase<TAgg, TId, TModel>` 상속
37-
- `ToDomain` / `ToModel` 매퍼 구현
38-
- `DbContext`, `DbSet` 오버라이드
39-
- `PropertyMap`으로 Specification 매핑
40-
- Include 선언 (N+1 방지)
41-
- `InMemoryRepositoryBase<TAgg, TId>` 상속 (테스트용)
42-
- 모든 메서드 `virtual` (Source Generator 파이프라인 필수)
43-
44-
**Query Adapter (Read Side / CQRS):**
45-
- `DapperQueryBase<TEntity, TDto>` 상속
46-
- `SelectSql`, `CountSql`, `DefaultOrderBy`, `AllowedSortColumns` 오버라이드
47-
- `DapperSpecTranslator` 구현
48-
- `InMemoryQueryBase<TEntity, TDto>` 상속 (테스트용)
49-
50-
**Endpoint (Presentation):**
51-
- FastEndpoints의 `Endpoint<TRequest, TResponse>` 상속
52-
- `IMediator.Send()``FinResponse` 매핑
53-
- `SendCreatedFinResponseAsync` / `SendFinResponseAsync`
54-
55-
**External API:**
56-
- `IObservablePort` 구현
57-
- `IO.liftAsync` + try/catch
58-
- `AdapterError.For` / `AdapterError.FromException`
59-
60-
상세 패턴은 references 파일을 읽으세요.
61-
62-
### ObservableSignal — Adapter 내부 개발자 로깅
63-
64-
`ObservableSignal`은 Adapter 구현 코드 내부에서 개발자가 직접 운영 목적의 로그를 출력하는 정적 API입니다.
65-
Observable 래퍼가 설정한 공통 컨텍스트(`request.layer`, `request.category.name`, `request.handler.name`, `request.handler.method`)를 자동으로 포함합니다.
66-
67-
**Pillar 범위:**
68-
- Debug → Logging만 (고빈도 → Tracing 노이즈 방지)
69-
- Warning/Error → Logging + Activity Event
70-
71-
**로그 수준 가이드:**
72-
| Level | 용도 | 예시 |
73-
|-------|------|------|
74-
| Debug | 정상 흐름 상세 (프로덕션 비활성) | 캐시 미스, 쿼리 상세 |
75-
| Warning | 자동 복구 가능한 열화 | Polly 재시도, rate limit, 느린 쿼리 |
76-
| Error | 복구 불가 실패 | 재시도 소진, 서킷 오픈, DLQ 이동 |
77-
78-
**사용 예시:**
79-
```csharp
80-
// Polly 재시도 시
81-
ObservableSignal.Warning("Retry attempt {Attempt}/{MaxRetry}",
82-
("adapter.retry.attempt", attempt),
83-
("adapter.retry.delay_ms", delay.TotalMilliseconds));
84-
85-
// 캐시 미스 시
86-
ObservableSignal.Debug("Cache miss", ("adapter.cache.key", cacheKey));
87-
88-
// 재시도 소진 시
89-
ObservableSignal.Error(ex, "Database operation failed after exhausting retries",
90-
("adapter.db.retry.attempt", maxRetries));
91-
```
92-
93-
**부가 필드 프리픽스**: `adapter.*` (adapter.retry.*, adapter.http.*, adapter.db.*, adapter.cache.*, adapter.message.*)
94-
95-
### CtxEnricherPipeline
96-
`CtxEnricherPipeline`은 파이프라인 최선두에서 `IUsecaseCtxEnricher`를 호출하여
97-
`ctx.*` 필드를 Logging/Tracing/MetricsTag에 동시 전파합니다.
98-
99-
Adapter 초기화에서 `CtxEnricherContext.SetPushFactory`를 등록하여
100-
Serilog LogContext + Activity.SetTag + MetricsTagContext를 통합합니다.
101-
102-
Observable Port의 `RequestCategory` 예시:
103-
- Repository → `"repository"`
104-
- QueryAdapter → `"query"`
105-
- ExternalApi → `"external_api"`
106-
- UnitOfWork → `"unit_of_work"`
107-
108-
### Phase 3: DI 등록
109-
110-
- `RegisterScopedObservablePort<IPort, AdapterObservable>()`
111-
- `RegisterConfigureOptions<TOptions, TValidator>()`
112-
- Provider 분기 (InMemory vs Sqlite)
113-
114-
### Phase 4: 구현
115-
116-
.cs 파일 생성 + EF Core Configuration
117-
118-
**출력:** `{context}/adapter/` 폴더에 4단계 문서 + 소스 코드
119-
120-
## References
121-
122-
- Repository 패턴: `references/repository-patterns.md`
123-
- Endpoint 패턴: `references/endpoint-patterns.md`
124-
- DI 등록 패턴: `references/di-registration.md`
1+
---
2+
name: adapter-develop
3+
description: "Functorium 프레임워크 기반 어댑터 레이어(Repository, Query Adapter, Endpoint, DI 등록)를 구현합니다. 'Repository 구현', '어댑터 추가', '엔드포인트 만들어줘', 'DI 등록', 'EF Core 설정', 'Dapper 쿼리' 등의 요청에 반응합니다."
4+
---
5+
6+
## 선행 조건
7+
8+
`application-develop` 스킬에서 생성한 `application/03-implementation-results.md`를 읽어 Port 목록(IRepository, IQueryPort, External Service)을 확인합니다.
9+
`architecture-design` 스킬에서 생성한 `01-architecture-design.md`가 있으면 읽어 폴더 구조와 영속성 전략을 확인합니다.
10+
11+
## 후속 스킬
12+
13+
```
14+
project-spec → architecture-design → domain-develop → application-develop → **adapter-develop** → observability-develop → test-develop
15+
```
16+
17+
어댑터 구현 완료 후 `observability-develop` 스킬에서 관측성 전략(KPI→메트릭 매핑, 대시보드, 알림, ctx.* 전파)을 설계합니다.
18+
19+
# Adapter Develop Skill
20+
21+
Functorium 프레임워크 기반 어댑터 레이어를 구현하는 스킬입니다.
22+
23+
## 워크플로우
24+
25+
### Phase 1: 포트 → 어댑터 매핑
26+
27+
사용자에게 질문:
28+
- 어떤 포트를 구현할까요? (IRepository, IQueryPort, External API, Endpoint)
29+
- 영속성 전략은? (EF Core, InMemory, Dapper)
30+
- Soft Delete가 필요한가?
31+
32+
### Phase 2: 어댑터 구현
33+
34+
**Repository (Write Side):**
35+
- `[GenerateObservablePort]` 어트리뷰트 적용
36+
- `EfCoreRepositoryBase<TAgg, TId, TModel>` 상속
37+
- `ToDomain` / `ToModel` 매퍼 구현
38+
- `DbContext`, `DbSet` 오버라이드
39+
- `PropertyMap`으로 Specification 매핑
40+
- Include 선언 (N+1 방지)
41+
- `InMemoryRepositoryBase<TAgg, TId>` 상속 (테스트용)
42+
- 모든 메서드 `virtual` (Source Generator 파이프라인 필수)
43+
44+
**Query Adapter (Read Side / CQRS):**
45+
- `DapperQueryBase<TEntity, TDto>` 상속
46+
- `SelectSql`, `CountSql`, `DefaultOrderBy`, `AllowedSortColumns` 오버라이드
47+
- `DapperSpecTranslator` 구현
48+
- `InMemoryQueryBase<TEntity, TDto>` 상속 (테스트용)
49+
50+
**Endpoint (Presentation):**
51+
- FastEndpoints의 `Endpoint<TRequest, TResponse>` 상속
52+
- `IMediator.Send()``FinResponse` 매핑
53+
- `SendCreatedFinResponseAsync` / `SendFinResponseAsync`
54+
55+
**External API:**
56+
- `IObservablePort` 구현
57+
- `IO.liftAsync` + try/catch
58+
- `AdapterError.For` / `AdapterError.FromException`
59+
60+
상세 패턴은 references 파일을 읽으세요.
61+
62+
### ObservableSignal — Adapter 내부 개발자 로깅
63+
64+
`ObservableSignal`은 Adapter 구현 코드 내부에서 개발자가 직접 운영 목적의 로그를 출력하는 정적 API입니다.
65+
Observable 래퍼가 설정한 공통 컨텍스트(`request.layer`, `request.category.name`, `request.handler.name`, `request.handler.method`)를 자동으로 포함합니다.
66+
67+
**Pillar 범위:**
68+
- Debug → Logging만 (고빈도 → Tracing 노이즈 방지)
69+
- Warning/Error → Logging + Activity Event
70+
71+
**로그 수준 가이드:**
72+
| Level | 용도 | 예시 |
73+
|-------|------|------|
74+
| Debug | 정상 흐름 상세 (프로덕션 비활성) | 캐시 미스, 쿼리 상세 |
75+
| Warning | 자동 복구 가능한 열화 | Polly 재시도, rate limit, 느린 쿼리 |
76+
| Error | 복구 불가 실패 | 재시도 소진, 서킷 오픈, DLQ 이동 |
77+
78+
**사용 예시:**
79+
```csharp
80+
// Polly 재시도 시
81+
ObservableSignal.Warning("Retry attempt {Attempt}/{MaxRetry}",
82+
("adapter.retry.attempt", attempt),
83+
("adapter.retry.delay_ms", delay.TotalMilliseconds));
84+
85+
// 캐시 미스 시
86+
ObservableSignal.Debug("Cache miss", ("adapter.cache.key", cacheKey));
87+
88+
// 재시도 소진 시
89+
ObservableSignal.Error(ex, "Database operation failed after exhausting retries",
90+
("adapter.db.retry.attempt", maxRetries));
91+
```
92+
93+
**부가 필드 프리픽스**: `adapter.*` (adapter.retry.*, adapter.http.*, adapter.db.*, adapter.cache.*, adapter.message.*)
94+
95+
### CtxEnricherPipeline
96+
`CtxEnricherPipeline`은 파이프라인 최선두에서 `IUsecaseCtxEnricher`를 호출하여
97+
`ctx.*` 필드를 Logging/Tracing/MetricsTag에 동시 전파합니다.
98+
99+
Adapter 초기화에서 `CtxEnricherContext.SetPushFactory`를 등록하여
100+
Serilog LogContext + Activity.SetTag + MetricsTagContext를 통합합니다.
101+
102+
Observable Port의 `RequestCategory` 예시:
103+
- Repository → `"repository"`
104+
- QueryAdapter → `"query"`
105+
- ExternalApi → `"external_api"`
106+
- UnitOfWork → `"unit_of_work"`
107+
108+
### Phase 3: DI 등록
109+
110+
- `RegisterScopedObservablePort<IPort, AdapterObservable>()`
111+
- `RegisterConfigureOptions<TOptions, TValidator>()`
112+
- Provider 분기 (InMemory vs Sqlite)
113+
114+
### Phase 4: 구현
115+
116+
.cs 파일 생성 + EF Core Configuration
117+
118+
**출력:** `{context}/adapter/` 폴더에 4단계 문서 + 소스 코드
119+
120+
## References
121+
122+
- Repository 패턴: `references/repository-patterns.md`
123+
- Endpoint 패턴: `references/endpoint-patterns.md`
124+
- DI 등록 패턴: `references/di-registration.md`

0 commit comments

Comments
 (0)