Community연구 & 데이터 분석github.com

APS-프레임워크/aps-template

APS 프레임워크 프로젝트 템플릿: .NET Azure Functions 및 ASP.NET Core 웹 앱 생성을 위한 에이전트, 스킬, 명령 및 스크립트 제공

aps-template란 무엇인가요?

이 스킬은 오케스트레이터 에이전트가 .NET 기반 프로젝트에서 **새로운 기능을 생성**하는 전체 워크플로우를 안내합니다. 기존 코드를 수정하는 리팩터링(별도의 `refactor-protocol` 스킬)과 달리, 이 스킬은 '순수 생성'에 초점을 맞춥니다. Azure Functions 격리 작업자 또는 ASP.NET Core 웹앱 환경에서 HTTP 엔드포인트, 도메인 서비스, 작업/이벤트 핸들러, 설정 옵션 등을 추가할 때 사용합니다. 스킬은 사용자 요구사항 분석(Fase 1), 기존 서비스 재사용 가능성 평가(Fase 1.5) 및 설정 필요성 분석(Fase 1.6)을 통해 불필요한 코드 중복을 방지합니다. 공개 API에 미치는 영향을 검토하고(Fase 1.7), 수정될 기존 컴포넌트의 회귀 테스트가 있는지 확인합니다(Fase 1.8). 최종 생성 계획을 사용자에게 제시한 후(Fase 3) 워커를 호출하여 계약, 구현, 프레젠테이션 레이어를 순서대로 생성하고(Fase 4), 최종적으로 검증 및 커밋(Fase 5)합니다. `FUNCTIONS`, `WEBAPP`, `NUGET_LIBRARY` 등 다양한 호스트 유형을 지원하며 프로젝트 구조를 검증하는 선행 단계를 포함합니다.

지원 대상~Claude Code~Codex CLI~Cursor✓OpenCode
npx skills add APS-Framework/aps-template

Installed? Explore more 연구 & 데이터 분석 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

내 역할

오케스트레이터가 새로운 기능을 생성할 때 (기존 기능 수정이 아닌) 재사용, 설정, 호환성을 사전 분석하여 안내합니다. 리팩터링과 달리, 보존해야 할 기존 코드가 없습니다: 디자인은 사용자 요구사항에서부터 시작됩니다.

이 스킬을 사용해야 할 때 (refactor-protocol 대신):

  • 사용자가 존재하지 않는 엔드포인트, 서비스, 작업, 핸들러, 이벤트 또는 설정을 요청함
  • 작업이 순수 생성이며, 기존 동작을 수정하는 것이 아님
  • 결과물이 저장소에 새 파일을 추가하며, 기존 파일의 시그니처를 변경하지 않음

이 스킬을 사용하지 말아야 할 때 (대신 refactor-protocol 사용):

  • 기존 서비스의 시그니처 수정
  • 이미 존재하는 엔드포인트의 동작 변경
  • 코드 이름 변경, 추출 또는 이동

0단계 — 구조 검증 (항상 먼저)

  1. project-structure 스킬을 로드하고 전체 검증을 실행합니다
  2. 호스트 유형 감지: FUNCTIONS | WEBAPP | NUGET_LIBRARY
  3. 결과에 따라 조치:
상태조치
HARD_BLOCK중단. 사용자에게 알림.
NUGET_LIBRARYHTTP 엔드포인트 생성은 예상치 못한 상황. 질문: "라이브러리에 공개 작업을 추가하시겠습니까, 아니면 감지하지 못한 호스트가 실제로 있습니까?"
PREGUNTA계속 진행하기 전에 질문 해결
OK / WARNING1단계로 진행

1단계 — 요구사항 수집

오케스트레이터는 사용자 설명($ARGUMENTS)에서 최대한 많은 정보를 추론하고, 명확하지 않은 것만 질문합니다. 설명에 이미 답이 있는 질문은 하지 않습니다.

1.1 이름, 목적 및 기능 유형

  • HTTP 엔드포인트 (Function/Controller): [동사] /경로 — 설명
  • 도메인 서비스: 서비스 이름 및 책임
  • 작업/이벤트 핸들러: 트리거 + 동작
  • 설정 옵션: 옵션 이름 및 목적

1.2 READ vs MUTATION 분류

기능이 상태를 변경하는지 읽기 전용인지 결정합니다. 이는 다음에 영향을 줍니다:

  • 응답 DTO가 위치할 곳
  • 트랜잭션/멱등성 필요 여부
  • 필요한 테스트 종류
유형특징영향
READ-ONLYGET, 기존 데이터 반환, 쓰기 없음임시 DTO, 최소 테스트
MUTATIONPOST/PUT/DELETE, 상태 쓰기 또는 변경성공 + 오류 테스트 필요

1.3 예상 입력/출력 수집

  • 요청: 본문 또는 쿼리 매개변수 구조
  • 응답: 응답 본문 구조, 상태 코드
  • 오류: 어떤 오류를 어떤 상태 코드에 매핑해야 하는지

1.5단계 — 재사용 분석 (중요, 건너뛰지 말 것)

목표: 아무것도 생성하기 전에 기능이 부분적으로 또는 완전히 이미 존재하는지 감지합니다.

