LogoSkills

data-layer-agent

Clean Architecture Data Layer specialist. Used for Repository implementation, caching, and Drift DAO work

ํ•ญ๋ชฉ๋‚ด์šฉ
Invoke/feature:data
Aliases/data:create, /layer:data
ToolsRead, Edit, Write, Glob, Grep
Modelsonnet
Skillsfeature

/feature:data โ€” ์•ฑ์˜ "๋ฐ์ดํ„ฐ ์ฐฝ๊ณ " ๋‹ด๋‹น ์ผ๊พผ#

ํ•œ๋งˆ๋””๋กœ#

์•ฑ์ด ํ™”๋ฉด์— ๋ณด์—ฌ์ค„ ์ •๋ณด๋ฅผ ์„œ๋ฒ„์—์„œ ๊ฐ€์ ธ์˜ค๊ณ , ์ž ๊น ๋ณด๊ด€(์บ์‹œ)ํ•˜๊ณ , ๊ธฐ๊ธฐ ์•ˆ์— ์ €์žฅํ•˜๋Š” "๋ฐ์ดํ„ฐ ์ฐฝ๊ณ  ๋‹ด๋‹น์ž"๋ฅผ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด ์ฃผ๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ๋งˆ์น˜ ๋งค์žฅ ๋’คํŽธ์˜ ์ฐฝ๊ณ  ์ง์›์ฒ˜๋Ÿผ โ€” ๋ณธ์‚ฌ(์„œ๋ฒ„)์—์„œ ๋ฌผ๊ฑด์„ ๋ฐ›์•„์˜ค๊ณ , ์ž์ฃผ ์“ฐ๋Š” ๊ฑด ๊ฐ€๊นŒ์ด ์Œ“์•„๋‘๊ณ (์บ์‹œ), ํ•„์š”ํ•˜๋ฉด ๋งค์žฅ ๋‚ด ๋ณด๊ด€ํ•จ(๋กœ์ปฌ DB)์— ๋„ฃ์–ด ๋‘ก๋‹ˆ๋‹ค.

๋ˆ„๊ฐ€ยท์–ธ์ œ ์“ฐ๋‚˜์š”#

  • Flutter ์•ฑ์— ์ƒˆ ๊ธฐ๋Šฅ์„ ๋งŒ๋“œ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€, ๊ทธ ๊ธฐ๋Šฅ์˜ "๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„"์„ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • /feature:data ๋ช…๋ น์„ ์ง์ ‘ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜, ์ „์ฒด ๊ธฐ๋Šฅ์„ ํ•œ ๋ฒˆ์— ๋งŒ๋“œ๋Š” /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(๊ฑฐ์˜ ์•ˆ ๋ฐ”๋€Œ๋Š” ๋ฐ์ดํ„ฐ์— ์ ํ•ฉ).

์–ด๋–ป๊ฒŒ ์“ฐ๋‚˜์š”#

# ๊ธฐ๋ณธ ์‚ฌ์šฉ โ€” ๊ธฐ๋Šฅ ์ด๋ฆ„๊ณผ ํ•ต์‹ฌ ๋ฐ์ดํ„ฐ(์—”ํ‹ฐํ‹ฐ) ์ด๋ฆ„์„ ์ง€์ •
/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#

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

Parameters#

ParameterRequiredDescription
feature_nameโœ…Feature module name (snake_case)
entity_nameโœ…Entity name (PascalCase)
locationโŒapplication, common, console (default: application)
cachingโŒswr, 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