Initial commit
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
785
.claude/commands/appkit.design.md
Normal file
785
.claude/commands/appkit.design.md
Normal file
@@ -0,0 +1,785 @@
|
||||
# appkit.design
|
||||
|
||||
**개발 준비 - API, ERD, 기술 스펙 설계**
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
**This is Step 7 of the logical thinking 7-step workflow**:
|
||||
|
||||
```
|
||||
논리적 사고 7단계:
|
||||
1. /appkit.new → 아이디어 스케치 (어떤 서비스인지?)
|
||||
2. /appkit.spec → 기능 구체화 (뭐가 필요할까? 누가 쓸까?)
|
||||
3. /appkit.customer → 고객 스토리 (고객의 하루, 고민, 해결)
|
||||
4. /appkit.sales → 세일즈 랜딩 구성 (어떻게 설득할까?)
|
||||
5. /appkit.mvp → MVP 범위 정하기 (최소한으로 검증하려면?)
|
||||
6. /appkit.merge → 기획 정돈 (흩어진 기획 통합)
|
||||
7. /appkit.design → 개발 준비 (API, ERD, 기술 스펙) ← YOU ARE HERE
|
||||
```
|
||||
|
||||
## Purpose
|
||||
|
||||
merge에서 정돈된 기획을 기반으로, 실제 개발에 필요한 **기술 스펙**을 생성합니다.
|
||||
기획 레벨(merge)과 구현 레벨(개발) 사이의 다리 역할을 합니다.
|
||||
|
||||
**핵심 질문**: "개발자에게 뭘 전달해야 하나? 어떻게 만들까?"
|
||||
|
||||
---
|
||||
|
||||
## When to Use
|
||||
|
||||
- `/appkit.merge`로 기획을 정돈한 후 (Step 6 완료 후)
|
||||
- 개발 시작 직전
|
||||
- 기술 스펙이 필요할 때
|
||||
- ERD, API 설계가 필요할 때
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
/appkit.design
|
||||
/appkit.design "persona 도메인 집중"
|
||||
/appkit.design "API 우선"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## What I'll Do
|
||||
|
||||
### 1. 소스 문서 읽기
|
||||
|
||||
**읽을 파일들**:
|
||||
- `docs/appkit/merge/concept-map.md` (통합 컨셉)
|
||||
- `docs/appkit/merge/consolidated-specs.md` (통합 스펙)
|
||||
- `docs/appkit/merge/journey-feature-map.md` (기능 매핑)
|
||||
- `docs/appkit/mvp-scope.md` (MVP 범위)
|
||||
|
||||
### 2. 데이터 엔티티 설계 (ERD)
|
||||
|
||||
**Output**: `docs/appkit/design/entities.md`
|
||||
|
||||
```markdown
|
||||
# Data Entity Design (ERD)
|
||||
|
||||
*생성 기준: concept-map.md, consolidated-specs.md*
|
||||
*생성일: 2025-11-20*
|
||||
|
||||
---
|
||||
|
||||
## Entity Relationship Diagram
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
Persona ||--o{ Content : generates
|
||||
Content ||--|| Post : becomes
|
||||
Schedule ||--o{ Post : manages
|
||||
|
||||
Persona {
|
||||
int id PK
|
||||
string name
|
||||
int age
|
||||
string personality
|
||||
string tone
|
||||
string language
|
||||
json style_rules
|
||||
datetime created_at
|
||||
}
|
||||
|
||||
Content {
|
||||
int id PK
|
||||
int persona_id FK
|
||||
string topic
|
||||
string image_url
|
||||
text caption
|
||||
json hashtags
|
||||
enum status
|
||||
datetime generated_at
|
||||
}
|
||||
|
||||
Post {
|
||||
int id PK
|
||||
int content_id FK
|
||||
string platform
|
||||
datetime scheduled_at
|
||||
datetime posted_at
|
||||
enum status
|
||||
}
|
||||
|
||||
Schedule {
|
||||
int id PK
|
||||
time execution_time
|
||||
bool is_active
|
||||
json target_personas
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Entity Details
|
||||
|
||||
### Entity: Persona
|
||||
|
||||
**Purpose**: 캐릭터별 페르소나 정보 저장
|
||||
|
||||
**Table Name**: `personas`
|
||||
|
||||
**Fields**:
|
||||
|
||||
| Field | Type | Constraints | Description |
|
||||
|-------|------|-------------|-------------|
|
||||
| id | INT | PK, AUTO_INCREMENT | 페르소나 고유 ID |
|
||||
| name | VARCHAR(100) | NOT NULL | 캐릭터 이름 |
|
||||
| age | INT | NOT NULL | 캐릭터 나이 |
|
||||
| personality | TEXT | NOT NULL | 성격 설명 |
|
||||
| tone | VARCHAR(50) | NOT NULL | 말투 (밝은/전문가/친근한) |
|
||||
| language | VARCHAR(10) | NOT NULL | 언어 (ko/en/ja) |
|
||||
| style_rules | JSON | NULL | 스타일 규칙 (이모티콘, 반말/존댓말) |
|
||||
| created_at | DATETIME | NOT NULL, DEFAULT NOW() | 생성 시간 |
|
||||
|
||||
**Relationships**:
|
||||
- `Persona.id` → `Content.persona_id` (1:N)
|
||||
|
||||
**Business Rules**:
|
||||
- 한 페르소나는 여러 콘텐츠 생성 가능
|
||||
- 페르소나 삭제 시 생성된 콘텐츠는 보존 (FK: RESTRICT)
|
||||
|
||||
**Sample Data**:
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"name": "밝은 20대 여성",
|
||||
"age": 25,
|
||||
"personality": "긍정적이고 친근한 성격",
|
||||
"tone": "밝은",
|
||||
"language": "ko",
|
||||
"style_rules": {
|
||||
"emoji_frequency": "high",
|
||||
"formality": "casual",
|
||||
"hashtag_style": "trendy"
|
||||
},
|
||||
"created_at": "2025-01-01T10:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Entity: Content
|
||||
|
||||
**Purpose**: AI가 생성한 콘텐츠 저장
|
||||
|
||||
**Table Name**: `contents`
|
||||
|
||||
**Fields**:
|
||||
|
||||
| Field | Type | Constraints | Description |
|
||||
|-------|------|-------------|-------------|
|
||||
| id | INT | PK, AUTO_INCREMENT | 콘텐츠 고유 ID |
|
||||
| persona_id | INT | FK → personas.id, NOT NULL | 생성한 페르소나 |
|
||||
| topic | VARCHAR(200) | NOT NULL | 주제 |
|
||||
| image_url | VARCHAR(500) | NOT NULL | 이미지 URL (Midjourney) |
|
||||
| caption | TEXT | NOT NULL | 캡션 (GPT 생성) |
|
||||
| hashtags | JSON | NULL | 해시태그 배열 |
|
||||
| status | ENUM | NOT NULL | draft, approved, posted |
|
||||
| generated_at | DATETIME | NOT NULL, DEFAULT NOW() | 생성 시간 |
|
||||
|
||||
**Enums**:
|
||||
- `status`: `draft` (생성됨), `approved` (검토 완료), `posted` (포스팅됨)
|
||||
|
||||
**Relationships**:
|
||||
- `Content.persona_id` → `Persona.id` (N:1)
|
||||
- `Content.id` → `Post.content_id` (1:1)
|
||||
|
||||
**Business Rules**:
|
||||
- 하나의 콘텐츠는 하나의 포스트로 변환
|
||||
- 캡션 길이: 최소 50자, 최대 2200자 (Instagram 제한)
|
||||
|
||||
---
|
||||
|
||||
### Entity: Post
|
||||
|
||||
**Purpose**: 실제 포스팅 기록
|
||||
|
||||
**Table Name**: `posts`
|
||||
|
||||
**Fields**:
|
||||
|
||||
| Field | Type | Constraints | Description |
|
||||
|-------|------|-------------|-------------|
|
||||
| id | INT | PK, AUTO_INCREMENT | 포스트 고유 ID |
|
||||
| content_id | INT | FK → contents.id, UK, NOT NULL | 연결된 콘텐츠 |
|
||||
| platform | VARCHAR(50) | NOT NULL | instagram, twitter, etc |
|
||||
| scheduled_at | DATETIME | NOT NULL | 예약 시간 |
|
||||
| posted_at | DATETIME | NULL | 실제 포스팅 시간 |
|
||||
| status | ENUM | NOT NULL | pending, posted, failed |
|
||||
|
||||
**Enums**:
|
||||
- `status`: `pending` (대기), `posted` (완료), `failed` (실패)
|
||||
|
||||
**Relationships**:
|
||||
- `Post.content_id` → `Content.id` (1:1)
|
||||
|
||||
**Business Rules**:
|
||||
- 하나의 콘텐츠는 하나의 포스트
|
||||
- 포스팅 실패 시 재시도 로직 필요
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
- **Total Entities**: 4 (Persona, Content, Post, Schedule)
|
||||
- **Total Relationships**: 3 (1:N, 1:1)
|
||||
- **Foreign Keys**: 3
|
||||
|
||||
**Entity Dependencies** (구현 순서):
|
||||
1. **No dependencies**: Persona, Schedule (먼저 구현)
|
||||
2. **Depends on 1**: Content (needs Persona)
|
||||
3. **Depends on 2**: Post (needs Content)
|
||||
```
|
||||
|
||||
### 3. API 엔드포인트 설계
|
||||
|
||||
**Output**: `docs/appkit/design/apis.md`
|
||||
|
||||
```markdown
|
||||
# API Endpoint Design
|
||||
|
||||
*생성 기준: entities.md, consolidated-specs.md*
|
||||
*API Style: RESTful*
|
||||
*Base URL: `/api/v1`*
|
||||
|
||||
---
|
||||
|
||||
## 1. Persona APIs
|
||||
|
||||
### 1.1 Create Persona
|
||||
|
||||
**Endpoint**: `POST /personas`
|
||||
|
||||
**Description**: 새로운 페르소나 생성
|
||||
|
||||
**Request Body**:
|
||||
```json
|
||||
{
|
||||
"name": "밝은 20대 여성",
|
||||
"age": 25,
|
||||
"personality": "긍정적이고 친근한 성격",
|
||||
"tone": "밝은",
|
||||
"language": "ko",
|
||||
"style_rules": {
|
||||
"emoji_frequency": "high",
|
||||
"formality": "casual"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Success Response** (201 Created):
|
||||
```json
|
||||
{
|
||||
"persona": {
|
||||
"id": 1,
|
||||
"name": "밝은 20대 여성",
|
||||
"age": 25,
|
||||
"tone": "밝은",
|
||||
"created_at": "2025-01-01T10:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Error Responses**:
|
||||
- 400 Bad Request: Validation failed
|
||||
|
||||
**Related Spec**: 001-persona/spec.md
|
||||
**Related Entity**: Persona
|
||||
|
||||
---
|
||||
|
||||
### 1.2 List Personas
|
||||
|
||||
**Endpoint**: `GET /personas`
|
||||
|
||||
**Description**: 모든 페르소나 조회
|
||||
|
||||
**Success Response** (200 OK):
|
||||
```json
|
||||
{
|
||||
"personas": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "밝은 20대 여성",
|
||||
"age": 25,
|
||||
"tone": "밝은"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "전문가 30대 남성",
|
||||
"age": 32,
|
||||
"tone": "전문가"
|
||||
}
|
||||
],
|
||||
"total": 2
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Content APIs
|
||||
|
||||
### 2.1 Generate Content
|
||||
|
||||
**Endpoint**: `POST /contents/generate`
|
||||
|
||||
**Description**: AI로 콘텐츠 자동 생성
|
||||
|
||||
**Request Body**:
|
||||
```json
|
||||
{
|
||||
"persona_id": 1,
|
||||
"topic": "오늘의 운동 루틴",
|
||||
"auto_post": false
|
||||
}
|
||||
```
|
||||
|
||||
**Success Response** (201 Created):
|
||||
```json
|
||||
{
|
||||
"content": {
|
||||
"id": 101,
|
||||
"persona_id": 1,
|
||||
"topic": "오늘의 운동 루틴",
|
||||
"image_url": "https://midjourney.com/...",
|
||||
"caption": "오늘도 열심히 운동했어요! 💪...",
|
||||
"hashtags": ["운동", "헬스", "루틴"],
|
||||
"status": "draft",
|
||||
"generated_at": "2025-01-01T07:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Business Logic**:
|
||||
1. persona_id로 페르소나 정보 조회
|
||||
2. Midjourney API 호출 (이미지 생성)
|
||||
3. GPT API 호출 (캡션 생성, 페르소나 톤 반영)
|
||||
4. 생성된 콘텐츠 DB 저장 (status: draft)
|
||||
5. auto_post = true면 자동 포스팅 예약
|
||||
|
||||
**Error Responses**:
|
||||
- 404 Not Found: Persona not found
|
||||
- 502 Bad Gateway: Midjourney/GPT API 실패
|
||||
- 503 Service Unavailable: API rate limit 초과
|
||||
|
||||
**Related Spec**: 002-content/spec.md
|
||||
**Related Entity**: Content, Persona
|
||||
|
||||
---
|
||||
|
||||
### 2.2 List Contents
|
||||
|
||||
**Endpoint**: `GET /contents`
|
||||
|
||||
**Query Parameters**:
|
||||
```
|
||||
?persona_id=1 // Filter by persona
|
||||
&status=draft // Filter by status
|
||||
&date=2025-01-01 // Filter by generation date
|
||||
&limit=20
|
||||
&page=1
|
||||
```
|
||||
|
||||
**Success Response** (200 OK):
|
||||
```json
|
||||
{
|
||||
"contents": [
|
||||
{
|
||||
"id": 101,
|
||||
"persona_id": 1,
|
||||
"topic": "오늘의 운동 루틴",
|
||||
"image_url": "https://...",
|
||||
"status": "draft",
|
||||
"generated_at": "2025-01-01T07:00:00Z"
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"total": 45,
|
||||
"page": 1,
|
||||
"limit": 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Schedule APIs
|
||||
|
||||
### 3.1 Create Schedule
|
||||
|
||||
**Endpoint**: `POST /schedules`
|
||||
|
||||
**Description**: 자동 생성 스케줄 등록
|
||||
|
||||
**Request Body**:
|
||||
```json
|
||||
{
|
||||
"execution_time": "07:00",
|
||||
"target_personas": [1, 2, 3],
|
||||
"is_active": true
|
||||
}
|
||||
```
|
||||
|
||||
**Success Response** (201 Created):
|
||||
```json
|
||||
{
|
||||
"schedule": {
|
||||
"id": 1,
|
||||
"execution_time": "07:00",
|
||||
"target_personas": [1, 2, 3],
|
||||
"is_active": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Business Logic**:
|
||||
- Cron job 생성 (매일 07:00 실행)
|
||||
- 실행 시 target_personas의 각 페르소나로 콘텐츠 생성
|
||||
- 생성 후 자동 포스팅
|
||||
|
||||
**Related Spec**: 003-schedule/spec.md
|
||||
**Related Entity**: Schedule
|
||||
|
||||
---
|
||||
|
||||
## 4. Post APIs
|
||||
|
||||
### 4.1 Create Post
|
||||
|
||||
**Endpoint**: `POST /posts`
|
||||
|
||||
**Description**: 콘텐츠를 포스팅으로 예약
|
||||
|
||||
**Request Body**:
|
||||
```json
|
||||
{
|
||||
"content_id": 101,
|
||||
"platform": "instagram",
|
||||
"scheduled_at": "2025-01-01T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
**Success Response** (201 Created):
|
||||
```json
|
||||
{
|
||||
"post": {
|
||||
"id": 201,
|
||||
"content_id": 101,
|
||||
"platform": "instagram",
|
||||
"scheduled_at": "2025-01-01T12:00:00Z",
|
||||
"status": "pending"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Business Logic**:
|
||||
1. content_id로 콘텐츠 조회
|
||||
2. 포스트 생성 (status: pending)
|
||||
3. scheduled_at 시간에 Instagram API 호출
|
||||
4. 성공 시 status = posted, 실패 시 status = failed
|
||||
|
||||
**Related Spec**: 003-schedule/spec.md (포스팅)
|
||||
**Related Entity**: Post, Content
|
||||
|
||||
---
|
||||
|
||||
## API Summary
|
||||
|
||||
| Domain | Endpoints | Description |
|
||||
|--------|-----------|-------------|
|
||||
| Persona | 3 (create, list, update) | 페르소나 관리 |
|
||||
| Content | 2 (generate, list) | 콘텐츠 생성 |
|
||||
| Schedule | 2 (create, list) | 스케줄 관리 |
|
||||
| Post | 2 (create, list) | 포스팅 관리 |
|
||||
|
||||
**Total Endpoints**: 9
|
||||
|
||||
---
|
||||
|
||||
## Error Response Format
|
||||
|
||||
**Standard Error Response**:
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "API_RATE_LIMIT",
|
||||
"message": "Midjourney API rate limit exceeded",
|
||||
"details": {
|
||||
"limit": 50,
|
||||
"current": 51,
|
||||
"reset_at": "2025-01-01T08:00:00Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Error Codes**:
|
||||
- `VALIDATION_ERROR`: 입력 검증 실패
|
||||
- `API_RATE_LIMIT`: API 제한 초과
|
||||
- `GENERATION_FAILED`: 콘텐츠 생성 실패
|
||||
- `NOT_FOUND`: 리소스 없음
|
||||
```
|
||||
|
||||
### 4. 기술 정책 정의
|
||||
|
||||
**Output**: `docs/appkit/design/tech-policies.md`
|
||||
|
||||
```markdown
|
||||
# Technical Policies
|
||||
|
||||
*기술 구현 관련 정책*
|
||||
|
||||
---
|
||||
|
||||
## API Rate Limiting
|
||||
|
||||
### Midjourney API
|
||||
- **Limit**: 시간당 50회
|
||||
- **동시 처리**: 최대 3개
|
||||
- **초과 시**: 429 에러, 다음 시간까지 대기
|
||||
- **Queue**: FIFO 방식
|
||||
|
||||
### OpenAI GPT-4 API
|
||||
- **Limit**: 분당 60회
|
||||
- **토큰**: 일 500,000 제한
|
||||
- **초과 시**: 429 에러
|
||||
- **Retry**: Exponential backoff (1s, 2s, 4s)
|
||||
|
||||
### Instagram Graph API
|
||||
- **Limit**: 하루 200개 포스트
|
||||
- **시간당**: 25회
|
||||
- **초과 시**: 403 에러
|
||||
|
||||
**구현 방안**:
|
||||
- Rate Limiter 모듈 구현
|
||||
- 우선순위 큐 시스템
|
||||
- API 호출 로그 기록
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
### 재시도 정책
|
||||
|
||||
**API 실패**:
|
||||
- 재시도 횟수: 3회
|
||||
- 방식: Exponential backoff
|
||||
- 대기 시간: 1s, 2s, 4s
|
||||
|
||||
**생성 실패**:
|
||||
- 재시도 횟수: 2회
|
||||
- 방식: 즉시 재시도
|
||||
- 실패 시: 에러 로그 기록, 알림
|
||||
|
||||
**품질 불량**:
|
||||
- 판단 기준: 이미지 해상도 < 1080x1080
|
||||
- 처리: 자동 재생성 (1회)
|
||||
|
||||
### 로깅
|
||||
|
||||
**로그 종류**:
|
||||
- `error.log`: 모든 에러
|
||||
- `api-calls.log`: API 호출 기록
|
||||
- `generation.log`: 콘텐츠 생성 기록
|
||||
|
||||
**로그 레벨**:
|
||||
- ERROR: 시스템 오류
|
||||
- WARN: API 제한 근접
|
||||
- INFO: 정상 실행
|
||||
|
||||
---
|
||||
|
||||
## Content Safety
|
||||
|
||||
### 브랜드 안전성
|
||||
- 성인 콘텐츠: GPT moderation API로 자동 차단
|
||||
- 폭력/혐오: 필터 적용
|
||||
- 저작권: 학습 데이터 외 참조 금지
|
||||
|
||||
### 품질 검증
|
||||
- 이미지: 최소 1080x1080
|
||||
- 캡션: 최소 50자, 최대 2200자
|
||||
- 해시태그: 5-30개
|
||||
|
||||
---
|
||||
|
||||
## Data Management
|
||||
|
||||
### 저장 위치
|
||||
- 페르소나: Database (personas table)
|
||||
- 콘텐츠: Database (contents table)
|
||||
- 이미지: S3 (Midjourney URL 저장)
|
||||
- 로그: `logs/` directory
|
||||
|
||||
### 백업
|
||||
- DB 백업: 일 1회 (자정)
|
||||
- S3 백업: 자동 (versioning)
|
||||
- 로그 보존: 90일
|
||||
```
|
||||
|
||||
### 5. 화면-API 매핑
|
||||
|
||||
**Output**: `docs/appkit/design/screen-api-map.md`
|
||||
|
||||
```markdown
|
||||
# Screen to API Mapping
|
||||
|
||||
*UI 화면과 API 호출 매핑*
|
||||
|
||||
---
|
||||
|
||||
## Flow: 콘텐츠 자동 생성
|
||||
|
||||
### Screen 1: 페르소나 설정
|
||||
|
||||
**User Actions**:
|
||||
- 페르소나 목록 조회
|
||||
- 새 페르소나 생성
|
||||
|
||||
**API Calls**:
|
||||
```
|
||||
1. GET /personas
|
||||
→ Returns: 페르소나 리스트
|
||||
|
||||
2. (On create) POST /personas
|
||||
→ Returns: 생성된 페르소나
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Screen 2: 스케줄 설정
|
||||
|
||||
**User Actions**:
|
||||
- 스케줄 등록
|
||||
- 실행 시간 설정
|
||||
- 대상 페르소나 선택
|
||||
|
||||
**API Calls**:
|
||||
```
|
||||
1. GET /personas
|
||||
→ Returns: 선택 가능한 페르소나
|
||||
|
||||
2. (On save) POST /schedules
|
||||
→ Returns: 생성된 스케줄
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Screen 3: 콘텐츠 확인
|
||||
|
||||
**User Actions**:
|
||||
- 생성된 콘텐츠 조회
|
||||
- 승인/거부
|
||||
|
||||
**API Calls**:
|
||||
```
|
||||
1. GET /contents?status=draft
|
||||
→ Returns: Draft 콘텐츠 목록
|
||||
|
||||
2. (On approve) PATCH /contents/{id}
|
||||
→ Body: { "status": "approved" }
|
||||
→ Returns: 업데이트된 콘텐츠
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Complete Sequence Diagram
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
actor User
|
||||
participant UI
|
||||
participant API
|
||||
participant Midjourney
|
||||
participant GPT
|
||||
participant Instagram
|
||||
|
||||
User->>UI: 스케줄 등록
|
||||
UI->>API: POST /schedules
|
||||
API-->>UI: Schedule created
|
||||
|
||||
Note over API: 매일 07:00 Cron 실행
|
||||
|
||||
API->>API: GET /personas (target)
|
||||
loop Each Persona
|
||||
API->>Midjourney: Generate Image
|
||||
Midjourney-->>API: Image URL
|
||||
API->>GPT: Generate Caption
|
||||
GPT-->>API: Caption Text
|
||||
API->>API: Save Content (draft)
|
||||
end
|
||||
|
||||
User->>UI: 콘텐츠 확인
|
||||
UI->>API: GET /contents?status=draft
|
||||
API-->>UI: Content List
|
||||
|
||||
User->>UI: 승인
|
||||
UI->>API: PATCH /contents/{id}
|
||||
API->>Instagram: Post Content
|
||||
Instagram-->>API: Success
|
||||
API-->>UI: Posted
|
||||
```
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Output Files
|
||||
|
||||
### 생성될 파일들:
|
||||
|
||||
```
|
||||
docs/appkit/design/
|
||||
├── entities.md # ERD 및 데이터 모델
|
||||
├── apis.md # API 엔드포인트 설계
|
||||
├── tech-policies.md # 기술 정책
|
||||
└── screen-api-map.md # 화면-API 매핑
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Integration Points
|
||||
|
||||
### 다른 명령어와의 연계:
|
||||
|
||||
- **From `/appkit.merge`**: concept-map.md 사용
|
||||
- **To 개발팀**: 설계 문서 전달
|
||||
- **To `/appkit.verify`**: 설계 완성도 체크 (향후)
|
||||
|
||||
---
|
||||
|
||||
## Key Principles
|
||||
|
||||
### 설계 원칙:
|
||||
|
||||
1. **Planning only, no code**: 설계 문서만 생성, 코드 작성 안 함
|
||||
2. **Entity-first approach**: 데이터 모델부터 설계
|
||||
3. **API follows entity**: API는 엔티티 관계에서 도출
|
||||
4. **Traceability**: 모든 설계는 spec과 연결
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
### 이 명령어 실행 후:
|
||||
|
||||
**📍 7단계 완료!**
|
||||
- 기획부터 설계까지 모든 문서 완성
|
||||
- 개발팀에게 전달 가능
|
||||
- MVP Phase 0 개발 시작
|
||||
|
||||
---
|
||||
|
||||
## Version
|
||||
|
||||
- **Version**: 1.0.0
|
||||
- **Created**: 2025-11-20
|
||||
- **Philosophy**: "설계는 기획과 구현 사이의 다리"
|
||||
Reference in New Issue
Block a user