SuperAPI AI Directory

peach-gen-store

Frontend & websites

View repository

Updated 10-15 21:34

About this skill

Frontend Store generation skill

Persona

당신은 Vue3/Pinia 상태관리 최고 전문가입니다.
- Pinia Option API 스타일 마스터
- TypeScript 타입 시스템 전문가
- API 연동과 상태 동기화 최적화
- test-data.store.ts 패턴의 완벽한 구현

Core Principles

┌─────────────────────────────────────────────────────────────────┐
│  순차 개발 전략에서 peach-gen-store의 역할                             │
│                                                                 │
│  전제조건: Backend API 완료 (TDD 통과)                          │
│                                                                 │
│  1. Backend API 스펙 기반으로 생성                              │
│  2. TDD 검증 필수 (API 연동 테스트)                             │
│  3. 출력물 = 확정된 Store 인터페이스 (다음 단계 입력)           │
│  4. AI와 티키타카로 품질 확보                                   │
│                                                                 │
│  완료 기준:                                                     │
│  ✅ vue-tsc 타입 체크 통과 (필수)                               │
│  ⚪ TDD 테스트 통과 (복잡한 클라이언트 로직 있을 때만)          │
└─────────────────────────────────────────────────────────────────┘

Input Method

/peach-gen-store [테이블명] [옵션]

Option

Option Default Description
file N File upload feature (Y/N)
storeTdd N Generate Store TDD actions (Y/N) - Backend controllerTdd=Y required

Workflow

Step 1: Check Backend API + detect module location

# Backend 모듈 위치 감지 (modules-* 분리 구조 대응)
ls -d api/src/modules*/[모듈명]/ 2>/dev/null

# API 스펙 확인 (Type 파일)
cat api/src/modules*/[모듈명]/type/[모듈명].type.ts 2>/dev/null

# Frontend 모듈 구조 확인
ls -d front/src/modules*/

# Frontend 상수 확인
ls front/src/modules/_common/constants/ 2>/dev/null

Create in the Frontend corresponding path matching the Backend module path:

  • api/src/modules/[모듈명]/ → front/src/modules/[모듈명]/
  • api/src/modules-domain/[모듈명]/ → front/src/modules-domain/[모듈명]/
  • api/src/modules-external/[모듈명]/ → front/src/modules-domain/[모듈명]/ (frontend is unified under domain)

_common/constants/ If present, consider utilizing constants in the frontend as well.

If there is no Backend:

⚠️ Backend API가 없습니다!
먼저 /peach-gen-backend [테이블명] 실행하세요.

Step 1.5: Domain analysis (Analyze)

Compare and analyze the Backend API types and the test-data Store:

  1. API spec comparison: number of endpoints compared to test-data, response structure, special actions
  2. State complexity assessment: whether a simple CRUD Store vs multiple lists/filter state/derived state is needed
  3. Adaptation decision:
    • Must Follow → as-is (Pinia Option API, type principles, module boundaries)
    • May Adapt → domain-tailored (additional state fields, action separation)
  4. Structure proposal (May Suggest): If the analysis result shows a structure different from the guide code is more suitable, propose it to the user:
    • Store file separation (e.g., read-only Store + management-only Store)
    • Derived state (computed) structure proposal
    • Apply after user confirmation. Do not violate Must Follow.

Step 2: Code generation

Reference template (test-data):

  • front/src/modules/test-data/type/test-data.type.ts
  • front/src/modules/test-data/store/test-data.store.ts
  • front/src/modules/test-data/test/test-data.test.ts

Step 3: TDD verification (required)

# 타입 체크
cd front && bunx vue-tsc --noEmit

# 테스트 실행 (있는 경우)
cd front && bun test src/modules/[모듈명]/test/

Step 4: Back-and-forth

타입 에러 또는 테스트 실패 시:
1. 에러 원인 분석
2. 코드 수정
3. 다시 검증
4. 통과할 때까지 반복

⚠️ 타입 체크 통과 없이 완료 선언 금지!

Generated file structure

front/src/[감지된 modules 경로]/[모듈명]/
├── type/[모듈명].type.ts    ← Entity, DTO 타입
├── store/[모듈명].store.ts  ← Pinia Store
└── test/[모듈명].test.ts    ← TDD 테스트 (선택적)

The module creation path follows the Backend corresponding path detected in Step 1. Default: front/src/modules/[모듈명]/


Checklist by layer

Type layer

  • Entity Interface (same as backend)
  • ListItem Interface (for lists, nIndex added)
  • SearchDto Interface (search parameters)
  • PagingDto Interface (paging, sortData added)
  • InsertDto Interface (for registration)
  • UpdateDto Interface (for updates)
  • File Interface (when file=Y)

Store layer

State

  • listData: ListItem[] (list data)
  • listTotalRow: number (total count)
  • detailData: Entity | null (detail data)

Actions (Detail)

  • detailDataInit (detail data initialization)
  • paging (paged list) - useApi().get('/[모듈명]', params)
  • list (full list) - useApi().get('/[모듈명]/list', params)
  • detail (detail retrieval) - useApi().get('/[모듈명]/' + seq)
  • cursorList (cursor paging) - useApi().get('/[모듈명]/cursor-list')
  • insert (registration) - useApi().post('/[모듈명]', data)
  • update (update) - useApi().put('/[모듈명]/' + seq, data)
  • updateUse (activate/deactivate) - useApi().patch('/[모듈명]/use')
  • softDelete (delete) - useApi().patch('/[모듈명]/delete')
  • hardDelete (physical delete, for testing) - useApi().delete('/[모듈명]/' + seq)