단계

  1. *.Impl/에서 @explore를 사용하여 기능 도메인으로 기존 서비스 검색
  2. 필요한 동작의 80% 이상을 충족하는 후보 메서드 검색:
    • 필요한 데이터를 간단한 필터로 이미 반환하는 메서드가 있는가?
    • 해당 케이스를 추가하기 위해 오버로드할 수 있는 메서드가 있는가?
  3. *.API/에서 동일한 요청/응답 형태를 가진 유사 엔드포인트 검색

의사 결정 트리

케이스의 100%를 충족하는 메서드가 있는가?
└── 예 → 새 메서드 생성 안 함. 다음만 생성:
        · *.API/의 엔드포인트 (Function/Controller)
        · *.API/ 전용 DTO 요청/응답
        · 응답 형태 테스트

거의 완벽한 메서드가 있는가? (필터, 페이지네이션, 정렬)
├── 예 → 고려:
│   ├── 기존 메서드에 선택적 매개변수 추가 (기본값 포함)
│   ├── 더 구체적인 시그니처로 오버로드 생성
│   └── 기존 메서드를 래핑하는 확장 메서드 생성
└── 아니오 → 새 메서드 생성 계속

관련되지만 다른 서비스가 있는가? (예: 유사한 책임)
├── 예 → 사용자에게 질문: "[CSXxxService]를 확장할까요, 아니면 새 [CSYyyService]를 만들까요?"
└── 아니오 → 새 서비스 생성

이 단계의 예상 출력

다음 세 가지 결정 중 하나를 계속 진행하기 전에 사용자에게 제시:

  1. 순수 재사용: 기능이 기존 메서드의 래퍼로 구현됨
  2. 확장: 기존 서비스에 오버로드/메서드 추가
  3. 새로 생성: 새 서비스 및 메서드 (재사용 불가능 이유 설명)

1.6단계 — 설정 분석 (신규)

목표: 기능에 설정 가능한 매개변수가 필요한지, 필요하다면 어디에 정의할지 감지합니다.

핵심 질문

  1. 기능에 외부 설정 없이 합리적인 기본값이 있는가?
  2. 환경별로 설정 가능해야 하는 임계값, 페이지네이션, 시간 제한 또는 플래그가 있는가?
  3. URL/키/비밀번호가 있는 외부 시스템에 연결하는가?
  4. 점진적 롤아웃을 위한 기능 플래그가 필요한가?

의사 결정 트리

기능에 설정이 필요한가?
├── 아니오 → 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. 간접적 영향 표면 식별: 1.5단계(재사용 vs 확장 vs 신규)를 기반으로 다음을 나열:

    • 메서드를 확장하거나 오버로드할 기존 서비스
    • 수정할 기존 인터페이스
    • 라우팅/DI에 의해 영향을 받을 수 있는 기존 엔드포인트
    • 편집할 (생성하지 않을) 기존 파일
  2. 작업할 각 기존 컴포넌트에 대해:

    • src/*.Test*/**에서 이를 실행하는 테스트 검색
    • 커버리지가 있음 → OK, 계속
    • 커버리지가 없음 → HARD_BLOCK:
      • @refactor-worker-tests를 호출하여 현재 동작에 대한 특성화 테스트 생성
      • @refactor-verifier를 호출하여 통과 확인
      • 별도 커밋:
        test(characterization): <클래스>에 특성화 테스트 추가
        
  3. 기능이 100% 신규 생성인 경우 (기존 파일 수정 없음):

    • 회귀 표면 없음 → 사전 점검 생략
    • 단, 새 기능의 테스트는 4단계에서 생성되고 5단계에서 통과해야 함

(5단계) 종료 기준

기능이 올바르다고 간주되려면 @refactor-verifier가 다음이 통과함을 확인해야 함:

  1. 기능의 새 테스트 (서비스 + 엔드포인트)
  2. 간접적 컴포넌트의 기존 테스트 (회귀)

둘 중 하나라도 실패하면 기능을 종료할 수 없음.


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단계 — 실행

워커 순서

  1. @refactor-worker-contracts — *.Contracts/에 새 유형 또는 시그니처가 있는 경우에만
  2. @refactor-worker-impl — *.Impl/에 코드가 있을 때마다
  3. @refactor-worker-presentation — 엔드포인트가 있을 때마다
  4. @refactor-worker-tests — 항상 마지막에

참고: 기능이 새 Service Gateway를 노출하지 않는 한 @refactor-worker-crosscutting은 호출하지 않습니다. 생성에서는 드문 경우이며, 일반적으로 리팩터링에서 발생합니다.

각 워커에 대한 지침

프롬프트에 다음 포함:

  • 전체 계획 (3단계)
  • 프로젝트 패턴: 생성하기 전에 유사한 파일 읽기
  • 예상 내용이 포함된 정확한 파일 목록
  • 1.6단계가 설정을 감지한 경우: IXxxOptions 경로 및 설정 섹션

5단계 — 검증 및 커밋

  1. @refactor-verifier 호출
  2. PASS인 경우 다음 형식으로 커밋 제안:
    feat(<범위>): <짧은 이름> 기능 추가
    
    - ICS{Nombre}Service 인터페이스 및 CS{Nombre}Service 구현 추가
    - {동사} /{경로} Function/Controller 추가
    - {Nombre}Request/{Nombre}Response 계약 추가
    - I{Nombre}Options 새 설정 추가 (해당하는 경우)
    - CS{Nombre}Service 단위 테스트 추가
    
  3. 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 문이 추가되었는가?

관련 스킬