/cc-flutter:feature:create — 기능 하나를 처음부터 끝까지 자동 조립#
| 항목 | 내용 |
|---|---|
| 실행 명령 | /cc-flutter:feature:create |
| 분류 | 워크플로우 |
| 난이도 | ●●● 높음 |
| MCP 서버 | serena, sequential, context7, magic |
한마디로#
새 기능 하나를 만들 때, 서버(백엔드)부터 화면(프론트엔드)까지 한 번에 자동으로 만들어 주는 "조립 라인" 입니다. 가구 하나를 부품·설명서·조립·검수까지 한 번에 끝내 주는 풀세트 주문이라고 보면 됩니다.
누가·언제 쓰나요#
- 새로운 기능을 밑바닥부터 끝까지 한 번에 만들고 싶을 때
- 서버(Serverpod)와 앱 화면(Flutter)을 동시에 만들어야 할 때
- 정해진 표준 구조(Clean Architecture)대로 빠짐없이 만들고 싶을 때
무엇을 해주나요#
기능 이름 하나만 주면, 다음을 알아서 만들고 검사까지 해 줍니다.
- 서버 쪽: 데이터 모델, 엔드포인트(서버 기능), 데이터베이스 반영
- 앱 쪽: 화면, 상태 관리 코드, 데이터 연결 코드
- 테스트: 자동 테스트(BDD
.feature파일 포함) - 마무리 검사: 코드 분석, 테스트 실행, 그리고 실제 서버를 띄워 앱과 잘 맞물리는지까지 통합 점검
즉, "기능 하나"에 필요한 모든 파일과 검증이 한 묶음으로 만들어집니다.
어떻게 쓰나요#
# 커뮤니티 게시글 기능 만들기
/cc-flutter:feature:create community Post
--location application
--caching swr
--endpoint-type app
--fields " title:String, content:String, category:PostCategory, imageUrls:List < String > ? "
# 채팅 메시지 기능 만들기
/cc-flutter:feature:create chat Message
--location application
--caching cache-first
--endpoint-type app
--fields " content:String, senderId:int, chatRoomId:int, readAt:DateTime? "
# 관리자 대시보드 기능 만들기
/cc-flutter:feature:create dashboard Stats
--location console
--caching none
--endpoint-type console
--fields " totalUsers:int, totalPosts:int, activeUsers:int "
-
첫 번째 값은 기능 이름(예:
community), 두 번째 값은 데이터 이름(예:Post)으로, 둘 다 꼭 필요합니다. -
--location: 어디에 만들지 (application일반 앱 /common공용 /console관리자, 기본값application) -
--caching: 데이터 저장 방식 (swr/cache-first/none, 기본값swr) -
--endpoint-type: 서버 기능 종류 (app/console/both, 기본값app) --fields: 어떤 데이터 항목을 담을지 (예:"title:String, content:String")--with-bdd: 테스트도 같이 만들지 (기본값 켜짐true)
안에서 무슨 일이 벌어지나요#
크게 여섯 단계를 차례로 진행하며, 단계마다 필요한 파일을 만들고 확인합니다.
- 사전 점검(Phase 0) — 작업에 필요한 도구(런타임 검증용 MCP)가 준비됐는지 확인하고, 없으면 자동으로 설치·연결합니다.
- 요구사항 확인(Phase 1) — 기능 이름, 담을 데이터 항목, 필요한 기능 범위(목록/추가/수정/삭제), 저장 방식, 테스트 포함 여부를 정리합니다.
- 서버 만들기(Phase 2) — 데이터 모델과 서버 기능을 만들고, 데이터베이스에 반영합니다.
- 앱 만들기(Phase 3) — 데이터 구조, 데이터 연결, 화면과 상태 관리 코드를 만듭니다.
- 테스트 만들기(Phase 4) — 시나리오 기반 자동 테스트(BDD)를 생성합니다.
-
통합·검수(Phase 5) — 코드 분석과 테스트를 돌리고, 실제 서버를 띄워(
serverpod start) 서버와 앱이 실제로 잘 맞물리는지까지 최종 확인합니다.
⚙️ 상세 옵션·실행 명세 (개발자 / AI 에이전트용)
Triggers#
- When creating a new Feature from start to finish
- When implementing Serverpod backend and Flutter frontend simultaneously
- When a complete Clean Architecture workflow is needed
Context Trigger Pattern#
/cc-flutter:feature:create {feature_name} {entity_name} [--options]Parameters#
| Parameter | Required | Description | Example |
|---|---|---|---|
feature_name | ✅ | Feature module name (snake_case) | community, chat, wallet |
entity_name | ✅ | Entity name (PascalCase) | Post, Message, Transaction |
--location | ❌ | Location | application, common, console (default: application) |
--caching | ❌ | Caching strategy | swr, cache-first, none (default: swr) |
--endpoint-type | ❌ | Endpoint type | app, console, both (default: app) |
--fields | ❌ | Field Definition | "title:String, content:String" |
--with-bdd | ❌ | BDD Test Generation | true, false (default: true) |
--bdd-from | ❌ | BDD Scenario source | .claude/docs/{feature}/bdd/ |
Execution Flow#
┌─────────────────────────────────────────────────────────┐
│ Phase 0: Preflight (MCP & 환경 점검) ⭐ fvm 고려 │
├─────────────────────────────────────────────────────────┤
│ 0-1. marionette_mcp 실행 파일 존재 확인 │
│ 0-2. 미설치 시 `fvm dart pub global activate` 자동 실행 │
│ 0-3. Claude Code MCP 등록 상태 확인 (claude mcp list) │
│ 0-4. 실패 시 절대 경로로 재등록 + PATH 주입 │
│ 0-5. Cursor/Zed MCP 설정 파일 존재/동기화 확인(선택) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Phase 1: Requirements gathering (Interactive) │
├─────────────────────────────────────────────────────────┤
│ 1. Feature/Entity 이름 확인 │
│ 2. 필드 정의 수집 │
│ 3. CRUD 메서드 범위 확인 │
│ 4. 캐싱 전략 선택 │
│ 5. BDD 테스트 포함 여부 확인 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Phase 2: Backend implementation │
├─────────────────────────────────────────────────────────┤
│ Step 1: /cc-serverpod:model │
│ Step 2: /cc-serverpod:endpoint │
│ Step 3: melos run backend:pod:generate │
│ Step 4: 마이그레이션 (필요 시) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Phase 3: Frontend implementation │
├─────────────────────────────────────────────────────────┤
│ Step 5: /cc-flutter:feature:domain │
│ Step 6: /cc-flutter:feature:data │
│ Step 7: /cc-flutter:feature:presentation │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Phase 4: BDD 테스트 생성 (--with-bdd true 시) ⭐ │
├─────────────────────────────────────────────────────────┤
│ Step 8: /cc-flutter:bdd:generate {feature_name} │
│ Step 9: patrol test --target integration_test/scenarios/*_test.dart │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Phase 5: Integration and verification │
├─────────────────────────────────────────────────────────┤
│ Step 10: DI 등록 확인 │
│ Step 11: Route 등록 확인 │
│ Step 12: melos run build │
│ Step 13: melos run analyze │
│ Step 14: melos run test --scope={feature} │
│ Step 15: patrol test --target integration_test/scenarios/*_test.dart │
│ Step 16: 로컬 풀스택 통합 검증 ⭐ (serverpod start) │
│ ↳ server+내장 Postgres+app 기동 → 로컬 백엔드 대상 통합 │
│ ↳ backend: dart test -t integration / front: 로컬 백엔드 │
│ ↳ 백엔드 변경 시 마이그레이션/로그는 Serverpod MCP 활용 │
│ ↳ 폴백(3.x): docker compose up -d + dart run │
└─────────────────────────────────────────────────────────┘Phase 0: Preflight (MCP & 환경 점검)#
목적: 기능 작업 전에 런타임 검증(marionette_mcp)이 가능한 상태인지 확인하고, 필요하면 자동 설치·재등록. fvm 환경을 전제로 함.
Step 0-1. 실행 파일 존재 확인#
MCP_BIN= " $HOME/.pub-cache/bin/marionette_mcp "
if [ ! -x " $MCP_BIN " ]; then
echo " ⚠️ marionette_mcp 미설치 — 자동 설치를 시작합니다. "
NEEDS_INSTALL=1
else
echo " ✅ marionette_mcp 설치됨: $MCP_BIN "
fiStep 0-2. fvm 경유 자동 설치#
중요: dart는 zshrc alias(fvm dart)라 GUI 앱의 subprocess 환경에서는 동작하지 않음 → 항상 fvm dart로 실행.
if [ " $NEEDS_INSTALL " = " 1 " ]; then
# fvm default SDK로 글로벌 활성화 (프로젝트별 SDK와 별개)
fvm dart pub global activate marionette_mcp
# PATH 확인
case " :$PATH: " in
* " :$HOME/.pub-cache/bin: " *) ;;
*)
echo ' export PATH= " $PATH:$HOME/.pub-cache/bin " ' > > " $HOME/.zshrc "
export PATH= " $PATH:$HOME/.pub-cache/bin "
;;
esac
fiStep 0-3. Claude Code MCP 등록 상태 확인#
if ! claude mcp list 2 > & 1 | grep -q " marionette:.*✓ Connected " ; then
echo " ⚠️ marionette MCP 연결 실패 — 절대 경로로 재등록 "
claude mcp remove marionette 2 > /dev/null || true
claude mcp add --transport stdio marionette -- " $HOME/.pub-cache/bin/marionette_mcp "
claude mcp list | grep marionette
fiStep 0-4. Cursor / Zed 설정 동기화 (선택)#
GUI 앱은
~/.zshrc의 PATH/alias를 읽지 않음 → 절대 경로 +env.PATH주입 필수.
Cursor (~/.cursor/mcp.json):
{
" mcpServers " : {
" marionette " : {
" command " : " /Users/dongwoo/.pub-cache/bin/marionette_mcp " ,
" env " : { " PATH " : " /Users/dongwoo/fvm/default/bin:/usr/bin:/bin " }
}
}
}Zed (~/.config/zed/settings.json):
{
" context_servers " : {
" marionette " : {
" command " : {
" path " : " /Users/dongwoo/.pub-cache/bin/marionette_mcp " ,
" env " : { " PATH " : " /Users/dongwoo/fvm/default/bin:/usr/bin:/bin " }
}
}
}
}Step 0-5. 대상 Flutter 앱 전제 조건 안내#
MCP는 떠 있어도 대상 앱에 marionette_flutter 통합이 없으면 붙지 못함. Phase 4.7(실 동작 구현) 직전에 점검:
# pubspec.yaml
dev_dependencies:
marionette_flutter: ^latest// main.dart (debug build 한정)
void main() {
MarionetteBinding.ensureInitialized();
runApp(const MyApp());
}
snapshot 버전 불일치(exit 253): fvm 프로젝트 SDK 전환 후 발생 가능. 래퍼가
dart pub global run으로 fallback하지만 반복되면fvm dart pub global activate marionette_mcp재실행.
Preflight 게이트#
위 5단계 모두 통과해야 Phase 1 진입. 실패 시 사용자에게 원인 보고 후 중단.
Phase 1: Requirements Gathering#
Interactive Mode#
## Feature Creation Requirements
### default 정보
- **Feature name**: {feature_name}
- **Entity name**: {entity_name}
- **Location**: application / common / console
### Entity Fields
| Field Name | Type | Required | Description |
|--------|------|------|------|
| title | String | ✅ | Title |
| content | String | ✅ | Content |
| category | Enum | ✅ | Category |
### CRUD Methods
- [x] List query (pagination)
- [x] Single item query
- [x] Create
- [x] Update
- [x] Delete
### Caching Strategy
- [x] SWR (Stale-While-Revalidate)
- [ ] Cache-First
- [ ] NonePhase 2: Backend Implementation#
Step 1: Serverpod Model#
# Run /cc-serverpod:model command
/cc-serverpod:model {feature_name} {entity_name}
--fields " {fields} "
--has-crud trueGenerated Files:
backend/.../model/entities/{entity_name}.spy.yamlbackend/.../model/dto/...backend/.../model/enum/...
Step 2: Serverpod Endpoint#
# Run /cc-serverpod:endpoint command
/cc-serverpod:endpoint {feature_name} {entity_name}
--type {endpoint_type}Generated Files:
backend/.../endpoint/{feature_name}_endpoint.dartbackend/.../service/{feature_name}_service.dart
Step 3: Code Generation#
melos run backend:pod:generateStep 4: Migration#
melos run backend:pod:create-migration
melos run backend:pod:run-migrationPhase 3: Frontend Implementation#
Step 5: Domain Layer#
# Run /cc-flutter:feature:domain command
/cc-flutter:feature:domain {feature_name} {entity_name}
--location {location}Generated Files:
- Entity, Repository Interface, UseCase
- UseCase Test
Step 6: Data Layer#
# Run /cc-flutter:feature:data command
/cc-flutter:feature:data {feature_name} {entity_name}
--location {location}
--caching {caching}Generated Files:
- Repository Implementation체, Serverpod Mixin
- Cache Strategy, Local DB (Drift)
Step 7: Presentation Layer#
# Run /cc-flutter:feature:presentation command
/cc-flutter:feature:presentation {feature_name} {entity_name}
--location {location}Generated Files:
- BLoC (Event, State), BLoC Test
- Page, Widget, Widget Test
- Route, Widgetbook UseCase (
feature/{location}/{feature_name}/widgetbook/— feature 소유. 조립 앱은 스캔만)
Phase 4: BDD Test Generation#
--with-bdd true (default) executed:
Step 8: BDD Scenario and Step Writing#
# Run /cc-flutter:bdd:generate command
/cc-flutter:bdd:generate {feature_name}
--entity-name {entity_name}
--location {location}
--from-claude-docs true # .claude/docs에 BDD 파일이 있는 경우Generated Files (⛔ feature 패키지 안이 아니라 앱별 app/{app}/integration_test/에 전부
모입니다 — build.yaml도, 코드 생성기도 없습니다):
app/{app}/integration_test/
├── features/
│ ├── {feature}_list.feature
│ ├── {feature}_detail.feature
│ └── {feature}_form.feature
├── step/
│ └── {feature}_steps.dart # Feature 전용 step (TestDriver 기반, 손으로 작성)
└── scenarios/
└── {feature}_{scenario}_test.dart # Patrol 테스트 (손으로 작성)Step 9: Patrol 테스트 실행#
# ⛔ melos run test:bdd 는 폐지된 코드생성 명령입니다 — .feature → Patrol 테스트를 대신
# 만들어주지 않습니다. scenarios/*_test.dart 는 이미 손으로 작성된 실행 파일이므로 곧바로 실행합니다.
cd app/{location}
patrol test --target integration_test/scenarios/{feature}_{scenario}_test.dart결과: .feature의 Scenario 이름·step 순서를 그대로 옮겨 손으로 작성한 Patrol E2E 테스트 실행
Phase 5: Integration and Verification#
Step 10: Dependency Wiring Verification#
Items to verify: No di/ folder, no getIt usage, direct BlocSignalProvider creation
// 페이지에서 BLoC 직접 생성
BlocSignalProvider(create: (_) => {Feature}Bloc())
Step 9: Route Registration Verification#
File to verify: feature/{type}/{feature}/lib/src/route/{feature}_route.dart (TypedGoRoute/GoRouteData per-feature; kobic에는 단일 app_router.dart가 없고 라우트는 feature 모듈별로 분산 정의됨)
Step 10-12: Build and test#
melos run build
melos run analyze
melos run test --scope={feature_name}Step 16: 로컬 풀스택 통합 검증 (Serverpod 4 / 로컬 풀스택) ⭐#
목적: 위젯/유닛 테스트(mock)와 별개로, 실제 백엔드를 띄운 상태에서 backend↔front 계약을 검증한다. Serverpod 4의 내장 Postgres 덕분에 Docker 없이 완전 로컬로 통합테스트가 가능하다.
언제 켜는가: Phase 2(Backend)에서 모델/엔드포인트가 추가·변경되었거나, Phase 3 data layer가 실제 endpoint를 호출할 때. 순수 위젯/유닛만 바뀐 경우는 생략 가능(기존 mock 테스트로 충분).
로컬 풀스택 기동 —
serverpod start한 명령으로 백엔드 서버 + 내장 Postgres + Flutter 앱을 함께 기동한다(서버·DB·웹·앱 sub-second stateful 핫리로드, 재컴파일/재시작 없음). 앱은 dev flavor에서 로컬 서버(http://localhost:8080/)로 연결되고 Staging은 폴백이다. 핫리로드가 막히면serverpod start터미널에서 R 키로 서버+앱 강제 재시작.로컬 백엔드 대상 통합 검증
- 백엔드:
withServerpod헬퍼 기반 통합테스트를dart test -t integration으로 실행(내장 Postgres라 Docker 불필요, 기능 구현 중 바로 endpoint 통합테스트 가능). - 프론트: feature/Patrol/통합 테스트는 mock이 아니라 방금 띄운 로컬 백엔드를 대상으로 수행. base-URL은 앱의 기존 client/OpenApiService/flavor 설정을 따르고 하드코딩하지 않는다.
- 백엔드:
백엔드 변경 시 마이그레이션·로그는 Serverpod MCP 활용 — 실행 중인 로컬 서버에 에이전트가 연결해 DB 마이그레이션 생성·적용, 서버 로그 읽기, 앱 구동+스크린샷 검토를 수행한다.
Serverpod 3.x 환경 폴백 — 내장 Postgres가 없는 3.x(legacy)에서는
docker compose up -d로 DB를 띄운 뒤dart run bin/main.dart로 서버를 기동하고 동일하게dart test -t integration수행.
상세 절차는 serverpod-local-fullstack, serverpod-mcp-guide 스킬을 참조.
TodoWrite Template#
TodoWrite([
// Phase 0: Preflight
{"content": "marionette_mcp 설치 확인 (fvm dart pub global activate)", "status": "pending", "activeForm": "marionette_mcp Preflight 중"},
{"content": "Claude Code MCP 등록 상태 확인/재등록", "status": "pending", "activeForm": "MCP 등록 확인 중"},
// Backend
{"content": "Generate Serverpod model", "status": "pending", "activeForm": "Generate Serverpod model in progress"},
{"content": "Generate Serverpod endpoint", "status": "pending", "activeForm": "Generate Serverpod endpoint in progress"},
{"content": "backend:pod:generate 실행", "status": "pending", "activeForm": "backend:pod:generate running"},
// Frontend - Domain
{"content": "Generate Domain Entity", "status": "pending", "activeForm": "Generate Domain Entity in progress"},
{"content": "Generate Repository Interface", "status": "pending", "activeForm": "Generate Repository Interface in progress"},
{"content": "Generate UseCase", "status": "pending", "activeForm": "Generate UseCase in progress"},
{"content": "Generate UseCase tests", "status": "pending", "activeForm": "Generate UseCase tests in progress"},
// Frontend - Data
{"content": "Generate Repository implementation", "status": "pending", "activeForm": "Generate Repository implementation in progress"},
{"content": "Generate Serverpod Mixin", "status": "pending", "activeForm": "Generate Serverpod Mixin in progress"},
// Frontend - Presentation
{"content": "Generate BLoC", "status": "pending", "activeForm": "Generate BLoC in progress"},
{"content": "Generate BLoC tests", "status": "pending", "activeForm": "Generate BLoC tests in progress"},
{"content": "Generate Page/Widget", "status": "pending", "activeForm": "Generate Page/Widget in progress"},
{"content": "Generate Widget tests", "status": "pending", "activeForm": "Generate Widget tests in progress"},
{"content": "Define Routes", "status": "pending", "activeForm": "Define Routes in progress"},
{"content": "Generate Widgetbook UseCase", "status": "pending", "activeForm": "Generate Widgetbook UseCase in progress"},
// BDD 테스트 (--with-bdd true 시, app/{app}/integration_test/ 에 hand-written — 코드 생성기 없음)
{"content": "Write BDD .feature files", "status": "pending", "activeForm": "Writing BDD .feature files"},
{"content": "Write BDD Step definitions (TestDriver)", "status": "pending", "activeForm": "Writing BDD Step definitions"},
{"content": "Write Patrol scenario test files by hand", "status": "pending", "activeForm": "Writing Patrol scenario test files"},
// Integration
{"content": "Code generation and analysis", "status": "pending", "activeForm": "Code generation and analysis in progress"},
{"content": "Run unit tests", "status": "pending", "activeForm": "Run unit tests in progress"},
{"content": "Run BDD tests", "status": "pending", "activeForm": "Run BDD tests in progress"},
{"content": "로컬 풀스택 기동 (serverpod start: server+내장 Postgres+app)", "status": "pending", "activeForm": "로컬 풀스택 기동 중"},
{"content": "로컬 백엔드 대상 통합 검증 (backend dart test -t integration / front 로컬 백엔드)", "status": "pending", "activeForm": "로컬 백엔드 통합 검증 중"},
])
MCP Integration#
| Phase | MCP Server | Purpose |
|---|---|---|
| Requirements analysis | Sequential | Complex analysis and planning |
| Backend | Serena, Context7 | Pattern analysis, Serverpod Document |
| Domain | Serena, Context7 | UseCase Pattern, Clean Architecture |
| Data | Serena, Context7 | Mixin Pattern, Drift Document |
| Presentation | Magic, Serena | UI generation, BLoC Pattern |
| Verification | Serena | Symbol search, reference verification |
Reference Agents#
Reference ${CLAUDE_PLUGIN_ROOT}/agents/feature-orchestrator-agent.md for detailed implementation rules
Examples#
Create Community Post Feature#
/cc-flutter:feature:create community Post
--location application
--caching swr
--endpoint-type app
--fields " title:String, content:String, category:PostCategory, imageUrls:List < String > ? "Create Chat Message Feature#
/cc-flutter:feature:create chat Message
--location application
--caching cache-first
--endpoint-type app
--fields " content:String, senderId:int, chatRoomId:int, readAt:DateTime? "Create Admin Dashboard Feature#
/cc-flutter:feature:create dashboard Stats
--location console
--caching none
--endpoint-type console
--fields " totalUsers:int, totalPosts:int, activeUsers:int "Success Criteria#
- ✅ All files generated in correct locations
- ✅
melos run analyzeNo errors - ✅
melos run test --scope={feature_name}Passes - ✅
patrol test --target integration_test/scenarios/{feature}_*_test.dartPasses (--with-bdd true when) - ✅ DI Registration complete
- ✅ Route Registration complete
- ✅ Components verifiable from Widgetbook (use_case 는 feature 패키지 소유 ·
path는[App]/Feature형태 · build_runner 를 feature·조립 앱 양쪽에서 실행) - ✅ BDD .feature File Gherkin 문법 준수
- ✅ 로컬 풀스택(
serverpod start: server+내장 Postgres+app) 기동 성공 — 백엔드 변경 시 - ✅ 로컬 백엔드 대상 통합 검증 통과 (backend
dart test -t integration/ front는 로컬 백엔드 대상). 3.x 폴백:docker compose up -d+dart run
Core Rules Summary#
Backend#
- Korean comments on all fields
- Follow import order
- Separate business logic into Service
Domain#
- UseCase const constructor + Optional Constructor Injection
- getIt/@injectable prohibited
- All UseCase tests required
Data#
- Serverpod Mixin
as podnamespace required - SWR/Cache-First caching strategy
Presentation#
- BLoC Event: sealed class + private implementation
- UseCase Optional Constructor Injection (
Bloc(useCase: mockUseCase)Test) - Widget
super.keylast position - BLoC/Widget tests required
- Widgetbook reflection required