| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| Invoke | /feature:presentation |
| Aliases | /presentation:create, /layer:presentation |
| Tools | Read, Edit, Write, Glob, Grep |
| Model | sonnet |
| Skills | feature |
/feature:presentation โ ํ๋ฉด(UI) ๋ง๋ค์ด์ฃผ๋ ์ผ๊พผ#
ํ๋ง๋๋ก#
์ฑ์์ ์ฌ์ฉ์ ๋์ ๋ณด์ด๋ ํ๋ฉด ๋ถ๋ถ์ ์ ํด์ง ๊ท์น๋๋ก ์๋์ผ๋ก ๋ง๋ค์ด์ฃผ๋ ์ ๋ด ์ผ๊พผ์ ๋๋ค. ์ง์ผ๋ก ์น๋ฉด ๊ณจ์กฐยท๋ฐฐ๊ด(๋ฐ์ดํฐ)์ด ์๋๋ผ ๋์ ๋ณด์ด๋ ์ธํ ๋ฆฌ์ด์ ์ค์์น(ํ๋ฉดยท๋ฒํผ) ๋ฅผ ํ์ค ์์ฌ๋ก ๋๊ฐ์ด ์๊ณตํด ์ฃผ๋ ์ญํ ์ด์์.
๋๊ฐยท์ธ์ ์ฐ๋์#
- ์ ๊ธฐ๋ฅ์ ํ๋ฉด(ํ์ด์ง)๊ณผ ๋ฒํผยท์นด๋ ๊ฐ์ ์์ ฏ์ ๋ง๋ค์ด์ผ ํ ๋
- ํ๋ฉด ์ํ ๊ด๋ฆฌ(BLoC)์ ํ๋ฉด ์ ํ(Route)์ ์ผ๊ด๋ ๋ฐฉ์์ผ๋ก ๊น๊ณ ์ถ์ ๋
- ์ ์ฒด ๊ธฐ๋ฅ ์๋ ์์ฑ(
/feature:create)์ ๋ง์ง๋ง 5๋จ๊ณ๋ก ์๋ ํธ์ถ๋ ๋
๋ฌด์์ ํด์ฃผ๋์#
๊ธฐ๋ฅ ์ด๋ฆ ํ๋๋ง ์ฃผ๋ฉด, ํ๋ฉด ๊ด๋ จ ํ์ผ ๋ฌถ์์ ํ ๋ฒ์ ๋ง๋ค์ด ์ค๋๋ค. ์ค์ ๋ก ์๊ธฐ๋ ๊ฒ:
-
์ํ ๊ด๋ฆฌ ์ฝ๋(BLoC) โ
{feature}_list_bloc.dart,..._event.dart,..._state.dart - ํ๋ฉด(Page) โ
{feature}_page.dart - ์์ ฏ(๋ถํ) โ
{entity}_card.dart - ํ๋ฉด ์ ํ(Route) โ
{feature}_route.dart - ํ ์คํธ + Widgetbook โ ํ๋ฉด์ด ์ ๋๋ก ๋์ํ๋์ง ํ์ธํ๋ ์๋ ๊ฒ์ฌ ํ์ผ
์ด ๋ชจ๋ ๊ฒ์ด ํ์ฌ ํ์ค ํจํด(BLoC, Clean Architecture ๊ท์น)์ ๋ง์ถฐ ์ผ๊ด๋๊ฒ ์์ฑ๋ฉ๋๋ค.
์ด๋ป๊ฒ ์ฐ๋์#
# ๊ธฐ๋ณธ: ๊ธฐ๋ฅ ์ด๋ฆ๊ณผ ์ํฐํฐ ์ด๋ฆ์ ๋๊น๋๋ค
/feature:presentation
# ๋ณ์นญ์ผ๋ก๋ ํธ์ถ ๊ฐ๋ฅ
/presentation:create
/layer:presentation
๋๊ธธ ์ ์๋ ๊ฐ:
feature_name(ํ์) โ ๊ธฐ๋ฅ ๋ชจ๋ ์ด๋ฆ (snake_case ์:user_list)entity_name(ํ์) โ ์ํฐํฐ ์ด๋ฆ (PascalCase ์:User)-
location(์ ํ) โapplication(๊ธฐ๋ณธ) /common/console์ค ์ด๋์ ๋ง๋ค์ง pages(์ ํ) โ ๋ง๋ค ํ์ด์ง ๋ชฉ๋ก
์์์ ๋ฌด์จ ์ผ์ด ๋ฒ์ด์ง๋์#
-
์ํ ๊ด๋ฆฌ(BLoC) ์์ฑ โ ํ๋ฉด์ด ๊ฐ์ง ์ ์๋ ์ฌ๊ฑด(Event)๊ณผ ์ํ(State)๋ฅผ ํ์ค ํํ๋ก ๋ง๋ค๊ณ , ๋น๋๊ธฐ ์ฒ๋ฆฌ ํ ์์ ์ ๊ฒ(
isClosed)์ ๋ฃ์ต๋๋ค. - ํ๋ฉดยท์์ ฏ ์์ฑ โ ํ์ด์ง๋ฅผ BlocProvider๋ก ๊ฐ์ธ๊ณ , ์นด๋ ๊ฐ์ ๋ถํ ์์ ฏ์ ์ ํด์ง ๊ท์น์ผ๋ก ๋ง๋ญ๋๋ค.
- ํ๋ฉด ์ ํ(Route) ์์ฑ โ
@TypedGoRoute๋ฐฉ์์ผ๋ก ํ๋ฉด ์ด๋ ๊ฒฝ๋ก๋ฅผ ์ ์ํฉ๋๋ค. -
๊ธ์ง ํจํด ์ฐจ๋จ โ ์๋ ๋ฐฉ์(
Key? key)์ด๋ ์๋๊ฒฝ๋ก import, BLoC์ด ๋ฐ์ดํฐ ์ ์ฅ์์ ์ง์ ์๋๋ ์๋ชป๋ ๊ตฌ์กฐ๋ฅผ ๋ง์ต๋๋ค. - ์์ฒด ์ ๊ฒ(์ฒดํฌ๋ฆฌ์คํธ) + ํ ์คํธ โ ๋ง๋ ๊ฒฐ๊ณผ๊ฐ ๊ท์น์ ๋ง๋์ง ํญ๋ชฉ๋ณ๋ก ํ์ธํ๊ณ ํ ์คํธ ์ฝ๋๊น์ง ์์ฑํฉ๋๋ค.
โ๏ธ ์์ธ ์ต์ ยท์คํ ๋ช ์ธ (๊ฐ๋ฐ์ / AI ์์ด์ ํธ์ฉ)
Role#
Consistently generates BLoC (Event sealed class, State), Page/Widget, Route, tests, and Widgetbook.
Activation Conditions#
/feature:presentationActivated when command is invoked- Invoked from
/feature:createorchestration Step 5
Parameters#
| Parameter | Required | Description |
|---|---|---|
feature_name | โ | Feature module name (snake_case) |
entity_name | โ | Entity name (PascalCase) |
location | โ | application, common, console (default: application) |
pages | โ | To generate Page List |
Generated Files#
feature/{location}/{feature_name}/lib/src/presentation/
โโโ bloc/
โ โโโ {feature}_list/
โ โโโ {feature}_list_bloc.dart
โ โโโ {feature}_list_event.dart
โ โโโ {feature}_list_state.dart
โโโ page/
โ โโโ {feature}_page.dart
โโโ widget/
โ โโโ {entity}_card.dart
โโโ route/
โโโ {feature}_route.dart
# Tests ํ์ผ
feature/{location}/{feature_name}/test/presentation/
โโโ bloc/{feature}_list_bloc_test.dart
โโโ page/{feature}_page_test.dartCore Patterns Summary#
BLoC Event/State#
๐ Details: BLoC Pattern
- Event:
sealed class+ factory constructor + private Implementation - State:
sealed classor Freezed union type isClosedCheck: Required after await, before emit!
UseCase Integration Pattern#
๐ Details: UseCase Pattern
| Pattern | Description |
|---|---|
| Optional Constructor Injection | โ Standard pattern - Direct creation/Test without getIt |
Widget Generation Rules#
const MyWidget({
required this.data,
this.onTap,
super.key, // โ
Always last
});
Route Pattern#
@TypedGoRoute<FeatureRoute>(path: '/feature')
class FeatureRoute extends GoRouteData { ... }
Prohibited Patterns#
// โ Key? key ํจํด ๊ธ์ง (super.key ์ฌ์ฉ)
const MyWidget({Key? key, required this.data}) : super(key: key);
// โ Relative path import prohibited
import '../domain/entity/user.dart';
// โ BLoC์์ Repository ์ง์ ์ ๊ทผ ๊ธ์ง (UseCase ํตํด์๋ง)
class MyBloc {
final IRepository _repository; // UseCase ์ฐํ!
}
Checklist#
Common (Required)#
- Event: sealed class + factory + private implementation pattern
- State: sealed class or Freezed union
- BLoC:
if (isClosed) return;Check (await After Required) - Page: BlocProvider wrapping
- Widget:
super.keylast position - Route: @TypedGoRoute annotation
- package import only (relative path prohibited)
Tests#
- BLoC Test Writing
- Widget Test Writing
- Widgetbook UseCase Writing
UseCase Patterns#
- Optional Constructor Injection:
Bloc(useCase: mockUseCase)Direct injection Test