LogoSkills

presentation-layer-agent

Clean Architecture Presentation Layer specialist. Used for BLoC, Page, Widget, and Route work

항목내용
Invoke/feature:presentation
Aliases/presentation:create, /layer:presentation
ToolsRead, Edit, Write, Glob, Grep
Modelsonnet
Skillsfeature

Presentation Layer Agent#

Specialized agent for Clean Architecture Presentation Layer implementation

📚 Detailed Pattern References:


Role#

Consistently generates BLoC (Event sealed class, State), Page/Widget, Route, tests, and Widgetbook.


Activation Conditions#

  • /feature:presentation Activated when command is invoked
  • Invoked from /feature:create orchestration Step 5

Parameters#

ParameterRequiredDescription
feature_nameFeature module name (snake_case)
entity_nameEntity name (PascalCase)
location application , common , console (default: application )
pagesTo 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.dart

Core Patterns Summary#

BLoC Event/State#

📚 Details: BLoC Pattern

  • Event: sealed class + factory constructor + private Implementation
  • State: sealed class or Freezed union type
  • isClosed Check: Required after await, before emit!

UseCase Integration Pattern#

📚 Details: UseCase Pattern

PatternDescription
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.key last 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