LogoSkills

data-layer-agent

Clean Architecture 데이터 레이어 전문가입니다. Repository 구현, 캐싱, Drift DAO 작업에 사용합니다.

/cc-flutter:feature:data — 앱의 "데이터 창고" 담당 일꾼#

항목내용
실행 명령/cc-flutter:feature:data
별칭/data:create, /layer:data
모델sonnet
사용 도구 Read, Edit, Write, Glob, Grep
연계 스킬feature

한마디로#

앱이 화면에 보여줄 정보를 서버에서 가져오고, 잠깐 보관(캐시)하고, 기기 안에 저장하는 "데이터 창고 담당자"를 자동으로 만들어 주는 도구입니다. 마치 매장 뒤편의 창고 직원처럼 — 본사(서버)에서 물건을 받아오고, 자주 쓰는 건 가까이 쌓아두고(캐시), 필요하면 매장 내 보관함(로컬 DB)에 넣어 둡니다.

누가·언제 쓰나요#

  • Flutter 앱에 새 기능을 만드는 개발자가, 그 기능의 "데이터 처리 부분"을 만들 때 사용합니다.
  • /cc-flutter:feature:data 명령을 직접 실행하거나, 전체 기능을 한 번에 만드는 /cc-flutter:feature:create 작업의 4번째 단계에서 자동으로 호출됩니다.

무엇을 해주나요#

데이터를 다루는 데 필요한 파일들을 정해진 구조로 한꺼번에 만들어 줍니다. 만들어지는 것들:

  • Repository ({feature}_repository.dart) — 데이터를 가져오고 저장하는 핵심 창구
  • API Mixin ({feature}_api_mixin.dart) — 서버와 통신하는 부분
  • Cache ({entity}_cache_repository.dart) — 자주 쓰는 데이터를 잠깐 보관하는 곳
  • Local DB ({entity}_table.dart, {entity}_dao.dart, {feature}_database.dart) — 기기 안에 데이터를 저장하는 부분

캐시 방식은 두 가지 중에서 고릅니다: SWR(자주 바뀌거나 실시간 데이터에 적합) 또는 Cache-First(거의 안 바뀌는 데이터에 적합).

어떻게 쓰나요#

# 기본 사용 — 기능 이름과 핵심 데이터(엔티티) 이름을 지정
/cc-flutter:feature:data feature_name=post entity_name=Post
  • feature_name (필수) — 기능 모듈 이름 (snake_case, 예: post)
  • entity_name (필수) — 핵심 데이터 이름 (PascalCase, 예: Post)
  • location (선택) — 어디에 만들지: application(기본), common, console
  • caching (선택) — 캐시 방식: swr(기본), cache-first, none

안에서 무슨 일이 벌어지나요#

  1. 서버에서 데이터를 받아오는 창구(Repository)와 통신 부분(API Mixin)을 만듭니다.
  2. 서버 데이터와 앱 내부 데이터 형식을 서로 변환하는 연결 작업을 넣습니다.
  3. 선택한 캐시 방식(SWR / Cache-First)에 맞게 데이터를 잠깐 보관하는 부분을 구성합니다.
  4. 기기 안에 데이터를 저장하는 표(Table)와 저장 담당(DAO)을 만듭니다.
  5. 마지막으로, 결과가 항상 일정한 형식으로 나오는지 등 체크리스트를 점검합니다.

⚙️ 상세 옵션·실행 명세 (개발자 / AI 에이전트용)

Role#

Consistently generates Repository implementation, API Mixin (namespace import), Cache strategy, and Local DB.


Activation Conditions#

  • /cc-flutter:feature:data Activated when command is invoked
  • Invoked from /cc-flutter:feature:create orchestration Step 4

Parameters#

ParameterRequiredDescription
feature_nameFeature module name (snake_case)
entity_nameEntity name (PascalCase)
locationapplication, common, console (default: application)
cachingswr, cache-first, none (default: swr)

Generated Files#

feature/{location}/{feature_name}/lib/src/data/
├── repository/
│   ├── {feature}_repository.dart
│   ├── mixins/
│   │   └── {feature}_api_mixin.dart
│   └── repository.dart
├── cache/
│   └── {entity}_cache_repository.dart
└── local/
    ├── tables/
    │   └── {entity}_table.dart
    ├── dao/
    │   └── {entity}_dao.dart
    └── {feature}_database.dart

Core Patterns Summary#

Repository Implementation#

📚 Details: Repository Pattern

  • @LazySingleton(as: IFeatureRepository) Annotation
  • Mixin separation pattern recommended (network logic reuse)

API Mixin (Namespace required!)#

import 'package:serverpod_service/serverpod_service.dart' as serverpod;

mixin FeatureApiMixin implements IFeatureRepository {
  serverpod.ServerpodClient get client;  // ✅ 네임스페이스로 충돌 방지
}

Caching Strategy Selection#

📚 Details: Caching Pattern

PatternSelection Criteria
SWRFrequent updates, Real-time
Cache-FirstMinimize network, Static data

Critical Import Pattern#

// Repository: dependencies만 사용
import 'package:dependencies/dependencies.dart';

// Mixin: 네임스페이스 필수!
import 'package:serverpod_service/serverpod_service.dart' as serverpod;

// Domain Entity (네임스페이스 없음)
PostCategory category = PostCategory.qna;

// API DTO (네임스페이스로 충돌 방지)
serverpod.PostCategory apiCategory = serverpod.PostCategory.qna;

Checklist#

  • Repository: @LazySingleton(as: Interface) Annotation
  • API Mixin: as serverpod Namespace import
  • 양방향 DTO 변환: _mapFromDto, _categoryToDto
  • Caching strategy: SWR or Cache-First
  • Drift: Table + DAO Generation
  • Return Type: Either<Failure, T> consistency