TDD Operations (only when storeTdd=Y)

→ See the "Store TDD" section below

File features (file=Y)

  • uploadFileLocal (local file upload)
  • uploadFileS3 (S3 file upload)
  • getDownloadUrl (download URL)

TDD tests (only when storeTdd=Y)

→ See the "Store TDD" section below


Pattern rules

// ✅ Pinia Option API 스타일 (권장)
export const use[모듈명]Store = defineStore('[모듈명]', {
  state: () => ({
    listData: [] as ListItem[],
    listTotalRow: 0,
    detailData: null as Entity | null,
  }),
  actions: {
    async paging(params: PagingDto) {
      const { $api } = useNuxtApp();
      const res = await $api.get('[모듈명]/paging', { params });
      if (res.value?.data) {
        this.listData = res.value.data.list;
        this.listTotalRow = res.value.data.totalRow;
      }
      return res;
    },
    // ...
  },
});

// ❌ Setup 스타일 (사용 금지)
export const use[모듈명]Store = defineStore('[모듈명]', () => {
  // ...
});

file option handling

file=N (default)

  • Store: exclude file-related functions
    • uploadFileLocal ❌
    • uploadFileS3 ❌
    • getDownloadUrl ❌

file=Y

  • Store: include file-related functions
    • uploadFileLocal ✅
    • uploadFileS3 ✅
    • getDownloadUrl ✅
  • Type: add File interface

Bounded Autonomy (autonomous adaptation rules)

The guide code is a basic reference skeleton and is not a mandatory standard. If the AI judges that a better structure fits the domain characteristics, it adjusts autonomously. The Must Follow and "no abstraction for a single use site" principles must still be observed, and adjusted items and reasons must be recorded in the completion report. For detailed principles, see peach-setup-ui-proto/references/04-bounded-autonomy.md (Frontend) or peach-setup-harness/references/05-bounded-autonomy.md (Backend).

Must Follow (absolute compliance)

  • Pinia Option API (Setup style prohibited)
  • Types: for core domain types such as Entity/InsertDto/UpdateDto, unnecessary optional (?), null, undefined prohibited
    • Search conditions, function option parameters, and framework state representations are explicitly allowed
  • Module boundaries: _common만 import
  • Store standard state: listData, listTotalRow, detailData

May Adapt (supplement after analysis)

  • Additional state fields (domain-specific filters, multiple lists)
  • Action separation approach (complex data transformation logic)
  • Error handling implementation details

May Suggest (confirm with user after suggesting)

  • Store file separation (e.g., read-only + management-only)
  • Derived state (computed) structure suggestion
  • Composite filter state design

When suggesting: present the reason to the user and apply after confirmation. Must not violate Must Follow.

Adapt conditions

When supplementing, always: (1) explain the reason (2) do not violate Must Follow (3) pass vue-tsc


Completion conditions

┌─────────────────────────────────────────────────────────────────┐
│  ✅ 완료 체크리스트                                              │
│                                                                 │
│  □ bunx vue-tsc --noEmit 통과 (필수)                             │
│  □ TDD 테스트 통과 (storeTdd=Y인 경우만)                        │
│                                                                 │
│  위 조건 모두 통과해야 완료!                                     │
│  실패 시 AI와 티키타카로 수정                                   │
└─────────────────────────────────────────────────────────────────┘

Post-completion guidance

🎉 Frontend Store 생성 완료!

생성된 파일:
├── front/src/[감지된 modules 경로]/[모듈명]/
│   ├── type/[모듈명].type.ts
│   └── store/[모듈명].store.ts

검증 결과:
✅ 타입 체크 통과

📌 확정된 Store 인터페이스:
- use[모듈명]Store()
  - state: listData, listTotalRow, detailData
  - actions: paging, list, detail, insert, update, updateUse, softDelete

다음 단계:
→ /peach-gen-ui [모듈명] 실행하여 Frontend UI 생성

Store TDD (only when storeTdd=Y)

→ test-pattern.md See details

Prerequisites: Backend controllerTdd=Y required Most Stores are API Wrappers, so TDD is unnecessary. Backend TDD is sufficient.

TDD Actions

  • initTdd (create TDD data) - useApi().post('/[모듈명]/tdd/init')
  • cleanupTdd (clean up TDD) - useApi().delete('/[모듈명]/tdd/cleanup/' + seq)

Integrated workflow test

  • beforeAll: VitestSetup.initializeTestEnvironment(), sign()
  • it('integrated workflow'): single test in runner style
    1. Create TDD data (initTdd)
    2. Detail view (detail)
    3. Update data (update)
    4. Change use status (updateUse)
    5. List/paging view
    6. Cursor paging (cursorList)
    7. File upload/update (file=Y)
    8. Logical delete (softDelete)
    9. TDD physical delete (cleanupTdd)
  • finally: cleanup on exception

See detailed guide

For detailed patterns per layer, see the references folder:


⚠️ Conditional reference guide (token saving)

Important: Read only the reference files for the selected option! Do not load all references at once.

Required references (always)

File Purpose
store-pattern.md Pinia Store structure
type-pattern.md Entity, DTO type definitions

Additional references per option

Option Files to read
file=Y file-option.md
storeTdd=Y test-pattern.md

Reference

  • Guide code (required): front/src/modules/test-data/
  • Backend Type: api/src/modules/[모듈명]/type/

⚠️ Important: Reference the test-data guide code as the baseline skeleton, but adapt it within the scope of Bounded Autonomy to match domain characteristics