내 역할
오케스트레이터가 새로운 기능을 생성할 때 (기존 기능 수정이 아닌) 재사용, 설정, 호환성을 사전 분석하여 안내합니다. 리팩터링과 달리, 보존해야 할 기존 코드가 없습니다: 디자인은 사용자 요구사항에서부터 시작됩니다.
이 스킬을 사용해야 할 때 (refactor-protocol 대신):
- 사용자가 존재하지 않는 엔드포인트, 서비스, 작업, 핸들러, 이벤트 또는 설정을 요청함
- 작업이 순수 생성이며, 기존 동작을 수정하는 것이 아님
- 결과물이 저장소에 새 파일을 추가하며, 기존 파일의 시그니처를 변경하지 않음
이 스킬을 사용하지 말아야 할 때 (대신 refactor-protocol 사용):
- 기존 서비스의 시그니처 수정
- 이미 존재하는 엔드포인트의 동작 변경
- 코드 이름 변경, 추출 또는 이동
0단계 — 구조 검증 (항상 먼저)
project-structure스킬을 로드하고 전체 검증을 실행합니다- 호스트 유형 감지:
FUNCTIONS|WEBAPP|NUGET_LIBRARY - 결과에 따라 조치:
| 상태 | 조치 |
|---|---|
HARD_BLOCK | 중단. 사용자에게 알림. |
NUGET_LIBRARY | HTTP 엔드포인트 생성은 예상치 못한 상황. 질문: "라이브러리에 공개 작업을 추가하시겠습니까, 아니면 감지하지 못한 호스트가 실제로 있습니까?" |
PREGUNTA | 계속 진행하기 전에 질문 해결 |
OK / WARNING | 1단계로 진행 |
1단계 — 요구사항 수집
오케스트레이터는 사용자 설명($ARGUMENTS)에서 최대한 많은 정보를 추론하고, 명확하지 않은 것만 질문합니다. 설명에 이미 답이 있는 질문은 하지 않습니다.
1.1 이름, 목적 및 기능 유형
- HTTP 엔드포인트 (Function/Controller):
[동사] /경로 — 설명 - 도메인 서비스: 서비스 이름 및 책임
- 작업/이벤트 핸들러: 트리거 + 동작
- 설정 옵션: 옵션 이름 및 목적
1.2 READ vs MUTATION 분류
기능이 상태를 변경하는지 읽기 전용인지 결정합니다. 이는 다음에 영향을 줍니다:
- 응답 DTO가 위치할 곳
- 트랜잭션/멱등성 필요 여부
- 필요한 테스트 종류
| 유형 | 특징 | 영향 |
|---|---|---|
| READ-ONLY | GET, 기존 데이터 반환, 쓰기 없음 | 임시 DTO, 최소 테스트 |
| MUTATION | POST/PUT/DELETE, 상태 쓰기 또는 변경 | 성공 + 오류 테스트 필요 |
1.3 예상 입력/출력 수집
- 요청: 본문 또는 쿼리 매개변수 구조
- 응답: 응답 본문 구조, 상태 코드
- 오류: 어떤 오류를 어떤 상태 코드에 매핑해야 하는지
1.5단계 — 재사용 분석 (중요, 건너뛰지 말 것)
목표: 아무것도 생성하기 전에 기능이 부분적으로 또는 완전히 이미 존재하는지 감지합니다.
단계
*.Impl/에서@explore를 사용하여 기능 도메인으로 기존 서비스 검색- 필요한 동작의 80% 이상을 충족하는 후보 메서드 검색:
- 필요한 데이터를 간단한 필터로 이미 반환하는 메서드가 있는가?
- 해당 케이스를 추가하기 위해 오버로드할 수 있는 메서드가 있는가?
*.API/에서 동일한 요청/응답 형태를 가진 유사 엔드포인트 검색
의사 결정 트리
케이스의 100%를 충족하는 메서드가 있는가?
└── 예 → 새 메서드 생성 안 함. 다음만 생성:
· *.API/의 엔드포인트 (Function/Controller)
· *.API/ 전용 DTO 요청/응답
· 응답 형태 테스트
거의 완벽한 메서드가 있는가? (필터, 페이지네이션, 정렬)
├── 예 → 고려:
│ ├── 기존 메서드에 선택적 매개변수 추가 (기본값 포함)
│ ├── 더 구체적인 시그니처로 오버로드 생성
│ └── 기존 메서드를 래핑하는 확장 메서드 생성
└── 아니오 → 새 메서드 생성 계속
관련되지만 다른 서비스가 있는가? (예: 유사한 책임)
├── 예 → 사용자에게 질문: "[CSXxxService]를 확장할까요, 아니면 새 [CSYyyService]를 만들까요?"
└── 아니오 → 새 서비스 생성
이 단계의 예상 출력
다음 세 가지 결정 중 하나를 계속 진행하기 전에 사용자에게 제시:
- 순수 재사용: 기능이 기존 메서드의 래퍼로 구현됨
- 확장: 기존 서비스에 오버로드/메서드 추가
- 새로 생성: 새 서비스 및 메서드 (재사용 불가능 이유 설명)
1.6단계 — 설정 분석 (신규)
목표: 기능에 설정 가능한 매개변수가 필요한지, 필요하다면 어디에 정의할지 감지합니다.
핵심 질문
- 기능에 외부 설정 없이 합리적인 기본값이 있는가?
- 환경별로 설정 가능해야 하는 임계값, 페이지네이션, 시간 제한 또는 플래그가 있는가?
- URL/키/비밀번호가 있는 외부 시스템에 연결하는가?
- 점진적 롤아웃을 위한 기능 플래그가 필요한가?
의사 결정 트리
기능에 설정이 필요한가?
├── 아니오 → IXxxOptions 생성 안 함, AddCustomConfiguration 수정 안 함
└── 예 → 계속
어떤 유형의 설정인가?
├── 연결 문자열 또는 비밀
│ └── appsettings.json에 이름이 있는 IConfiguration 사용 (AddCustomConfiguration에서 관리)
├── 단순 값 (임계값, 시간 제한, 플래그)
│ └── *.Impl/에 IXxxOptions 생성 (인터페이스) + AddCustomConfiguration<T>("key")에 추가
└── 값 목록 (허용된 출처, 매핑)
└── IEnumerable<T> 유형의 속성을 가진 IXxxOptions 생성
프로젝트 규칙
프로젝트는 IoCExtensions.cs (현재 프로젝트의 43-45줄)에서 AddCustomConfiguration<IXxxOptions>("config-section")을 사용합니다. 인터페이스는 *.Impl/에 있으며 *.Impl/Services/에서 참조됩니다.
예상 출력
기능에 설정이 필요한 경우, 사용자에게 다음을 제시:
- 인터페이스 이름 (예:
IPendingPaymentOptions) - 유형 및 기본값이 포함된 속성
appsettings.json의 섹션 (예:"RAMBLA.PendingPayment")IoCExtensions.AddCSLevelBooking()수정
필요하지 않은 경우, 계획에 명시적으로 표시.
1.7단계 — 공개 API 영향 분석
목표: 기존 소비자를 손상시키지 않도록 합니다.
기능이 기존 메서드를 재사용하는 경우
- 메서드가 동일한 시그니처를 유지하는가? → 영향 없음
- 선택적 매개변수가 추가되는가? → 모든 호출 사이트가 손상되지 않는지 확인
- 오버로드가 추가되는가? → 컴파일러가 모호함 없이 해결하는지 확인
- 이름이 변경되는가? →
grep으로 모든 호출 사이트 검색 및 마이그레이션
기능이 새 서비스를 추가하는 경우
- 서비스가 DI에 등록되는가? →
IoCExtensions에 등록 확인 - 기존 서비스에 순환 종속성 가능성이 있는가? → 확인
기능이 새 엔드포인트를 추가하는 경우
- 경로가 기존 경로와 충돌하는가? → 확인
- HTTP 메서드가 REST와 일관적인가? (GET은 읽기, POST는 변경)
1.8단계 — 회귀 테스트 사전 점검 (필수)
목표: 새 코드를 생성하거나 기존 코드를 수정하기 전에, 작업할 (간접적으로라도) 컴포넌트에 테스트 커버리지가 있는지 확인합니다. 없으면 구현을 시작하기 전에 테스트를 만들고 실행합니다.
단계
-
간접적 영향 표면 식별: 1.5단계(재사용 vs 확장 vs 신규)를 기반으로 다음을 나열:
- 메서드를 확장하거나 오버로드할 기존 서비스
- 수정할 기존 인터페이스
- 라우팅/DI에 의해 영향을 받을 수 있는 기존 엔드포인트
- 편집할 (생성하지 않을) 기존 파일
-
작업할 각 기존 컴포넌트에 대해:
src/*.Test*/**에서 이를 실행하는 테스트 검색- 커버리지가 있음 → OK, 계속
- 커버리지가 없음 → HARD_BLOCK:
@refactor-worker-tests를 호출하여 현재 동작에 대한 특성화 테스트 생성@refactor-verifier를 호출하여 통과 확인- 별도 커밋:
test(characterization): <클래스>에 특성화 테스트 추가
-
기능이 100% 신규 생성인 경우 (기존 파일 수정 없음):
- 회귀 표면 없음 → 사전 점검 생략
- 단, 새 기능의 테스트는 4단계에서 생성되고 5단계에서 통과해야 함
(5단계) 종료 기준
기능이 올바르다고 간주되려면 @refactor-verifier가 다음이 통과함을 확인해야 함:
- 기능의 새 테스트 (서비스 + 엔드포인트)
- 간접적 컴포넌트의 기존 테스트 (회귀)
둘 중 하나라도 실패하면 기능을 종료할 수 없음.
2단계 — 의사 결정 트리: 무엇을 어디에 생성할지
1.5단계(재사용/확장/신규)와 1.6단계(설정)의 결정을 적용합니다.
READ-ONLY 엔드포인트 및 재사용의 경우
*.API/
+ {Nombre}Function.cs — 새 Function/Controller
+ {Nombre}Request.cs — 프레젠테이션 전용
+ {Nombre}Response.cs — 프레젠테이션 전용
*.Test*/
+ {Nombre}FunctionTests.cs — 응답 형태 테스트 (로직 아님)
MUTATION 엔드포인트 및 새 서비스의 경우
*.Contracts/
+ ICS{Nombre}Service.cs — 서비스 인터페이스
+ {Nombre}Request.cs — 공유 요청인 경우
+ {Nombre}Response.cs — 공유 응답인 경우
*.Impl/
+ CS{Nombre}Service.cs — 구현
+ I{Nombre}Options.cs — 1.6단계가 설정을 감지한 경우에만
*.API/
+ {Nombre}Function.cs — Function/Controller
+ {Nombre}Request.cs — 전용 (Contracts에 없는 경우)
+ {Nombre}Response.cs — 전용 (Contracts에 없는 경우)
*.Test*/
+ CS{Nombre}ServiceTests.cs — happy path + 최소 하나의 오류
기존 서비스 확장의 경우
*.Contracts/
~ ICS{Nombre}Service.cs — 메서드 시그니처 추가 (또는 오버로드 생성)
*.Impl/
~ CS{Nombre}Service.cs — 새 메서드/오버로드 구현
*.API/
+ {Nombre}Function.cs — 새 Function/Controller
+ {Nombre}Request.cs — 전용인 경우
+ {Nombre}Response.cs — 전용인 경우
*.Test*/
+ (또는 ~) 서비스 테스트 — 새 메서드에 대한 케이스 추가
3단계 — 생성 계획
워커를 호출하기 전에 오케스트레이터는 이 계획을 사용자에게 제시하고 명시적인 확인을 기다립니다:
[생성 계획] 기능: <이름> — <간단한 설명>
호스트: <FUNCTIONS | WEBAPP>
분류: <READ-ONLY | MUTATION>
전략: <재사용 | 확장 | 신규>
재사용 분석 (1.5단계):
· 후보 서비스: <ICSXxxService> 또는 "없음"
· 후보 메서드: <XxxService.YyyMethod> 또는 "없음"
· 결정: <재사용 | 확장 | 신규>
설정 분석 (1.6단계):
· 설정 필요: <예 | 아니오>
· 필요한 경우: <IXxxOptions + appsettings 섹션>
공개 API 영향 (1.7단계):
· 영향받는 호출 사이트: <목록> 또는 "없음"
· 주요 변경 사항: <예 | 아니오>
생성할 아티팩트:
*.Contracts/ ([N] 파일):
+ ICS{Nombre}Service.cs — 새 인터페이스 (또는: IXxx에 메서드 추가)
+ {Nombre}Request.cs — 공유 유형인 경우
+ {Nombre}Response.cs — 공유 유형인 경우
*.Impl/ ([N] 파일):
+ CS{Nombre}Service.cs — 서비스 구현
+ I{Nombre}Options.cs — 설정이 필요한 경우에만 (1.6단계)
*.API/ ([N] 파일):
+ {Nombre}Function.cs — Azure Function (또는: {Nombre}Controller.cs)
+ {Nombre}Request.cs — 전용 유형인 경우
+ {Nombre}Response.cs — 전용 유형인 경우
*.Test*/ ([N] 파일):
+ CS{Nombre}ServiceTests.cs — 서비스 테스트 (happy path + 오류)
+ {Nombre}FunctionTests.cs — 엔드포인트 테스트 (해당하는 경우)
기존 파일 수정:
~ src/.../IoCExtensions.cs — 서비스 및 옵션 등록 (해당하는 경우)
실행 순서: Contracts → Impl → Presentation → Tests
진행하시겠습니까?
사용자의 명시적 승인 없이 워커를 호출하지 마십시오.
4단계 — 실행
워커 순서
@refactor-worker-contracts—*.Contracts/에 새 유형 또는 시그니처가 있는 경우에만@refactor-worker-impl—*.Impl/에 코드가 있을 때마다@refactor-worker-presentation— 엔드포인트가 있을 때마다@refactor-worker-tests— 항상 마지막에
참고: 기능이 새 Service Gateway를 노출하지 않는 한
@refactor-worker-crosscutting은 호출하지 않습니다. 생성에서는 드문 경우이며, 일반적으로 리팩터링에서 발생합니다.
각 워커에 대한 지침
프롬프트에 다음 포함:
- 전체 계획 (3단계)
- 프로젝트 패턴: 생성하기 전에 유사한 파일 읽기
- 예상 내용이 포함된 정확한 파일 목록
- 1.6단계가 설정을 감지한 경우:
IXxxOptions경로 및 설정 섹션
5단계 — 검증 및 커밋
@refactor-verifier호출- PASS인 경우 다음 형식으로 커밋 제안:
feat(<범위>): <짧은 이름> 기능 추가 - ICS{Nombre}Service 인터페이스 및 CS{Nombre}Service 구현 추가 - {동사} /{경로} Function/Controller 추가 - {Nombre}Request/{Nombre}Response 계약 추가 - I{Nombre}Options 새 설정 추가 (해당하는 경우) - CS{Nombre}Service 단위 테스트 추가 - FAIL인 경우 실패한 레이어 식별, 워커 재호출, 재검증
호스트별 패턴
FUNCTIONS — Azure Functions 격리 작업자
Function을 생성하기 전에 기존 HTTP Function을 읽고 스타일을 복사하세요. 일반적인 예:
public class {Nombre}Function
{
private readonly I{Nombre}Service _{campo};
public {Nombre}Function(I{Nombre}Service {campo}) => _{campo} = {campo};
[Function("{Nombre}Function")]
public async Task<HttpResponseData> RunAsync(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "{ruta}")] HttpRequestData req)
{
var request = await req.ReadFromJsonAsync<{Nombre}Request>();
var result = await _{campo}.ExecuteAsync(request);
var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteAsJsonAsync(result);
return response;
}
}
생성하기 전에 확인:
AuthorizationLevel.Function또는AzureAdJwt인가? (프로젝트에 따라 다름)- 경로가 충돌하지 않는가?
ReadFromJsonAsync/WriteAsJsonAsync확장 메서드의 using 문이 추가되었는가?