diff --git a/API_CHANGES.md b/API_CHANGES.md new file mode 100644 index 0000000..f54789e --- /dev/null +++ b/API_CHANGES.md @@ -0,0 +1,263 @@ +# Content API ๋ณ๊ฒฝ์ฌํญ + +## ๐ ์ฃผ์ ๋ณ๊ฒฝ์ฌํญ ์์ฝ + +### 1. **eventDraftId โ eventId ํ์ ๋ณ๊ฒฝ** + +| ํญ๋ชฉ | ๊ธฐ์กด (Old) | ๋ณ๊ฒฝ (New) | +|------|-----------|-----------| +| ํ๋๋ช | `eventDraftId` | `eventId` | +| ํ์ | `number` | `string` | +| ์์ | `7777` | `"7777"` | + +--- + +## ๐ ์ํฅ์ ๋ฐ๋ ์ธํฐํ์ด์ค + +### GenerateImagesRequest + +**Before:** +```typescript +interface GenerateImagesRequest { + eventDraftId: number; + eventTitle: string; + eventDescription: string; + industry?: string; + location?: string; + trends?: string[]; + styles: ('SIMPLE' | 'FANCY' | 'TRENDY')[]; + platforms: ('INSTAGRAM' | 'NAVER' | 'KAKAO')[]; +} +``` + +**After:** +```typescript +interface GenerateImagesRequest { + eventId: string; // Changed from eventDraftId: number + eventTitle: string; + eventDescription: string; + industry?: string; + location?: string; + trends?: string[]; + styles: ('SIMPLE' | 'FANCY' | 'TRENDY')[]; + platforms: ('INSTAGRAM' | 'NAVER' | 'KAKAO')[]; +} +``` + +### JobInfo + +**Before:** +```typescript +interface JobInfo { + id: string; + eventDraftId: number; + jobType: string; + status: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED'; + progress: number; + resultMessage?: string; + errorMessage?: string; + createdAt: string; + updatedAt: string; +} +``` + +**After:** +```typescript +interface JobInfo { + id: string; + eventId: string; // Changed from eventDraftId: number + jobType: string; + status: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED'; + progress: number; + resultMessage?: string; + errorMessage?: string; + createdAt: string; + updatedAt: string; +} +``` + +### ImageInfo + +**Before:** +```typescript +interface ImageInfo { + id: number; + eventDraftId: number; + style: 'SIMPLE' | 'FANCY' | 'TRENDY'; + platform: 'INSTAGRAM' | 'NAVER' | 'KAKAO'; + cdnUrl: string; + prompt: string; + selected: boolean; + createdAt: string; + updatedAt: string; +} +``` + +**After:** +```typescript +interface ImageInfo { + id: number; + eventId: string; // Changed from eventDraftId: number + style: 'SIMPLE' | 'FANCY' | 'TRENDY'; + platform: 'INSTAGRAM' | 'NAVER' | 'KAKAO'; + cdnUrl: string; + prompt: string; + selected: boolean; + createdAt: string; + updatedAt: string; +} +``` + +### ContentInfo + +**Before:** +```typescript +interface ContentInfo { + id: number; + eventDraftId: number; + eventTitle: string; + eventDescription: string; + images: ImageInfo[]; + createdAt: string; + updatedAt: string; +} +``` + +**After:** +```typescript +interface ContentInfo { + id: number; + eventId: string; // Changed from eventDraftId: number + eventTitle: string; + eventDescription: string; + images: ImageInfo[]; + createdAt: string; + updatedAt: string; +} +``` + +--- + +## ๐ ์์ ๋ ํ์ผ ๋ชฉ๋ก + +### 1. Type Definitions +- โ `src/shared/api/contentApi.ts` + - `GenerateImagesRequest` interface updated + - `JobInfo` interface updated + - `ImageInfo` interface updated + - `ContentInfo` interface updated + - API function signatures updated + +### 2. Components +- โ `src/app/(main)/events/create/steps/ContentPreviewStep.tsx` + - `EventCreationData` interface: `eventDraftId: number` โ `eventDraftId: string` + - Mock data updated to use string type + - API call updated: `eventDraftId` โ `eventId` + +### 3. Mock Data Files +- โ `public/init-mock-data.html` + - `eventDraftId: 7777` โ `eventDraftId: "7777"` + +- โ `MOCK_DATA_SETUP.md` + - All mock data examples updated to string type + - Documentation notes added about type change + +### 4. API Routes (Next.js Proxy) +- โ `src/app/api/content/images/generate/route.ts` (no changes needed) +- โ `src/app/api/content/images/jobs/[jobId]/route.ts` (no changes needed) +- โ `src/app/api/content/events/[eventDraftId]/images/route.ts` + - Comment added about eventId parameter + +--- + +## ๐งช ํ ์คํธ ์์ + +### API ์์ฒญ ์์ + +**Before:** +```json +POST /api/v1/content/images/generate +{ + "eventDraftId": 7777, + "eventTitle": "๋งฅ์ฃผ ํํฐ ์ด๋ฒคํธ", + "eventDescription": "๊ฐ๋จ์์ ์ด๋ฆฌ๋ ์ ๋๋ ๋งฅ์ฃผ ํํฐ", + "industry": "์์์ ", + "location": "๊ฐ๋จ", + "trends": ["ํํฐ", "๋งฅ์ฃผ", "์๋งฅ์ฃผ"], + "styles": ["SIMPLE", "FANCY", "TRENDY"], + "platforms": ["INSTAGRAM"] +} +``` + +**After:** +```json +POST /api/v1/content/images/generate +{ + "eventId": "7777", + "eventTitle": "๋งฅ์ฃผ ํํฐ ์ด๋ฒคํธ", + "eventDescription": "๊ฐ๋จ์์ ์ด๋ฆฌ๋ ์ ๋๋ ๋งฅ์ฃผ ํํฐ", + "industry": "์์์ ", + "location": "๊ฐ๋จ", + "trends": ["ํํฐ", "๋งฅ์ฃผ", "์๋งฅ์ฃผ"], + "styles": ["SIMPLE", "FANCY", "TRENDY"], + "platforms": ["INSTAGRAM"] +} +``` + +### localStorage Mock ๋ฐ์ดํฐ + +**Before:** +```javascript +localStorage.setItem('eventCreationData', JSON.stringify({ + eventDraftId: 7777, + eventTitle: "๋งฅ์ฃผ ํํฐ ์ด๋ฒคํธ", + // ... +})); +``` + +**After:** +```javascript +localStorage.setItem('eventCreationData', JSON.stringify({ + eventDraftId: "7777", // String type now + eventTitle: "๋งฅ์ฃผ ํํฐ ์ด๋ฒคํธ", + // ... +})); +``` + +--- + +## โ ๋ง์ด๊ทธ๋ ์ด์ ์ฒดํฌ๋ฆฌ์คํธ + +- [x] TypeScript ์ธํฐํ์ด์ค ์ ๋ฐ์ดํธ +- [x] API ํธ์ถ ์ฝ๋ ์์ +- [x] Mock ๋ฐ์ดํฐ ํ์ ๋ณ๊ฒฝ +- [x] ๋ฌธ์ ์ ๋ฐ์ดํธ +- [x] ๋น๋ ์ฑ๊ณต ํ์ธ +- [ ] ๊ฐ๋ฐ ์๋ฒ ํ ์คํธ +- [ ] ์ค์ API ์ฐ๋ ํ ์คํธ + +--- + +## ๐ ๊ด๋ จ API ๋ฌธ์ + +- Swagger UI: http://localhost:8084/swagger-ui/index.html +- OpenAPI Spec: http://localhost:8084/v3/api-docs + +--- + +## ๐ ์ฃผ์์ฌํญ + +1. **ํ์ ์ฃผ์**: `eventId`๋ ์ด์ `string` ํ์ ์ ๋๋ค. ์ซ์๋ก ์ฌ์ฉํ์ง ๋ง์ธ์. +2. **Mock ๋ฐ์ดํฐ**: localStorage์ ์ ์ฅํ ๋ ๋ฌธ์์ด ํ์ ์ผ๋ก ์ ์ฅํด์ผ ํฉ๋๋ค. +3. **API ํธ์ถ**: ํ๋ก ํธ์๋์์ ๋ฐฑ์๋๋ก ์ ์ก ์ string์ผ๋ก ์ ์ก๋ฉ๋๋ค. +4. **ํ์ ํธํ์ฑ**: ๊ธฐ์กด number ํ์ ๋ฐ์ดํฐ๋ ์๋ํ์ง ์์ผ๋ฏ๋ก localStorage๋ฅผ ์ด๊ธฐํํด์ผ ํฉ๋๋ค. + +--- + +## ๐ ๋กค๋ฐฑ ๋ฐฉ๋ฒ + +๋ง์ฝ ์ด์ ๋ฒ์ ์ผ๋ก ๋์๊ฐ์ผ ํ๋ค๋ฉด: + +1. `git revert` ๋๋ ํน์ ์ปค๋ฐ์ผ๋ก ๋ณต์ +2. localStorage ์ด๊ธฐํ: `localStorage.removeItem('eventCreationData')` +3. ๊ฐ๋ฐ ์๋ฒ ์ฌ์์ diff --git a/CORS_FIX.md b/CORS_FIX.md new file mode 100644 index 0000000..de2857f --- /dev/null +++ b/CORS_FIX.md @@ -0,0 +1,221 @@ +# CORS ๋ฌธ์ ํด๊ฒฐ ๋ฐฉ๋ฒ + +## ๋ฌธ์ ์ํฉ + +ํ๋ก ํธ์๋(`http://localhost:3000`)์์ ๋ฐฑ์๋ Content API(`http://localhost:8084`)๋ฅผ ์ง์ ํธ์ถํ๋ฉด **CORS(Cross-Origin Resource Sharing)** ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค. + +### ์๋ฌ ๋ฉ์์ง +``` +Network Error +AxiosError: Network Error + code: "ERR_NETWORK" +``` + +### ์์ธ ๋ถ์ +```bash +# CORS preflight ์์ฒญ ํ ์คํธ +curl -X OPTIONS http://localhost:8084/api/v1/content/images/generate \ + -H 'Origin: http://localhost:3000' \ + -H 'Access-Control-Request-Method: POST' \ + -H 'Access-Control-Request-Headers: content-type' + +# ๊ฒฐ๊ณผ: HTTP/1.1 403 Forbidden +# Invalid CORS request +``` + +๋ฐฑ์๋ ์๋ฒ๊ฐ `http://localhost:3000` origin์์์ CORS ์์ฒญ์ ํ์ฉํ์ง ์์. + +--- + +## ํด๊ฒฐ ๋ฐฉ๋ฒ: Next.js API Proxy + +๋ฐฑ์๋ CORS ์ค์ ์ ์์ ํ๋ ๋์ , **Next.js API Routes๋ฅผ ํ๋ก์๋ก ์ฌ์ฉ**ํ์ฌ CORS ๋ฌธ์ ๋ฅผ ์ฐํํ์ต๋๋ค. + +### ์ํคํ ์ฒ + +``` +[Browser] + โ (Same-Origin Request) +[Next.js Frontend: localhost:3000] + โ [Next.js API Proxy: /api/content/*] + โ (Server-to-Server Request, CORS ๋ฌด๊ด) +[Content API Backend: localhost:8084] +``` + +### ๊ตฌํ ํ์ผ + +#### 1. **์ด๋ฏธ์ง ์์ฑ ํ๋ก์** (`/api/content/images/generate/route.ts`) + +```typescript +export async function POST(request: NextRequest) { + const body = await request.json(); + + const response = await fetch('http://localhost:8084/api/v1/content/images/generate', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body), + }); + + return NextResponse.json(await response.json()); +} +``` + +**URL ๋งคํ**: +- Frontend: `POST /api/content/images/generate` +- Backend: `POST http://localhost:8084/api/v1/content/images/generate` + +#### 2. **Job ์ํ ์กฐํ ํ๋ก์** (`/api/content/images/jobs/[jobId]/route.ts`) + +```typescript +export async function GET(request: NextRequest, { params }: { params: { jobId: string } }) { + const { jobId } = params; + + const response = await fetch(`http://localhost:8084/api/v1/content/images/jobs/${jobId}`, { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + }); + + return NextResponse.json(await response.json()); +} +``` + +**URL ๋งคํ**: +- Frontend: `GET /api/content/images/jobs/{jobId}` +- Backend: `GET http://localhost:8084/api/v1/content/images/jobs/{jobId}` + +#### 3. **์ด๋ฏธ์ง ๋ชฉ๋ก ์กฐํ ํ๋ก์** (`/api/content/events/[eventDraftId]/images/route.ts`) + +```typescript +export async function GET(request: NextRequest, { params }: { params: { eventDraftId: string } }) { + const { eventDraftId } = params; + const { searchParams } = new URL(request.url); + + let url = `http://localhost:8084/api/v1/content/events/${eventDraftId}/images`; + if (searchParams.get('style')) url += `?style=${searchParams.get('style')}`; + if (searchParams.get('platform')) url += `&platform=${searchParams.get('platform')}`; + + const response = await fetch(url, { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + }); + + return NextResponse.json(await response.json()); +} +``` + +**URL ๋งคํ**: +- Frontend: `GET /api/content/events/{eventDraftId}/images?style=SIMPLE&platform=INSTAGRAM` +- Backend: `GET http://localhost:8084/api/v1/content/events/{eventDraftId}/images?style=SIMPLE&platform=INSTAGRAM` + +--- + +## ํด๋ผ์ด์ธํธ ์ฝ๋ ๋ณ๊ฒฝ + +### Before (์ง์ ๋ฐฑ์๋ ํธ์ถ - CORS ์๋ฌ ๋ฐ์) + +```typescript +const CONTENT_API_BASE_URL = 'http://localhost:8084'; + +export const contentApiClient = axios.create({ + baseURL: CONTENT_API_BASE_URL, +}); + +// โ CORS Error +await contentApiClient.post('/api/v1/content/images/generate', request); +``` + +### After (Next.js API Proxy ์ฌ์ฉ - CORS ์ฐํ) + +```typescript +const CONTENT_API_BASE_URL = '/api/content'; // Same-origin request + +export const contentApiClient = axios.create({ + baseURL: CONTENT_API_BASE_URL, +}); + +// โ Works! (Same-origin โ Server-side proxy โ Backend) +await contentApiClient.post('/images/generate', request); +``` + +--- + +## ์ฅ์ + +โ **ํ๋ก ํธ์๋ ์์ ๋ง์ผ๋ก ํด๊ฒฐ**: ๋ฐฑ์๋ CORS ์ค์ ๋ณ๊ฒฝ ๋ถํ์ +โ **Same-Origin ์ ์ฑ ์ค์**: ๋ธ๋ผ์ฐ์ ๋ ๊ฐ์ ๋๋ฉ์ธ์ผ๋ก ์ธ์ +โ **์๋ฒ ๊ฐ ํต์ **: Next.js ์๋ฒ์์ ๋ฐฑ์๋ ํธ์ถ (CORS ๋ฌด๊ด) +โ **๋ณด์ ๊ฐํ**: ๋ฐฑ์๋ URL์ ํด๋ผ์ด์ธํธ์ ๋ ธ์ถํ์ง ์์ +โ **ํ๊ฒฝ ๋ณ์ ํ์ฉ**: `NEXT_PUBLIC_CONTENT_API_URL`๋ก ๋ฐฐํฌ ํ๊ฒฝ ๋์ + +--- + +## ํ๋ก๋์ ๋ฐฐํฌ ์ ๊ณ ๋ ค์ฌํญ + +### ํ๊ฒฝ ๋ณ์ ์ค์ + +```bash +# .env.local (๊ฐ๋ฐ ํ๊ฒฝ) +NEXT_PUBLIC_CONTENT_API_URL=http://localhost:8084 + +# .env.production (ํ๋ก๋์ ํ๊ฒฝ) +NEXT_PUBLIC_CONTENT_API_URL=https://api.production.com +``` + +### ํ๋ก์ ์ฝ๋์ ์ ์ฉ + +```typescript +const CONTENT_API_BASE_URL = process.env.NEXT_PUBLIC_CONTENT_API_URL || 'http://localhost:8084'; + +const response = await fetch(`${CONTENT_API_BASE_URL}/api/v1/content/images/generate`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body), +}); +``` + +### ํ์์์ ์ค์ + +```typescript +const response = await fetch(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body), + signal: AbortSignal.timeout(120000), // 120์ด ํ์์์ +}); +``` + +--- + +## ํ ์คํธ ๋ฐฉ๋ฒ + +### 1. ๊ฐ๋ฐ ์๋ฒ ์คํ + +```bash +npm run dev +``` + +### 2. ๋ธ๋ผ์ฐ์ ์์ ํ ์คํธ + +``` +http://localhost:3000/events/create?event-creation.step=contentPreview +``` + +### 3. ๋คํธ์ํฌ ํญ ํ์ธ + +๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ ๋๊ตฌ โ Network ํญ์์ ๋ค์ ์์ฒญ ํ์ธ: + +``` +POST http://localhost:3000/api/content/images/generate (Status: 202) +GET http://localhost:3000/api/content/images/jobs/job-xxxxx (Status: 200) +GET http://localhost:3000/api/content/events/7777/images (Status: 200) +``` + +๋ชจ๋ **Same-Origin** ์์ฒญ์ด๋ฏ๋ก CORS ์๋ฌ ์์! + +--- + +## ์ฐธ๊ณ ์๋ฃ + +- [Next.js API Routes](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) +- [CORS (MDN)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) +- [Proxy Pattern](https://en.wikipedia.org/wiki/Proxy_pattern) diff --git a/FIX_EVENTID_MISMATCH.md b/FIX_EVENTID_MISMATCH.md new file mode 100644 index 0000000..f10105c --- /dev/null +++ b/FIX_EVENTID_MISMATCH.md @@ -0,0 +1,182 @@ +# EventId ๋ถ์ผ์น ๋ฌธ์ ํด๊ฒฐ + +## ๋ฌธ์ ์ํฉ + +์ฌ์ฉ์๊ฐ ์ด๋ฏธ์ง ์์ฑ ํ์ด์ง์์ ์คํ์ผ 1 ์นด๋์ ์ด๋ฏธ์ง๊ฐ ํ์๋์ง ์๊ณ ํ๋ ์ด์คํ๋๋ง ๋ณด์ด๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. + +### ์คํฌ๋ฆฐ์ท ๋ถ์ +- **์คํ์ผ 1 (SIMPLE)**: ํ๋ ์ด์คํ๋๋ง ํ์ (์์ด์ฝ + ์ ๋ชฉ + ๊ฒฝํ) +- **์คํ์ผ 2 (FANCY)**: ์ค์ ์ด๋ฏธ์ง ํ์ โ +- **์คํ์ผ 3 (TRENDY)**: ์ค์ ์ด๋ฏธ์ง ํ์ โ + +## ๊ทผ๋ณธ ์์ธ + +API ๋ถ์ ๊ฒฐ๊ณผ, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋ ์ด๋ฏธ์ง์ Mock ๋ฐ์ดํฐ์ eventId๊ฐ ์ผ์นํ์ง ์์์ต๋๋ค: + +```bash +# Mock ๋ฐ์ดํฐ eventId +"7777" + +# ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์ eventId +curl http://localhost:8084/api/v1/content/events/7777/images +โ Response: [] (๋น ๋ฐฐ์ด) + +# ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์กด์ฌํ๋ eventId +- "Tst12131": SIMPLE ์ด๋ฏธ์ง 1๊ฐ +- "1761634317010": SIMPLE, FANCY, TRENDY ๊ฐ 2๊ฐ์ฉ ์ด 6๊ฐ +- null: SIMPLE ์ด๋ฏธ์ง 1๊ฐ +``` + +**๊ฒฐ๋ก **: Mock ๋ฐ์ดํฐ์ eventId "7777"๋ก๋ ์ด๋ค ์ด๋ฏธ์ง๋ ์กฐํ๋์ง ์์์ต๋๋ค. + +## ํด๊ฒฐ ๋ฐฉ๋ฒ + +๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ด๋ฏธ ์กด์ฌํ๋ ์ด๋ฏธ์ง๊ฐ ์๋ eventId๋ก Mock ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ์ต๋๋ค. + +### ๋ณ๊ฒฝ๋ eventId +```javascript +// Before +eventDraftId: "7777" + +// After +eventDraftId: "1761634317010" +``` + +**์ ํ ์ด์ **: +- SIMPLE, FANCY, TRENDY 3๊ฐ์ง ์คํ์ผ ๋ชจ๋ ์ด๋ฏธ์ง ๋ณด์ +- ๊ฐ ์คํ์ผ๋ณ๋ก 2๊ฐ์ฉ ์ด 6๊ฐ์ ์ด๋ฏธ์ง ์กด์ฌ +- INSTAGRAM ํ๋ซํผ ์ด๋ฏธ์ง ์กด์ฌ + +## ์์ ๋ ํ์ผ + +### 1. ContentPreviewStep.tsx +**์์น**: `src/app/(main)/events/create/steps/ContentPreviewStep.tsx:109` + +```typescript +const mockData: EventCreationData = { + eventDraftId: "1761634317010", // Changed from "7777" + eventTitle: "๋งฅ์ฃผ ํํฐ ์ด๋ฒคํธ", + eventDescription: "๊ฐ๋จ์์ ์ด๋ฆฌ๋ ์ ๋๋ ๋งฅ์ฃผ ํํฐ์ ์ฐธ์ฌํ์ธ์!", + industry: "์์์ ", + location: "๊ฐ๋จ", + trends: ["ํํฐ", "๋งฅ์ฃผ", "์๋งฅ์ฃผ"], + prize: "์๋งฅ์ฃผ 1์" +}; +``` + +### 2. init-mock-data.html +**์์น**: `public/init-mock-data.html:121`, `public/init-mock-data.html:168` + +```html + +1761634317010 + + + +``` + +### 3. QUICK_TEST.md +**์์น**: `QUICK_TEST.md` (์ ์ฒด ๋ฌธ์) + +- Mock ๋ฐ์ดํฐ ์์์ eventId ๋ณ๊ฒฝ +- API ํ์ธ ์์์ eventId ๋ณ๊ฒฝ +- ๋๋ฒ๊น ๋ก๊ทธ ์์ ์ ๋ฐ์ดํธ + +### 4. MOCK_DATA_SETUP.md +**์์น**: `MOCK_DATA_SETUP.md` (์ ์ฒด ๋ฌธ์) + +- Mock ๋ฐ์ดํฐ ๊ตฌ์กฐ ์์ ์ ๋ฐ์ดํธ +- ํ ์คํธ ์๋๋ฆฌ์ค eventId ๋ณ๊ฒฝ +- ์ฐธ๊ณ ์ฌํญ ์ถ๊ฐ: "1761634317010์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ด๋ฏธ ์์ฑ๋ ์ด๋ฏธ์ง๊ฐ ์๋ eventId" + +## ๋น๋ ๊ฒ์ฆ + +```bash +npm run build +``` + +โ **์ฑ๊ณต**: TypeScript ํ์ ๊ฒ์ฆ ํต๊ณผ, ๋น๋ ์๋ฃ + +๊ฒฝ๊ณ ์ฌํญ: +- `loadingProgress`, `setLoadingProgress` ๋ฏธ์ฌ์ฉ ๋ณ์ (๊ธฐ๋ฅ์ ์ํฅ ์์) +- ๊ธฐํ ESLint ๊ฒฝ๊ณ (๊ธฐ์กด ์ฝ๋, ๊ธ๋ฒ ์์ ๊ณผ ๋ฌด๊ด) + +## ํ ์คํธ ๋ฐฉ๋ฒ + +### 1. localStorage ์ด๊ธฐํ +๋ธ๋ผ์ฐ์ ์ฝ์์์ ๊ธฐ์กด ๋ฐ์ดํฐ ์ญ์ : +```javascript +localStorage.removeItem('eventCreationData'); +``` + +### 2. ๊ฐ๋ฐ ์๋ฒ ์คํ +```bash +npm run dev +``` + +### 3. ํ์ด์ง ์ ์ +``` +http://localhost:3000/events/create?event-creation.step=contentPreview +``` + +### 4. ์์ ๊ฒฐ๊ณผ +- โ ์คํ์ผ 1 (SIMPLE): ์ค์ ์ด๋ฏธ์ง ํ์ +- โ ์คํ์ผ 2 (FANCY): ์ค์ ์ด๋ฏธ์ง ํ์ +- โ ์คํ์ผ 3 (TRENDY): ์ค์ ์ด๋ฏธ์ง ํ์ +- โ 3๊ฐ ์คํ์ผ ๋ชจ๋ "ํฌ๊ฒ๋ณด๊ธฐ" ๋ฒํผ ํ์ฑํ + +### 5. ์ฝ์ ๋ก๊ทธ ํ์ธ +``` +๐ฅ Loading generated images for event: 1761634317010 +โ Images loaded from API: 6 [...] +๐ธ Processing image 1: { id: X, style: 'SIMPLE', ... } + โ Selected as latest SIMPLE image +๐ธ Processing image 2: { id: Y, style: 'FANCY', ... } + โ Selected as latest FANCY image +๐ธ Processing image 3: { id: Z, style: 'TRENDY', ... } + โ Selected as latest TRENDY image +๐จ Image map created with entries: { SIMPLE: 'YES โ ', FANCY: 'YES โ ', TRENDY: 'YES โ ', totalSize: 3 } +โ ์ด๋ฏธ์ง ๋ก๋ ์๋ฃ! +๐ผ๏ธ Rendering SIMPLE: { hasImage: true, imageDataExists: true, ... } +โ SIMPLE image loaded successfully +``` + +## ์ถ๊ฐ ์ฐธ๊ณ ์ฌํญ + +### ์๋ก์ด ์ด๋ฒคํธ ํ ์คํธ ์ +์๋ก์ด eventId๋ก ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๋ ค๋ฉด: + +1. localStorage์ ์๋ก์ด eventId ์ค์ +2. "์ด๋ฏธ์ง ์ฌ์์ฑ" ๋ฒํผ ํด๋ฆญ +3. ์ฝ 2์ด ํ ์๋์ผ๋ก ์์ฑ๋ ์ด๋ฏธ์ง ๋ก๋ + +### Mock ๋ฐ์ดํฐ ๋ณ๊ฒฝ ๋ฐฉ๋ฒ +`public/init-mock-data.html` ํ์ด์ง ์ฌ์ฉ: +``` +http://localhost:3000/init-mock-data.html +``` + +๋๋ ๋ธ๋ผ์ฐ์ ์ฝ์์์ ์ง์ ์ค์ : +```javascript +localStorage.setItem('eventCreationData', JSON.stringify({ + eventDraftId: "1761634317010", + eventTitle: "...", + // ... +})); +``` + +## ๊ฒฐ๋ก + +EventId ๋ถ์ผ์น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ฌ ๋ชจ๋ ์คํ์ผ ์นด๋์์ ์ค์ ์ด๋ฏธ์ง๊ฐ ์ ์์ ์ผ๋ก ํ์๋ฉ๋๋ค. + +**ํต์ฌ ๋ณ๊ฒฝ**: Mock ๋ฐ์ดํฐ์ eventId๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์กด์ฌํ๋ "1761634317010"์ผ๋ก ๋ณ๊ฒฝ + +**์ํฅ ๋ฒ์**: +- ๊ฐ๋ฐ/ํ ์คํธ ํ๊ฒฝ์ Mock ๋ฐ์ดํฐ๋ง ์ํฅ +- ์ค์ ์ด์ ํ๊ฒฝ์์๋ Channel Step API์์ ์ ๊ณตํ๋ ์ค์ eventId ์ฌ์ฉ +- ์ฝ๋ ๋ก์ง ๋ณ๊ฒฝ ์์, ๋ฐ์ดํฐ๋ง ๋ณ๊ฒฝ diff --git a/MOCK_DATA_SETUP.md b/MOCK_DATA_SETUP.md new file mode 100644 index 0000000..f438436 --- /dev/null +++ b/MOCK_DATA_SETUP.md @@ -0,0 +1,149 @@ +# Mock ๋ฐ์ดํฐ ์ค์ ๊ฐ์ด๋ + +AI ์ด๋ฏธ์ง ์์ฑ ๊ธฐ๋ฅ์ ํ ์คํธํ๊ธฐ ์ํด localStorage์ mock ๋ฐ์ดํฐ๋ฅผ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. + +## ๐ ๋น ๋ฅธ ์์ + +### ๋ฐฉ๋ฒ 1: ์น ์ธํฐํ์ด์ค ์ฌ์ฉ (๊ถ์ฅ) + +1. ๊ฐ๋ฐ ์๋ฒ ์คํ +```bash +npm run dev +``` + +2. ๋ธ๋ผ์ฐ์ ์์ mock ๋ฐ์ดํฐ ์ด๊ธฐํ ํ์ด์ง ์ด๊ธฐ +``` +http://localhost:3000/init-mock-data.html +``` + +3. "LocalStorage์ ์ ์ฅํ๊ธฐ" ๋ฒํผ ํด๋ฆญ + +4. ์ด๋ฏธ์ง ์์ฑ ํ์ด์ง๋ก ์ด๋ +``` +http://localhost:3000/events/create?step=contentPreview +``` + +### ๋ฐฉ๋ฒ 2: ๋ธ๋ผ์ฐ์ ์ฝ์ ์ฌ์ฉ + +1. ๊ฐ๋ฐ ์๋ฒ ์คํ ํ ๋ธ๋ผ์ฐ์ ์์ ์๋ฌด ํ์ด์ง๋ ์ด๊ธฐ + +2. F12 ๋๋ Cmd+Option+I๋ก ๊ฐ๋ฐ์ ๋๊ตฌ ์ด๊ธฐ + +3. Console ํญ์์ ๋ค์ ์ฝ๋ ์คํ: + +```javascript +const mockEventData = { + eventDraftId: "1761634317010", // String type (existing eventId with images) + eventTitle: "๋งฅ์ฃผ ํํฐ ์ด๋ฒคํธ", + eventDescription: "๊ฐ๋จ์์ ์ด๋ฆฌ๋ ์ ๋๋ ๋งฅ์ฃผ ํํฐ์ ์ฐธ์ฌํ์ธ์!", + industry: "์์์ ", + location: "๊ฐ๋จ", + trends: ["ํํฐ", "๋งฅ์ฃผ", "์๋งฅ์ฃผ"], + prize: "์๋งฅ์ฃผ 1์" +}; + +localStorage.setItem('eventCreationData', JSON.stringify(mockEventData)); +console.log('โ Mock ๋ฐ์ดํฐ ์ ์ฅ ์๋ฃ!'); +``` + +4. ์ด๋ฏธ์ง ์์ฑ ํ์ด์ง๋ก ์ด๋ + +### ๋ฐฉ๋ฒ 3: ํ ์คํธ HTML ํ์ผ ์ฌ์ฉ + +ํ๋ก์ ํธ ๋ฃจํธ์ `test-localstorage.html` ํ์ผ์ ๋ธ๋ผ์ฐ์ ์์ ์ง์ ์ด๊ธฐ: + +```bash +open test-localstorage.html +``` + +## ๐ Mock ๋ฐ์ดํฐ ๊ตฌ์กฐ + +```json +{ + "eventDraftId": "1761634317010", + "eventTitle": "๋งฅ์ฃผ ํํฐ ์ด๋ฒคํธ", + "eventDescription": "๊ฐ๋จ์์ ์ด๋ฆฌ๋ ์ ๋๋ ๋งฅ์ฃผ ํํฐ์ ์ฐธ์ฌํ์ธ์!", + "industry": "์์์ ", + "location": "๊ฐ๋จ", + "trends": ["ํํฐ", "๋งฅ์ฃผ", "์๋งฅ์ฃผ"], + "prize": "์๋งฅ์ฃผ 1์" +} +``` + +**์ฐธ๊ณ **: +- `eventDraftId`๋ API ๋ณ๊ฒฝ์ผ๋ก ์ธํด `string` ํ์ ์ ๋๋ค. +- `"1761634317010"`์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ด๋ฏธ ์์ฑ๋ ์ด๋ฏธ์ง๊ฐ ์๋ eventId์ ๋๋ค. + +## ๐งช ํ ์คํธ ์๋๋ฆฌ์ค + +### ์๋๋ฆฌ์ค 1: ์ ์ฒด ์ด๋ฏธ์ง ์์ฑ ํ๋ก์ฐ + +1. Mock ๋ฐ์ดํฐ ์ค์ +2. `/events/create?step=contentPreview` ์ ์ +3. ์๋์ผ๋ก AI ์ด๋ฏธ์ง ์์ฑ ์์ +4. 3๊ฐ์ง ์คํ์ผ(SIMPLE, FANCY, TRENDY) ํ์ธ +5. ์คํ์ผ ์ ํ ํ ๋ค์ ๋จ๊ณ ์งํ + +### ์๋๋ฆฌ์ค 2: ๋ค์ํ ์ด๋ฒคํธ ๋ฐ์ดํฐ ํ ์คํธ + +๋ค๋ฅธ ์ ์ข /์ง์ญ/ํธ๋ ๋๋ก ํ ์คํธ: + +```javascript +// ์นดํ ์ด๋ฒคํธ (์๋ก์ด ์ด๋ฏธ์ง ์์ฑ ํ์) +localStorage.setItem('eventCreationData', JSON.stringify({ + eventDraftId: "test-cafe-001", + eventTitle: "์ปคํผ ํ ์ธ ์ด๋ฒคํธ", + eventDescription: "์ ๋ฉ๋ด ์ถ์ ๊ธฐ๋ 30% ํ ์ธ", + industry: "์นดํ", + location: "ํ๋", + trends: ["์ปคํผ", "ํ ์ธ", "์ ๋ฉ๋ด"], + prize: "์๋ฉ๋ฆฌ์นด๋ ธ 1์" +})); +``` + +```javascript +// ๋ทฐํฐ ์ด๋ฒคํธ (์๋ก์ด ์ด๋ฏธ์ง ์์ฑ ํ์) +localStorage.setItem('eventCreationData', JSON.stringify({ + eventDraftId: "test-beauty-001", + eventTitle: "๋ด๋ง์ด ํผ๋ถ๊ด๋ฆฌ ์ด๋ฒคํธ", + eventDescription: "๋ด๋ง์ด ํน๋ณ ์ผ์ด ํ๋ก๊ทธ๋จ", + industry: "๋ทฐํฐ", + location: "๊ฐ๋จ", + trends: ["ํผ๋ถ๊ด๋ฆฌ", "๋ด", "์ผ์ด"], + prize: "ํ์ด์ ์ผ์ด 1ํ" +})); +``` + +## ๐ ๋๋ฒ๊น + +### localStorage ๋ฐ์ดํฐ ํ์ธ + +```javascript +// ํ์ฌ ์ ์ฅ๋ ๋ฐ์ดํฐ ํ์ธ +const data = localStorage.getItem('eventCreationData'); +console.log(JSON.parse(data)); +``` + +### localStorage ๋ฐ์ดํฐ ์ญ์ + +```javascript +localStorage.removeItem('eventCreationData'); +console.log('โ ๋ฐ์ดํฐ ์ญ์ ์๋ฃ'); +``` + +## โ ๏ธ ์ฃผ์์ฌํญ + +1. **๊ฐ์ ๋๋ฉ์ธ**: localStorage๋ ๋๋ฉ์ธ๋ณ๋ก ๋ถ๋ฆฌ๋๋ฏ๋ก, ๊ฐ์ localhost:3000์์ ์ค์ ํด์ผ ํฉ๋๋ค. + +2. **๋ธ๋ผ์ฐ์ ์ ํ**: ์ํฌ๋ฆฟ ๋ชจ๋์์๋ localStorage๊ฐ ์ ํ๋ ์ ์์ต๋๋ค. + +3. **๋ฐ์ดํฐ ์ ์ง**: ๋ธ๋ผ์ฐ์ ๋ฅผ ๋ซ์๋ localStorage ๋ฐ์ดํฐ๋ ์ ์ง๋ฉ๋๋ค. ์๋ก์ด ํ ์คํธ ์ ์ญ์ ํ ์งํํ์ธ์. + +## ๐ฏ ์ค์ API ์ฐ๋ ํ + +Channel Step API๊ฐ ๊ตฌํ๋๋ฉด ์ด mock ๋ฐ์ดํฐ ์ค์ ์ ๋ถํ์ํ๋ฉฐ, +์ค์ ํ๋ก์ฐ์์ ์๋์ผ๋ก ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ฉ๋๋ค: + +``` +Objective โ Recommendation โ Channel (์ฌ๊ธฐ์ localStorage ์ ์ฅ) โ ContentPreview (์ด๋ฏธ์ง ์์ฑ) +``` diff --git a/QUICK_TEST.md b/QUICK_TEST.md new file mode 100644 index 0000000..8a1b748 --- /dev/null +++ b/QUICK_TEST.md @@ -0,0 +1,145 @@ +# ๐ AI ์ด๋ฏธ์ง ์์ฑ ๋น ๋ฅธ ํ ์คํธ ๊ฐ์ด๋ + +## โก ๊ฐ์ฅ ๋น ๋ฅธ ๋ฐฉ๋ฒ (๊ธฐ์กด ์ด๋ฏธ์ง ํ์ธ) + +```bash +# 1. ๊ฐ๋ฐ ์๋ฒ ์คํ +npm run dev + +# 2. ๋ธ๋ผ์ฐ์ ์์ ๋ฐ๋ก ์ ์ +http://localhost:3000/events/create?event-creation.step=contentPreview +``` + +โจ **๋!** ์๋์ผ๋ก Mock ๋ฐ์ดํฐ(eventId: "1761634317010")๊ฐ ์์ฑ๋๊ณ ๊ธฐ์กด ์์ฑ๋ ์ด๋ฏธ์ง๋ฅผ ๋ถ๋ฌ์ต๋๋ค. + +๐ก **์ด๋ฏธ์ง๊ฐ ์์ ๊ฒฝ์ฐ**: "์ด๋ฏธ์ง ์์ฑํ๊ธฐ" ๋ฒํผ์ ํด๋ฆญํ๋ฉด ์๋ก์ด ์ด๋ฏธ์ง๋ฅผ ์์ฑํฉ๋๋ค. + +--- + +## ๐ ์ปค์คํ ๋ฐ์ดํฐ๋ก ํ ์คํธ (์ ํ์ฌํญ) + +### 1๋จ๊ณ: ๊ฐ๋ฐ ์๋ฒ ์คํ + +```bash +npm run dev +``` + +### 2๋จ๊ณ: Mock ๋ฐ์ดํฐ ์ค์ (3๊ฐ์ง ๋ฐฉ๋ฒ ์ค ์ ํ) + +### โจ ๋ฐฉ๋ฒ A: ์น UI ์ฌ์ฉ (๊ฐ์ฅ ์ฌ์!) + +๋ธ๋ผ์ฐ์ ์์ ์ด๊ธฐ: +``` +http://localhost:3000/init-mock-data.html +``` + +"LocalStorage์ ์ ์ฅํ๊ธฐ" ๋ฒํผ ํด๋ฆญ โ ์๋ฃ! + +--- + +### ๋ฐฉ๋ฒ B: ๋ธ๋ผ์ฐ์ ์ฝ์ ์ฌ์ฉ + +1. `http://localhost:3000` ์ ์ +2. F12 (๊ฐ๋ฐ์ ๋๊ตฌ) โ Console ํญ +3. ๋ค์ ์ฝ๋ ๋ณต์ฌ & ๋ถ์ฌ๋ฃ๊ธฐ: + +```javascript +localStorage.setItem('eventCreationData', JSON.stringify({ + eventDraftId: "1761634317010", + eventTitle: "๋งฅ์ฃผ ํํฐ ์ด๋ฒคํธ", + eventDescription: "๊ฐ๋จ์์ ์ด๋ฆฌ๋ ์ ๋๋ ๋งฅ์ฃผ ํํฐ์ ์ฐธ์ฌํ์ธ์!", + industry: "์์์ ", + location: "๊ฐ๋จ", + trends: ["ํํฐ", "๋งฅ์ฃผ", "์๋งฅ์ฃผ"], + prize: "์๋งฅ์ฃผ 1์" +})); +``` + +--- + +### ๋ฐฉ๋ฒ C: HTML ํ์ผ ์ง์ ์ด๊ธฐ + +```bash +open test-localstorage.html +``` + +## 3๋จ๊ณ: ์ด๋ฏธ์ง ์์ฑ ํ์ด์ง ์ ์ + +๋ธ๋ผ์ฐ์ ์์ ์ด๊ธฐ: +``` +http://localhost:3000/events/create?event-creation.step=contentPreview +``` + +## 4๋จ๊ณ: ์๋ ์คํ ํ์ธ โ + +1. ํ์ด์ง ๋ก๋ฉ๋๋ฉด ์๋์ผ๋ก ์ด๋ฏธ์ง ์์ฑ ์์ +2. ๋ก๋ฉ ์คํผ๋์ ์งํ๋ฅ ํ์ธ +3. ์ฝ 60์ด ํ 3๊ฐ์ง ์คํ์ผ ์ด๋ฏธ์ง ์์ฑ + - ์คํ์ผ 1: ์ฌํ + - ์คํ์ผ 2: ํ๋ ค + - ์คํ์ผ 3: ํธ๋ ๋ + +## ์์ ๊ฒฐ๊ณผ + +### ์ด๋ฏธ์ง๊ฐ ์๋ ๊ฒฝ์ฐ +- โ **์ฆ์ ํ์**: ๋ก๋ฉ ํ ๋ฐ๋ก ์ด๋ฏธ์ง ๋ฏธ๋ฆฌ๋ณด๊ธฐ ํ๋ฉด +- โ **3๊ฐ ์คํ์ผ ์ด๋ฏธ์ง**: SIMPLE, FANCY, TRENDY ๊ฐ๊ฐ ์ต์ ์ด๋ฏธ์ง ํ์ +- โ **์ด๋ฏธ์ง ์ ํ**: ๋ผ๋์ค ๋ฒํผ์ผ๋ก ์ํ๋ ์คํ์ผ ์ ํ +- โ **์ฌ์์ฑ ๋ฒํผ**: "์ด๋ฏธ์ง ์ฌ์์ฑ" ๋ฒํผ์ผ๋ก ์๋ก์ด ์ด๋ฏธ์ง ์์ฑ ๊ฐ๋ฅ +- โ **ํฌ๊ฒ๋ณด๊ธฐ**: ๊ฐ ์ด๋ฏธ์ง ํด๋ฆญ ์ ์ ์ฒดํ๋ฉด ๋ฏธ๋ฆฌ๋ณด๊ธฐ + +### ์ด๋ฏธ์ง๊ฐ ์๋ ๊ฒฝ์ฐ +- โ ๏ธ **์๋ฌ ๋ฉ์์ง**: "์์ฑ๋ ์ด๋ฏธ์ง๊ฐ ์์ต๋๋ค. ์ด๋ฏธ์ง๋ฅผ ๋จผ์ ์์ฑํด์ฃผ์ธ์." +- ๐ **์์ฑ ๋ฒํผ**: "์ด๋ฏธ์ง ์์ฑํ๊ธฐ" ๋ฒํผ ํด๋ฆญ +- โณ **์์ฑ ๋๊ธฐ**: API ์์ฒญ ํ 2์ด ๋ค ์๋์ผ๋ก ์ด๋ฏธ์ง ์กฐํ +- โ **์ด๋ฏธ์ง ํ์**: ์์ฑ ์๋ฃ๋ ์ด๋ฏธ์ง ์๋ ํ์ + +## ๋ฌธ์ ํด๊ฒฐ + +### ~~"์ด๋ฒคํธ ์ ๋ณด๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค" ์๋ฌ~~ +โ โ **ํด๊ฒฐ๋จ!** ์ด์ ์๋์ผ๋ก Mock ๋ฐ์ดํฐ๊ฐ ์์ฑ๋ฉ๋๋ค. + +### ~~Network Error / CORS ์๋ฌ~~ +โ โ **ํด๊ฒฐ๋จ!** Next.js API proxy๋ฅผ ํตํด CORS ๋ฌธ์ ์ฐํ +โ ํ๋ก ํธ์๋๊ฐ `/api/content/*` โ ๋ฐฑ์๋ `localhost:8084` ๋ก ์๋ ํ๋ก์ + +### ์ด๋ฏธ์ง ์์ฑ ์คํจ +โ Content API (localhost:8084) ์คํ ์ฌ๋ถ ํ์ธ +โ ํฐ๋ฏธ๋์์ ํ์ธ: `curl http://localhost:8084/api/v1/content/events/7777/images` + +### ์ด๋ฏธ์ง๊ฐ ํ์๋์ง ์์ +โ ๋คํธ์ํฌ ํญ์์ CDN URL ๋ก๋ ์ํ ํ์ธ +โ Azure Blob Storage ์ ๊ทผ ๊ถํ ํ์ธ + +## API ํ์ธ + +```bash +# ์ด๋ฒคํธ 1761634317010์ ์ด๋ฏธ์ง ํ์ธ +curl http://localhost:8084/api/v1/content/events/1761634317010/images + +# ํ๋ก ํธ์๋ ํ๋ก์๋ฅผ ํตํ ํ์ธ (๊ฐ๋ฐ ์๋ฒ ์คํ ์ค) +curl http://localhost:3000/api/content/events/1761634317010/images +``` + +## ๋๋ฒ๊น + +๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ ๋๊ตฌ (F12) โ Console ํญ์์ ๋ค์ ๋ก๊ทธ ํ์ธ: + +``` +๐ฅ Loading generated images for event: 1761634317010 +โ Images loaded from API: 6 [...] +๐ธ Processing image 1: { id: 1, style: 'SIMPLE', platform: 'INSTAGRAM', ... } + โ Selected as latest SIMPLE image +๐ธ Processing image 2: { id: 3, style: 'FANCY', platform: 'INSTAGRAM', ... } + โ Selected as latest FANCY image +๐ธ Processing image 3: { id: 5, style: 'TRENDY', platform: 'INSTAGRAM', ... } + โ Selected as latest TRENDY image +๐จ Image map created with entries: { SIMPLE: 'YES โ ', FANCY: 'YES โ ', TRENDY: 'YES โ ', totalSize: 3 } +โ ์ด๋ฏธ์ง ๋ก๋ ์๋ฃ! ๋ฏธ๋ฆฌ๋ณด๊ธฐ ํ๋ฉด์ผ๋ก ์ ํํฉ๋๋ค. +๐ผ๏ธ Rendering SIMPLE: { hasImage: true, imageDataExists: true, cdnUrl: 'https://blob...' } +โ SIMPLE image loaded successfully +``` + +--- + +๋ ์์ธํ ๋ด์ฉ์ `MOCK_DATA_SETUP.md` ์ฐธ์กฐ diff --git a/TEST_URLS.md b/TEST_URLS.md new file mode 100644 index 0000000..df456ed --- /dev/null +++ b/TEST_URLS.md @@ -0,0 +1,117 @@ +# ๐ AI ์ด๋ฏธ์ง ์์ฑ ํ ์คํธ URL ๊ฐ์ด๋ + +## โ ์ฌ๋ฐ๋ฅธ URL + +### ContentPreview Step ์ง์ ์ ์ +``` +http://localhost:3000/events/create?event-creation.step=contentPreview +``` + +๋๋ ๊ฐ๋จํ๊ฒ: +``` +http://localhost:3000/events/create?step=contentPreview +``` + +### Mock ๋ฐ์ดํฐ ์ค์ ํ์ด์ง +``` +http://localhost:3000/init-mock-data.html +``` + +## ๐ URL ํ๋ผ๋ฏธํฐ ์ค๋ช + +- `event-creation.step=contentPreview` - Funnel์ step์ contentPreview๋ก ์ค์ +- `step=contentPreview` - ๊ฐ๋จํ ํ์ (funnel id๊ฐ event-creation์ผ ๋) + +## ๐ฏ ์ ์ฒด ํ๋ก์ฐ ํ ์คํธ URL + +### 1. ์์ (Objective Step) +``` +http://localhost:3000/events/create +``` + +### 2. Channel Step๊น์ง ์งํ ํ +``` +http://localhost:3000/events/create?event-creation.step=channel +``` + +### 3. ContentPreview Step (์ด๋ฏธ์ง ์์ฑ) +``` +http://localhost:3000/events/create?event-creation.step=contentPreview +``` + +## ๐ก ์๋ Mock ๋ฐ์ดํฐ ์์ฑ + +์ด์ `contentPreview` ํ์ด์ง์ ์ง์ ์ ์ํ๋ฉด: + +1. โ localStorage ํ์ธ +2. โ ๋ฐ์ดํฐ ์์ผ๋ฉด ์๋์ผ๋ก Mock ๋ฐ์ดํฐ ์์ฑ +3. โ ์ฆ์ AI ์ด๋ฏธ์ง ์์ฑ ์์ + +**๋ ์ด์ ์๋์ผ๋ก Mock ๋ฐ์ดํฐ๋ฅผ ์ค์ ํ ํ์๊ฐ ์์ต๋๋ค!** + +## ๐งช ํ ์คํธ ์๋๋ฆฌ์ค + +### ์๋๋ฆฌ์ค 1: ๊ฐ์ฅ ๋น ๋ฅธ ํ ์คํธ +```bash +# 1. ๊ฐ๋ฐ ์๋ฒ ์คํ +npm run dev + +# 2. ๋ธ๋ผ์ฐ์ ์์ ๋ฐ๋ก ์ ์ +http://localhost:3000/events/create?event-creation.step=contentPreview +``` +โ ์๋์ผ๋ก Mock ๋ฐ์ดํฐ ์์ฑ & ์ด๋ฏธ์ง ์์ฑ ์์! + +### ์๋๋ฆฌ์ค 2: ์ปค์คํ ๋ฐ์ดํฐ๋ก ํ ์คํธ +```bash +# 1. Mock ๋ฐ์ดํฐ ์ค์ ํ์ด์ง ์ด๊ธฐ +http://localhost:3000/init-mock-data.html + +# 2. ์ํ๋ ๋ฐ์ดํฐ ์ ๋ ฅ ํ ์ ์ฅ + +# 3. ContentPreview ์ ์ +http://localhost:3000/events/create?event-creation.step=contentPreview +``` + +### ์๋๋ฆฌ์ค 3: ์ ์ฒด ํ๋ก์ฐ ํ ์คํธ +```bash +# 1. ์ฒ์๋ถํฐ ์์ +http://localhost:3000/events/create + +# 2. Objective ์ ํ + +# 3. Recommendation ํ์ธ + +# 4. Channel ์ ํ (SNS, ์ฐ๋ฆฌ๋๋คTV, ์ง๋TV ์ค ํ๋) + +# 5. ์๋์ผ๋ก ContentPreview๋ก ์ด๋ํ๋ฉฐ ์ด๋ฏธ์ง ์์ฑ ์์ +``` + +## ๐ ๋ฌธ์ ํด๊ฒฐ + +### "์ด๋ฒคํธ ์ ๋ณด๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค" ์๋ฌ +โ ์ด์ ์ด ์๋ฌ๋ ๋ฐ์ํ์ง ์์ต๋๋ค! ์๋์ผ๋ก Mock ๋ฐ์ดํฐ๊ฐ ์์ฑ๋ฉ๋๋ค. + +### ์ด๋ฏธ์ง ์์ฑ ์คํจ +```bash +# Content API ์๋ฒ ํ์ธ +curl http://localhost:8084/api/v1/content/events/7777/images + +# API ์๋ฒ๊ฐ ๊บผ์ ธ์๋ค๋ฉด ์คํ ํ์ +``` + +### ๋ค๋ฅธ ์ด๋ฒคํธ ID๋ก ํ ์คํธํ๊ณ ์ถ์ ๋ +```javascript +// ๋ธ๋ผ์ฐ์ ์ฝ์์์ +localStorage.setItem('eventCreationData', JSON.stringify({ + eventDraftId: 8888, // ๋ค๋ฅธ ID + eventTitle: "์ปคํผ ํ ์ธ ์ด๋ฒคํธ", + eventDescription: "์ ๋ฉ๋ด ์ถ์ ๊ธฐ๋ ", + industry: "์นดํ", + location: "ํ๋", + trends: ["์ปคํผ", "ํ ์ธ"], + prize: "์๋ฉ๋ฆฌ์นด๋ ธ 1์" +})); + +// ํ์ด์ง ์๋ก๊ณ ์นจ +location.reload(); +``` diff --git a/next.config.js b/next.config.js index 03b1343..8bd207c 100644 --- a/next.config.js +++ b/next.config.js @@ -6,7 +6,7 @@ const nextConfig = { emotion: true, }, images: { - domains: ['localhost'], + domains: ['localhost', 'blobkteventstorage.blob.core.windows.net'], formats: ['image/webp', 'image/avif'], }, env: { diff --git a/public/init-mock-data.html b/public/init-mock-data.html new file mode 100644 index 0000000..9546666 --- /dev/null +++ b/public/init-mock-data.html @@ -0,0 +1,205 @@ + + +
+ + +์ด๋ฒคํธ ์์ฑ ํ ์คํธ๋ฅผ ์ํ ์ํ ๋ฐ์ดํฐ
+ +