diff --git a/src/features/dev/pages/ClinicsPage.tsx b/src/features/dev/pages/ClinicsPage.tsx
index b2e7e21..2402118 100644
--- a/src/features/dev/pages/ClinicsPage.tsx
+++ b/src/features/dev/pages/ClinicsPage.tsx
@@ -1,12 +1,12 @@
/**
* Dev: 클리닉 리스트 페이지.
*
- * 백엔드 `GET /api/clinics` (listClinics) 응답을 표로 확인하는 개발용 화면.
+ * 백엔드 `GET /api/clinics` (getClinics) 응답을 표로 확인하는 개발용 화면.
* 운영 도메인 노출 방지는 라우트 단의 DevOnly 가드에 위임.
*/
import { useState } from 'react';
import { Link } from 'react-router';
-import { useListClinics } from '@/shared/api/generated/clinics/clinics';
+import { useGetClinics } from '@/shared/api/generated/clinics/clinics';
import { PageContainer } from '@/shared/ui/page-container';
import { Spinner } from '@/shared/ui/spinner';
import { EmptyState } from '@/shared/ui/empty-state';
@@ -31,12 +31,13 @@ function formatDate(raw: string): string {
export default function ClinicsPage() {
const [offset, setOffset] = useState(0);
- const { data, isLoading, error, refetch, isFetching } = useListClinics(
+ const { data, isLoading, error, refetch, isFetching } = useGetClinics(
{ limit: PAGE_SIZE, offset },
{ query: { staleTime: 0 } },
);
- const items = data?.status === 200 ? data.data : [];
+ const items = data?.status === 200 ? data.data.items : [];
+ const total = data?.status === 200 ? data.data.total : 0;
return (
+
+ {total > 0 ? `${offset + 1}-${Math.min(offset + items.length, total)} / ${total}` : ''}
+
diff --git a/src/features/dev/routes.tsx b/src/features/dev/routes.tsx
index 0f0505f..9ec7c18 100644
--- a/src/features/dev/routes.tsx
+++ b/src/features/dev/routes.tsx
@@ -2,8 +2,7 @@ import { lazy } from 'react'
import DevOnly from './components/DevOnly'
const ComponentsPage = lazy(() => import('./pages/ComponentsPage'))
-// TODO: SDK 재생성으로 useListClinics 가 제거됨. 백엔드에 list 엔드포인트 재추가 후 복구.
-// const ClinicsPage = lazy(() => import('./pages/ClinicsPage'))
+const ClinicsPage = lazy(() => import('./pages/ClinicsPage'))
// `/dev/*` 는 DevOnly 가드를 거쳐 로컬호스트에서만 접근 가능.
export const devRoutes = [
@@ -11,7 +10,7 @@ export const devRoutes = [
element:
,
children: [
{ path: 'dev/components', element:
},
- // { path: 'dev/clinics', element:
},
+ { path: 'dev/clinics', element:
},
],
},
]
diff --git a/src/features/plan/components/MyAssetUpload.tsx b/src/features/plan/components/MyAssetUpload.tsx
index 3dd2489..6b6d6a0 100644
--- a/src/features/plan/components/MyAssetUpload.tsx
+++ b/src/features/plan/components/MyAssetUpload.tsx
@@ -1,10 +1,26 @@
-import { useState, useRef, useCallback, type DragEvent, type ChangeEvent } from 'react';
+import { useState, useRef, useCallback, useEffect, type DragEvent, type ChangeEvent } from 'react';
import { motion, AnimatePresence } from 'motion/react';
import { SectionWrapper } from '@/features/report/components/ui/SectionWrapper';
import { VideoFilled, FileTextFilled } from '@/shared/icons/FilledIcons';
import { Button } from '@/shared/ui/button';
+import { Spinner } from '@/shared/ui/spinner';
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from '@/shared/ui/dialog';
+import {
+ useUploadAnalysisRunFile,
+ useGetAnalysisRunFiles,
+ useDeleteAnalysisRunFile,
+} from '@/shared/api/generated/analysis/analysis';
+import type { FileListItem } from '@/shared/api/model/fileListItem';
import {
type UploadCategory,
+ type AssetCategory,
categoryConfig,
categoryBadge,
ALL_ACCEPT,
@@ -15,43 +31,141 @@ import {
// ─── Types ───
+type AssetStatus = 'idle' | 'uploading' | 'done' | 'error';
+
interface UploadedAsset {
id: string;
- file: File;
- category: 'image' | 'video' | 'text';
+ /** 로컬 업로드 직후엔 File 보유, 서버에서 받은 항목은 null. */
+ file: File | null;
+ category: AssetCategory;
previewUrl: string | null;
name: string;
size: string;
uploadedAt: Date;
+ status: AssetStatus;
+ remoteId?: number;
+ errorMessage?: string;
+}
+
+interface MyAssetUploadProps {
+ /** 업로드 대상 analysis run id. 없으면 로컬 미리보기만 동작. */
+ analysisRunId?: string;
+}
+
+// 백엔드 FileType ('image'|'video'|'audio'|'document'|'file') → 로컬 AssetCategory 1:1.
+function mapFileTypeToCategory(fileType: string): AssetCategory {
+ if (fileType === 'image' || fileType === 'video' || fileType === 'audio' || fileType === 'document') {
+ return fileType;
+ }
+ return 'file';
+}
+
+function serverFileToAsset(item: FileListItem): UploadedAsset {
+ const cat = mapFileTypeToCategory(item.file_type);
+ return {
+ id: `remote-${item.id}`,
+ file: null,
+ category: cat,
+ previewUrl: cat === 'image' || cat === 'video' ? item.file_url : null,
+ name: item.file_name,
+ size: typeof item.size_bytes === 'number' ? formatSize(item.size_bytes) : '',
+ uploadedAt: new Date(item.created_at),
+ status: 'done',
+ remoteId: item.id,
+ };
}
// ─── Component ───
-export default function MyAssetUpload() {
+export default function MyAssetUpload({ analysisRunId }: MyAssetUploadProps = {}) {
const [assets, setAssets] = useState
([]);
const [activeFilter, setActiveFilter] = useState('all');
const [isDragOver, setIsDragOver] = useState(false);
+ const [pendingDeleteId, setPendingDeleteId] = useState(null);
+ const [isDeleting, setIsDeleting] = useState(false);
const inputRef = useRef(null);
- const processFiles = useCallback((files: FileList | File[]) => {
- const newAssets: UploadedAsset[] = Array.from(files).map((file) => {
- const cat = categorize(file);
- const previewUrl =
- cat === 'image' || cat === 'video'
- ? URL.createObjectURL(file)
- : null;
- return {
- id: uid(),
- file,
- category: cat,
- previewUrl,
- name: file.name,
- size: formatSize(file.size),
- uploadedAt: new Date(),
- };
+ const { mutateAsync: uploadFile } = useUploadAnalysisRunFile();
+ const { mutateAsync: deleteFile } = useDeleteAnalysisRunFile();
+ const filesQuery = useGetAnalysisRunFiles(
+ analysisRunId ?? '',
+ { query: { enabled: !!analysisRunId } },
+ );
+
+ // 서버 파일 목록 → 로컬 assets 머지. 진행 중/실패 로컬 항목은 보존.
+ useEffect(() => {
+ if (filesQuery.data?.status !== 200) return;
+ const serverAssets = filesQuery.data.data.map(serverFileToAsset);
+ const serverIds = new Set(serverAssets.map((a) => a.remoteId));
+ setAssets((prev) => {
+ const localPending = prev.filter(
+ (a) => a.remoteId == null || !serverIds.has(a.remoteId),
+ );
+ return [...localPending, ...serverAssets];
});
- setAssets((prev) => [...newAssets, ...prev]);
- }, []);
+ }, [filesQuery.data]);
+
+ const processFiles = useCallback(
+ (files: FileList | File[]) => {
+ const newAssets: UploadedAsset[] = Array.from(files).map((file) => {
+ const cat = categorize(file);
+ const previewUrl =
+ cat === 'image' || cat === 'video' ? URL.createObjectURL(file) : null;
+ return {
+ id: uid(),
+ file,
+ category: cat,
+ previewUrl,
+ name: file.name,
+ size: formatSize(file.size),
+ uploadedAt: new Date(),
+ status: analysisRunId ? 'uploading' : 'idle',
+ };
+ });
+ setAssets((prev) => [...newAssets, ...prev]);
+
+ if (!analysisRunId) return;
+
+ newAssets.forEach(async (asset) => {
+ try {
+ const res = await uploadFile({
+ runId: analysisRunId,
+ // orval 이 binary 필드를 string 으로 타입 생성하므로 캐스팅 필요. 런타임은 FormData 로 정상 처리.
+ data: { file: asset.file as unknown as string, file_type: asset.category },
+ });
+ if (res.status === 201) {
+ setAssets((prev) =>
+ prev.map((a) =>
+ a.id === asset.id ? { ...a, status: 'done', remoteId: res.data.id } : a,
+ ),
+ );
+ filesQuery.refetch();
+ } else {
+ setAssets((prev) =>
+ prev.map((a) =>
+ a.id === asset.id
+ ? { ...a, status: 'error', errorMessage: '업로드 검증 실패' }
+ : a,
+ ),
+ );
+ }
+ } catch (err) {
+ setAssets((prev) =>
+ prev.map((a) =>
+ a.id === asset.id
+ ? {
+ ...a,
+ status: 'error',
+ errorMessage: err instanceof Error ? err.message : '업로드 실패',
+ }
+ : a,
+ ),
+ );
+ }
+ });
+ },
+ [analysisRunId, uploadFile, filesQuery],
+ );
const handleDrop = useCallback(
(e: DragEvent) => {
@@ -72,22 +186,48 @@ export default function MyAssetUpload() {
[processFiles],
);
- const removeAsset = useCallback((id: string) => {
- setAssets((prev) => {
- const found = prev.find((a) => a.id === id);
- if (found?.previewUrl) URL.revokeObjectURL(found.previewUrl);
- return prev.filter((a) => a.id !== id);
- });
- }, []);
+ const confirmDelete = useCallback(async () => {
+ if (!pendingDeleteId) return;
+ const target = assets.find((a) => a.id === pendingDeleteId);
+ if (!target) {
+ setPendingDeleteId(null);
+ return;
+ }
+
+ setIsDeleting(true);
+
+ if (target.file && target.previewUrl) URL.revokeObjectURL(target.previewUrl);
+
+ if (analysisRunId && target.remoteId != null) {
+ try {
+ await deleteFile({ runId: analysisRunId, fileId: target.remoteId });
+ filesQuery.refetch();
+ } catch {
+ setIsDeleting(false);
+ setPendingDeleteId(null);
+ return;
+ }
+ }
+
+ setAssets((prev) => prev.filter((a) => a.id !== pendingDeleteId));
+ setIsDeleting(false);
+ setPendingDeleteId(null);
+ }, [pendingDeleteId, assets, analysisRunId, deleteFile, filesQuery]);
+
+ const pendingDeleteAsset = pendingDeleteId
+ ? assets.find((a) => a.id === pendingDeleteId) ?? null
+ : null;
const filtered =
activeFilter === 'all' ? assets : assets.filter((a) => a.category === activeFilter);
- const counts = {
+ const counts: Record = {
all: assets.length,
image: assets.filter((a) => a.category === 'image').length,
video: assets.filter((a) => a.category === 'video').length,
- text: assets.filter((a) => a.category === 'text').length,
+ audio: assets.filter((a) => a.category === 'audio').length,
+ document: assets.filter((a) => a.category === 'document').length,
+ file: assets.filter((a) => a.category === 'file').length,
};
return (
@@ -143,17 +283,17 @@ export default function MyAssetUpload() {
파일을 드래그하거나 클릭하여 업로드
- Image, Video, Text 파일 지원 (JPG, PNG, MP4, MOV, TXT, PDF, DOC 등)
+ Image, Video, Audio, Document, File 지원 (JPG, MP4, MP3, PDF, DOCX, ZIP 등)
{/* File Type Badges */}
-
- {(['image', 'video', 'text'] as const).map((cat) => (
+
+ {(['image', 'video', 'audio', 'document', 'file'] as const).map((cat) => (
- {cat === 'image' ? 'Image' : cat === 'video' ? 'Video' : 'Text'}
+ {categoryConfig[cat].label}
))}
@@ -216,7 +356,9 @@ export default function MyAssetUpload() {
}}
/>
)}
- {asset.category === 'text' && (
+ {(asset.category === 'audio' ||
+ asset.category === 'document' ||
+ asset.category === 'file') && (
@@ -230,7 +372,7 @@ export default function MyAssetUpload() {
type="button"
variant="ghost"
size="icon-sm"
- onClick={() => removeAsset(asset.id)}
+ onClick={() => setPendingDeleteId(asset.id)}
className="absolute top-2 right-2 w-7 h-7 size-7 rounded-full bg-white/90 backdrop-blur-sm border border-slate-100 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity shadow-sm hover:bg-brand-rose-bg"
>
))}
@@ -271,6 +430,43 @@ export default function MyAssetUpload() {
>
)}
+
+
);
}
diff --git a/src/features/plan/data/myAssetUploadConstants.ts b/src/features/plan/data/myAssetUploadConstants.ts
index bc5e4d8..4db1831 100644
--- a/src/features/plan/data/myAssetUploadConstants.ts
+++ b/src/features/plan/data/myAssetUploadConstants.ts
@@ -1,30 +1,54 @@
-export type UploadCategory = 'all' | 'image' | 'video' | 'text';
+/**
+ * 백엔드 FileType 과 1:1 매칭되는 5종 분류.
+ * image — jpg, png, gif, webp, heic
+ * video — mp4, mov, avi, webm
+ * audio — mp3, wav, m4a, ogg
+ * document — pdf, docx, xlsx, pptx, txt, csv, hwp
+ * file — 그 외/분류 애매 (zip, json 등)
+ */
+export type AssetCategory = 'image' | 'video' | 'audio' | 'document' | 'file';
+export type UploadCategory = 'all' | AssetCategory;
export const categoryConfig: Record = {
all: { label: '전체' },
image: { label: 'Image' },
video: { label: 'Video' },
- text: { label: 'Text' },
+ audio: { label: 'Audio' },
+ document: { label: 'Document' },
+ file: { label: 'File' },
};
-export const categoryBadge: Record<'image' | 'video' | 'text', string> = {
+export const categoryBadge: Record = {
image: 'bg-brand-tint-purple text-brand-purple-muted shadow-[2px_3px_6px_rgba(155,138,212,0.12)]',
video: 'bg-brand-rose-bg text-brand-rose shadow-[2px_3px_6px_rgba(212,136,154,0.12)]',
- text: 'bg-brand-earth-bg text-brand-earth shadow-[2px_3px_6px_rgba(212,168,114,0.12)]',
+ audio: 'bg-sky-50 text-sky-700 shadow-[2px_3px_6px_rgba(56,189,248,0.12)]',
+ document: 'bg-brand-earth-bg text-brand-earth shadow-[2px_3px_6px_rgba(212,168,114,0.12)]',
+ file: 'bg-slate-100 text-slate-600 shadow-[2px_3px_6px_rgba(100,116,139,0.10)]',
};
-export const ACCEPT_MAP: Record = {
- 'image/*': '.jpg,.jpeg,.png,.gif,.webp,.svg',
- 'video/*': '.mp4,.mov,.webm,.avi',
- 'text/*': '.txt,.md,.doc,.docx,.pdf,.csv,.json',
+// 확장자 → 카테고리. 백엔드 분류 규칙과 동일.
+const EXT_BY_CATEGORY: Record = {
+ image: ['jpg', 'jpeg', 'png', 'gif', 'webp', 'heic'],
+ video: ['mp4', 'mov', 'avi', 'webm'],
+ audio: ['mp3', 'wav', 'm4a', 'ogg'],
+ document: ['pdf', 'docx', 'xlsx', 'pptx', 'txt', 'csv', 'hwp'],
+ file: [], // 폴백
};
-export const ALL_ACCEPT = Object.values(ACCEPT_MAP).join(',');
+export const ALL_ACCEPT = (Object.entries(EXT_BY_CATEGORY) as [AssetCategory, string[]][])
+ .flatMap(([, exts]) => exts.map((e) => `.${e}`))
+ .join(',');
-export function categorize(file: File): 'image' | 'video' | 'text' {
+export function categorize(file: File): AssetCategory {
+ const ext = file.name.split('.').pop()?.toLowerCase() ?? '';
+ for (const [cat, exts] of Object.entries(EXT_BY_CATEGORY) as [AssetCategory, string[]][]) {
+ if (exts.includes(ext)) return cat;
+ }
+ // MIME 폴백 — 확장자 누락된 케이스 보완.
if (file.type.startsWith('image/')) return 'image';
if (file.type.startsWith('video/')) return 'video';
- return 'text';
+ if (file.type.startsWith('audio/')) return 'audio';
+ return 'file';
}
export function formatSize(bytes: number): string {
diff --git a/src/features/plan/hooks/useMarketingPlan.ts b/src/features/plan/hooks/useMarketingPlan.ts
index f7357a6..d15a07f 100644
--- a/src/features/plan/hooks/useMarketingPlan.ts
+++ b/src/features/plan/hooks/useMarketingPlan.ts
@@ -1,6 +1,6 @@
import { useState, useEffect } from 'react';
import type { MarketingPlan } from '@/features/plan/types/plan';
-import { getPlan } from '@/shared/api/generated/plans/plans';
+import { getPlan } from '@/shared/api/generated/plan/plan';
interface UseMarketingPlanResult {
data: MarketingPlan | null;
@@ -32,19 +32,14 @@ export function useMarketingPlan(id: string | undefined): UseMarketingPlanResult
throw new Error('마케팅 기획이 아직 생성되지 않았습니다.');
}
+ // SDK PlanApiResponse 가 MarketingPlan 과 사실상 동일 — 패스스루.
+ // reportId/workflow 는 SDK 에 없는 로컬 전용 필드.
setData({
- id: id!,
+ ...(planOutput as unknown as MarketingPlan),
+ id: planOutput.id || id!,
reportId: id!,
- clinicName: '',
- clinicNameEn: '',
- createdAt: '',
- targetUrl: '',
- brandGuide: planOutput.brandGuide as MarketingPlan['brandGuide'],
- channelStrategies: planOutput.channelStrategies as MarketingPlan['channelStrategies'],
- contentStrategy: planOutput.contentStrategy as MarketingPlan['contentStrategy'],
- calendar: planOutput.calendar as MarketingPlan['calendar'],
- assetCollection: planOutput.assetCollection as MarketingPlan['assetCollection'],
- repurposingProposals: (planOutput.repurposingProposals ?? undefined) as MarketingPlan['repurposingProposals'],
+ clinicName: planOutput.clinicName ?? '',
+ clinicNameEn: planOutput.clinicNameEn ?? '',
});
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to fetch marketing plan');
diff --git a/src/features/plan/pages/GuestPlanPage.tsx b/src/features/plan/pages/GuestPlanPage.tsx
deleted file mode 100644
index c77cc05..0000000
--- a/src/features/plan/pages/GuestPlanPage.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * GuestPlanPage — `/plan/:id`
- *
- * 손님(비계약 방문자)이 보는 플랜 미리보기. 본문은 UserPlanPage 와 동일하나,
- * 인터랙티브 섹션(자산 업로드/전략 조정/워크플로우)은 노출되지 않고
- * 하단에 도입 문의 CTA(PlanCTA) 가 붙습니다.
- */
-import { useEffect } from 'react';
-import { useParams, useLocation } from 'react-router';
-import { useMarketingPlan } from '../hooks/useMarketingPlan';
-import { ReportNav } from '@/features/report/components/ReportNav';
-import { PLAN_SECTIONS } from '@/shared/constants/planSections';
-import PlanBody from '../components/PlanBody';
-
-export default function GuestPlanPage() {
- const { id } = useParams<{ id: string }>();
- const location = useLocation();
- const { data, isLoading, error } = useMarketingPlan(id);
-
- // 해시 기반 스크롤: /plan/:id#section-id → 렌더링 후 해당 섹션으로
- useEffect(() => {
- if (isLoading || !location.hash) return;
- const sectionId = location.hash.slice(1);
- const timer = setTimeout(() => {
- const el = document.getElementById(sectionId);
- if (!el) return;
- const STICKY_OFFSET = 128;
- const y = el.getBoundingClientRect().top + window.scrollY - STICKY_OFFSET;
- window.scrollTo({ top: y, behavior: 'smooth' });
- }, 300);
- return () => clearTimeout(timer);
- }, [isLoading, location.hash]);
-
- if (isLoading) {
- return (
-
- );
- }
-
- if (error || !data) {
- return (
-
-
-
오류가 발생했습니다
-
- {error ?? '마케팅 기획을 찾을 수 없습니다.'}
-
-
-
- );
- }
-
- return (
-
- );
-}
diff --git a/src/features/plan/pages/UserPlanPage.tsx b/src/features/plan/pages/PlanPage.tsx
similarity index 66%
rename from src/features/plan/pages/UserPlanPage.tsx
rename to src/features/plan/pages/PlanPage.tsx
index 4c6df6f..67e5c29 100644
--- a/src/features/plan/pages/UserPlanPage.tsx
+++ b/src/features/plan/pages/PlanPage.tsx
@@ -1,12 +1,12 @@
/**
- * UserPlanPage — `/clinics/:clinicId/plan/:id`
+ * PlanPage — 마케팅 기획 화면 (단일 페이지).
*
- * 계약된 병원 유저가 워크스페이스에서 운영하는 마케팅 기획 화면.
- * GuestPlanPage 의 본문 + 워크스페이스 액션바 + 인터랙티브 섹션
- * (MyAssetUpload / WorkflowTracker).
+ * 두 경로에서 동일 컴포넌트로 진입:
+ * - `/plan/:id` (랜딩 → 분석 → 리포트 → 플랜)
+ * - `/clinics/:clinicId/plan/:id` (워크스페이스 진입)
*
- * NOTE: StrategyAdjustmentSection(성과 기반 전략 조정) 은 성과 데이터 파이프라인 의존 →
- * 본 차수 미포함, 후속 모듈로 이관. 아래 import/render 주석 처리.
+ * 본문(PlanBody) + 인터랙티브 섹션(MyAssetUpload / WorkflowTracker) + 도입 문의 CTA 모두 노출.
+ * 업로드는 analysisRunId(=URL :id) 를 항상 넘기므로 어디서 들어와도 SDK 호출.
*/
import { useEffect } from 'react';
import { useParams, useLocation } from 'react-router';
@@ -15,15 +15,15 @@ import { ReportNav } from '@/features/report/components/ReportNav';
import { PLAN_SECTIONS } from '@/shared/constants/planSections';
import PlanBody from '../components/PlanBody';
import MyAssetUpload from '../components/MyAssetUpload';
-// import StrategyAdjustmentSection from '../components/StrategyAdjustmentSection';
import WorkflowTracker from '../components/WorkflowTracker';
+import PlanCTA from '../components/PlanCTA';
-export default function UserPlanPage() {
- const { id } = useParams<{ clinicId: string; id: string }>();
+export default function PlanPage() {
+ const { id } = useParams<{ clinicId?: string; id: string }>();
const location = useLocation();
- // const stateClinicId = (location.state as { clinicId?: string } | undefined)?.clinicId || null;
const { data, isLoading, error } = useMarketingPlan(id);
+ // 해시 기반 스크롤: /plan/:id#section-id → 렌더링 후 해당 섹션으로
useEffect(() => {
if (isLoading || !location.hash) return;
const sectionId = location.hash.slice(1);
@@ -65,7 +65,6 @@ export default function UserPlanPage() {
- {/* 유저 전용 인터랙티브 섹션 */}
{data.workflow && (
@@ -73,13 +72,10 @@ export default function UserPlanPage() {
)}
-
+
- {/* 성과 기반 전략 조정 — 본 차수 미포함, 후속 모듈 이관 */}
- {/*
-
-
*/}
+
);
}
diff --git a/src/features/plan/routes.tsx b/src/features/plan/routes.tsx
index e2c038d..ee7d1cd 100644
--- a/src/features/plan/routes.tsx
+++ b/src/features/plan/routes.tsx
@@ -1,9 +1,10 @@
import { lazy } from 'react'
import type { RouteObject } from 'react-router'
-const GuestPlanPage = lazy(() => import('./pages/GuestPlanPage'))
+const PlanPage = lazy(() => import('./pages/PlanPage'))
export const planRoutes: RouteObject[] = [
- // 손님(랜딩→분석→리포트→플랜) 흐름. 유저 워크스페이스 경로는 features/clinics/routes.tsx 참조.
- { path: 'plan/:id', element: },
+ // `/plan/:id` 와 `/clinics/:clinicId/plan/:id` 모두 동일 PlanPage 사용.
+ // 워크스페이스 경로 정의는 features/clinics/routes.tsx 참조.
+ { path: 'plan/:id', element: },
]
diff --git a/src/features/report/hooks/useReport.ts b/src/features/report/hooks/useReport.ts
index 3dbc882..df4fb76 100644
--- a/src/features/report/hooks/useReport.ts
+++ b/src/features/report/hooks/useReport.ts
@@ -1,7 +1,6 @@
import { useState, useEffect } from 'react';
import type { MarketingReport } from '@/features/report/types/report';
-import { getReport } from '@/shared/api/generated/reports/reports';
-import { transformReportOutput } from '@/features/report/lib/transformReport';
+import { getReport } from '@/shared/api/generated/report/report';
interface UseReportResult {
data: MarketingReport | null;
@@ -33,8 +32,9 @@ export function useReport(id: string | undefined): UseReportResult {
if (!output) {
throw new Error('리포트 데이터가 비어있습니다.');
}
- const transformed = transformReportOutput(id, output, { url: '', generatedAt: '' });
- setData(transformed);
+ // SDK MarketingReportResponse 가 사실상 MarketingReport 와 같은 shape — 그대로 사용.
+ // 미세한 차이(ScreenshotEvidence 등)는 컴포넌트 단에서 옵셔널로 처리됨.
+ setData(output as unknown as MarketingReport);
})
.catch((err) => {
setError(err instanceof Error ? err.message : 'Failed to fetch report');
diff --git a/src/features/report/lib/transformReport.ts b/src/features/report/lib/transformReport.ts
index 5aa887d..385b17f 100644
--- a/src/features/report/lib/transformReport.ts
+++ b/src/features/report/lib/transformReport.ts
@@ -1,6 +1,4 @@
import type { MarketingReport, Severity, ChannelScore, DiagnosisItem, TopVideo } from '@/features/report/types/report';
-import type { ReportOutput } from '@/shared/api/model/reportOutput';
-import type { ChannelScore as SdkChannelScore } from '@/shared/api/model/channelScore';
/**
* generate-report Edge Function의 API 응답.
@@ -1269,203 +1267,5 @@ export function mergeEnrichment(
return merged;
}
-// ════════════════════════════════════════════════════════════════════════════
-// SDK ReportOutput → MarketingReport 변환
-// 백엔드 OpenAPI 스펙(ReportOutput)을 그대로 받아 프론트엔드 컴포넌트가 기대하는
-// MarketingReport 형태로 매핑. ReportOutput에 없는 풍부한 메타(clinicSnapshot,
-// topVideos 등)는 빈 값으로 둠.
-// ════════════════════════════════════════════════════════════════════════════
-
-interface ReportMetadata {
- url: string;
- generatedAt?: string;
- clinicName?: string;
-}
-
-function channelScoreToScoreCard(
- channel: string,
- icon: string,
- ch: SdkChannelScore,
-): ChannelScore {
- return {
- channel,
- icon,
- score: ch.score,
- maxScore: 100,
- status: scoreToSeverity(ch.score),
- headline: ch.summary,
- };
-}
-
-function channelScoreToDiagnosis(
- category: string,
- ch: SdkChannelScore | null | undefined,
-): DiagnosisItem[] {
- if (!ch) return [];
- const items: DiagnosisItem[] = [];
- for (const weakness of ch.weaknesses) {
- items.push({ category, detail: weakness, severity: scoreToSeverity(ch.score) });
- }
- return items;
-}
-
-/** "1주차: 채널 역할 정의" → { month: 1, title: '1주차', subtitle: '채널 역할 정의' } */
-function parseRoadmapLine(line: string, index: number): import('../types/report').RoadmapMonth {
- const colonIdx = line.indexOf(':');
- if (colonIdx === -1) {
- return { month: index + 1, title: `Week ${index + 1}`, subtitle: line.trim(), tasks: [] };
- }
- return {
- month: index + 1,
- title: line.slice(0, colonIdx).trim(),
- subtitle: line.slice(colonIdx + 1).trim(),
- tasks: [],
- };
-}
-
-/**
- * 백엔드 SDK의 ReportOutput을 그대로 받아 MarketingReport로 변환.
- * - ReportOutput에 있는 필드: overall_score, {youtube,instagram,facebook,naver_blog,gangnam_unni}, conversion_strategy, roadmap, kpis
- * - 그 외 풍부한 메타(clinicSnapshot, topVideos, followers 등)는 SDK에 없으므로 빈/기본값
- */
-export function transformReportOutput(
- reportId: string,
- output: ReportOutput,
- metadata: ReportMetadata,
-): MarketingReport {
- const domain = (() => {
- try { return new URL(metadata.url).hostname; } catch { return metadata.url || ''; }
- })();
-
- // 채널별 score card — SDK에 값이 있는 채널만
- const channelScores: ChannelScore[] = [];
- if (output.youtube) channelScores.push(channelScoreToScoreCard('YouTube', 'youtube', output.youtube));
- if (output.instagram) channelScores.push(channelScoreToScoreCard('Instagram', 'instagram', output.instagram));
- if (output.facebook) channelScores.push(channelScoreToScoreCard('Facebook', 'facebook', output.facebook));
- if (output.naver_blog) channelScores.push(channelScoreToScoreCard('네이버 블로그', 'blog', output.naver_blog));
- if (output.gangnam_unni) channelScores.push(channelScoreToScoreCard('강남언니', 'star', output.gangnam_unni));
-
- // 전체 약점을 problemDiagnosis로 모음
- const problemDiagnosis: DiagnosisItem[] = [
- ...channelScoreToDiagnosis('YouTube', output.youtube),
- ...channelScoreToDiagnosis('Instagram', output.instagram),
- ...channelScoreToDiagnosis('Facebook', output.facebook),
- ...channelScoreToDiagnosis('네이버 블로그', output.naver_blog),
- ...channelScoreToDiagnosis('강남언니', output.gangnam_unni),
- ];
-
- return {
- id: reportId,
- createdAt: metadata.generatedAt || new Date().toISOString(),
- targetUrl: metadata.url,
- overallScore: output.overall_score,
-
- clinicSnapshot: {
- name: metadata.clinicName || '',
- nameEn: '',
- established: '',
- yearsInBusiness: 0,
- staffCount: 0,
- leadDoctor: { name: '', credentials: '', rating: 0, reviewCount: 0 },
- overallRating: 0,
- totalReviews: 0,
- priceRange: { min: '-', max: '-', currency: '₩' },
- certifications: [],
- mediaAppearances: [],
- medicalTourism: [],
- location: '',
- nearestStation: '',
- phone: '',
- domain,
- },
-
- channelScores,
-
- youtubeAudit: {
- channelName: '',
- handle: '',
- subscribers: 0,
- totalVideos: 0,
- totalViews: 0,
- weeklyViewGrowth: { absolute: 0, percentage: 0 },
- estimatedMonthlyRevenue: { min: 0, max: 0 },
- avgVideoLength: '-',
- uploadFrequency: '-',
- channelCreatedDate: '',
- subscriberRank: '-',
- channelDescription: output.youtube?.summary || '',
- linkedUrls: [],
- playlists: [],
- topVideos: [],
- diagnosis: channelScoreToDiagnosis('YouTube', output.youtube),
- },
-
- instagramAudit: {
- accounts: output.instagram ? [{
- handle: '',
- language: 'KR',
- label: '메인',
- posts: 0,
- followers: 0,
- following: 0,
- category: '의료/건강',
- profileLink: '',
- highlights: [],
- reelsCount: 0,
- contentFormat: '',
- profilePhoto: '',
- bio: output.instagram.summary,
- }] : [],
- diagnosis: channelScoreToDiagnosis('Instagram', output.instagram),
- },
-
- facebookAudit: {
- pages: [],
- diagnosis: channelScoreToDiagnosis('Facebook', output.facebook),
- brandInconsistencies: [],
- consolidationRecommendation: '',
- },
-
- otherChannels: [
- ...(output.naver_blog ? [{
- name: '네이버 블로그',
- status: 'active' as const,
- details: output.naver_blog.summary,
- }] : []),
- ...(output.gangnam_unni ? [{
- name: '강남언니',
- status: 'active' as const,
- details: output.gangnam_unni.summary,
- }] : []),
- ],
-
- websiteAudit: {
- primaryDomain: domain,
- additionalDomains: [],
- snsLinksOnSite: false,
- trackingPixels: [],
- mainCTA: '',
- },
-
- problemDiagnosis,
-
- transformation: {
- brandIdentity: [],
- contentStrategy: [],
- platformStrategies: [],
- websiteImprovements: [],
- newChannelProposals: [],
- },
-
- roadmap: output.roadmap.map(parseRoadmapLine),
-
- kpiDashboard: output.kpis.map((kpi) => ({
- metric: kpi,
- current: '-',
- target3Month: '-',
- target12Month: '-',
- })),
-
- screenshots: [],
- };
-}
+// SDK MarketingReportResponse ≈ MarketingReport — 별도 변환 함수 없이 useReport 에서
+// 직접 캐스팅해 사용. (구버전 ReportOutput 매핑 코드 제거)
diff --git a/src/shared/api/generated/analysis/analysis.ts b/src/shared/api/generated/analysis/analysis.ts
index b5f59ec..af47985 100644
--- a/src/shared/api/generated/analysis/analysis.ts
+++ b/src/shared/api/generated/analysis/analysis.ts
@@ -27,6 +27,9 @@ import type {
AnalysisCreate,
AnalysisStartResponse,
AnalysisStatusResponse,
+ BodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost,
+ FileListItem,
+ FileUploadResponse,
HTTPValidationError
} from '../../model';
@@ -128,6 +131,312 @@ export const useStartAnalysis = {
+
+
+
+
+ return `/api/analysis/${runId}/files`
+}
+
+export const uploadAnalysisRunFile = async (runId: string,
+ bodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost: BodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost, options?: RequestInit): Promise => {
+ const formData = new FormData();
+formData.append(`file`, bodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost.file)
+if(bodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost.file_type !== undefined) {
+ formData.append(`file_type`, bodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost.file_type)
+ }
+
+ return customFetcher(getUploadAnalysisRunFileUrl(runId),
+ {
+ ...options,
+ method: 'POST'
+ ,
+ body:
+ formData,
+ }
+);}
+
+
+
+
+export const getUploadAnalysisRunFileMutationOptions = (options?: { mutation?:UseMutationOptions>, TError,{runId: string;data: BodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost}, TContext>, request?: SecondParameter}
+): UseMutationOptions>, TError,{runId: string;data: BodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost}, TContext> => {
+
+const mutationKey = ['uploadAnalysisRunFile'];
+const {mutation: mutationOptions, request: requestOptions} = options ?
+ options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
+ options
+ : {...options, mutation: {...options.mutation, mutationKey}}
+ : {mutation: { mutationKey, }, request: undefined};
+
+
+
+
+ const mutationFn: MutationFunction>, {runId: string;data: BodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost}> = (props) => {
+ const {runId,data} = props ?? {};
+
+ return uploadAnalysisRunFile(runId,data,requestOptions)
+ }
+
+
+
+
+ return { mutationFn, ...mutationOptions }}
+
+ export type UploadAnalysisRunFileMutationResult = NonNullable>>
+ export type UploadAnalysisRunFileMutationBody = BodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost
+ export type UploadAnalysisRunFileMutationError = HTTPValidationError
+
+ /**
+ * @summary Upload Analysis Run File
+ */
+export const useUploadAnalysisRunFile = (options?: { mutation?:UseMutationOptions>, TError,{runId: string;data: BodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost}, TContext>, request?: SecondParameter}
+ , queryClient?: QueryClient): UseMutationResult<
+ Awaited>,
+ TError,
+ {runId: string;data: BodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost},
+ TContext
+ > => {
+
+ const mutationOptions = getUploadAnalysisRunFileMutationOptions(options);
+
+ return useMutation(mutationOptions, queryClient);
+ }
+ /**
+ * @summary Get Analysis Run Files
+ */
+export type getAnalysisRunFilesResponse200 = {
+ data: FileListItem[]
+ status: 200
+}
+
+export type getAnalysisRunFilesResponse422 = {
+ data: HTTPValidationError
+ status: 422
+}
+
+export type getAnalysisRunFilesResponseSuccess = (getAnalysisRunFilesResponse200) & {
+ headers: Headers;
+};
+export type getAnalysisRunFilesResponseError = (getAnalysisRunFilesResponse422) & {
+ headers: Headers;
+};
+
+export type getAnalysisRunFilesResponse = (getAnalysisRunFilesResponseSuccess | getAnalysisRunFilesResponseError)
+
+export const getGetAnalysisRunFilesUrl = (runId: string,) => {
+
+
+
+
+ return `/api/analysis/${runId}/files`
+}
+
+export const getAnalysisRunFiles = async (runId: string, options?: RequestInit): Promise => {
+
+ return customFetcher(getGetAnalysisRunFilesUrl(runId),
+ {
+ ...options,
+ method: 'GET'
+
+
+ }
+);}
+
+
+
+
+
+export const getGetAnalysisRunFilesQueryKey = (runId?: string,) => {
+ return [
+ `/api/analysis/${runId}/files`
+ ] as const;
+ }
+
+
+export const getGetAnalysisRunFilesQueryOptions = >, TError = HTTPValidationError>(runId: string, options?: { query?:Partial>, TError, TData>>, request?: SecondParameter}
+) => {
+
+const {query: queryOptions, request: requestOptions} = options ?? {};
+
+ const queryKey = queryOptions?.queryKey ?? getGetAnalysisRunFilesQueryKey(runId);
+
+
+
+ const queryFn: QueryFunction>> = () => getAnalysisRunFiles(runId, requestOptions);
+
+
+
+
+
+ return { queryKey, queryFn, enabled: !!(runId), staleTime: 60000, ...queryOptions} as UseQueryOptions>, TError, TData> & { queryKey: DataTag }
+}
+
+export type GetAnalysisRunFilesQueryResult = NonNullable>>
+export type GetAnalysisRunFilesQueryError = HTTPValidationError
+
+
+export function useGetAnalysisRunFiles>, TError = HTTPValidationError>(
+ runId: string, options: { query:Partial>, TError, TData>> & Pick<
+ DefinedInitialDataOptions<
+ Awaited>,
+ TError,
+ Awaited>
+ > , 'initialData'
+ >, request?: SecondParameter}
+ , queryClient?: QueryClient
+ ): DefinedUseQueryResult & { queryKey: DataTag }
+export function useGetAnalysisRunFiles>, TError = HTTPValidationError>(
+ runId: string, options?: { query?:Partial>, TError, TData>> & Pick<
+ UndefinedInitialDataOptions<
+ Awaited>,
+ TError,
+ Awaited>
+ > , 'initialData'
+ >, request?: SecondParameter}
+ , queryClient?: QueryClient
+ ): UseQueryResult & { queryKey: DataTag }
+export function useGetAnalysisRunFiles>, TError = HTTPValidationError>(
+ runId: string, options?: { query?:Partial>, TError, TData>>, request?: SecondParameter}
+ , queryClient?: QueryClient
+ ): UseQueryResult & { queryKey: DataTag }
+/**
+ * @summary Get Analysis Run Files
+ */
+
+export function useGetAnalysisRunFiles>, TError = HTTPValidationError>(
+ runId: string, options?: { query?:Partial>, TError, TData>>, request?: SecondParameter}
+ , queryClient?: QueryClient
+ ): UseQueryResult & { queryKey: DataTag } {
+
+ const queryOptions = getGetAnalysisRunFilesQueryOptions(runId,options)
+
+ const query = useQuery(queryOptions, queryClient) as UseQueryResult & { queryKey: DataTag };
+
+ query.queryKey = queryOptions.queryKey ;
+
+ return query;
+}
+
+
+
+
+/**
+ * @summary Delete Analysis Run File
+ */
+export type deleteAnalysisRunFileResponse204 = {
+ data: void
+ status: 204
+}
+
+export type deleteAnalysisRunFileResponse422 = {
+ data: HTTPValidationError
+ status: 422
+}
+
+export type deleteAnalysisRunFileResponseSuccess = (deleteAnalysisRunFileResponse204) & {
+ headers: Headers;
+};
+export type deleteAnalysisRunFileResponseError = (deleteAnalysisRunFileResponse422) & {
+ headers: Headers;
+};
+
+export type deleteAnalysisRunFileResponse = (deleteAnalysisRunFileResponseSuccess | deleteAnalysisRunFileResponseError)
+
+export const getDeleteAnalysisRunFileUrl = (runId: string,
+ fileId: number,) => {
+
+
+
+
+ return `/api/analysis/${runId}/files/${fileId}`
+}
+
+export const deleteAnalysisRunFile = async (runId: string,
+ fileId: number, options?: RequestInit): Promise => {
+
+ return customFetcher(getDeleteAnalysisRunFileUrl(runId,fileId),
+ {
+ ...options,
+ method: 'DELETE'
+
+
+ }
+);}
+
+
+
+
+export const getDeleteAnalysisRunFileMutationOptions = (options?: { mutation?:UseMutationOptions>, TError,{runId: string;fileId: number}, TContext>, request?: SecondParameter}
+): UseMutationOptions>, TError,{runId: string;fileId: number}, TContext> => {
+
+const mutationKey = ['deleteAnalysisRunFile'];
+const {mutation: mutationOptions, request: requestOptions} = options ?
+ options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
+ options
+ : {...options, mutation: {...options.mutation, mutationKey}}
+ : {mutation: { mutationKey, }, request: undefined};
+
+
+
+
+ const mutationFn: MutationFunction>, {runId: string;fileId: number}> = (props) => {
+ const {runId,fileId} = props ?? {};
+
+ return deleteAnalysisRunFile(runId,fileId,requestOptions)
+ }
+
+
+
+
+ return { mutationFn, ...mutationOptions }}
+
+ export type DeleteAnalysisRunFileMutationResult = NonNullable>>
+
+ export type DeleteAnalysisRunFileMutationError = HTTPValidationError
+
+ /**
+ * @summary Delete Analysis Run File
+ */
+export const useDeleteAnalysisRunFile = (options?: { mutation?:UseMutationOptions>, TError,{runId: string;fileId: number}, TContext>, request?: SecondParameter}
+ , queryClient?: QueryClient): UseMutationResult<
+ Awaited>,
+ TError,
+ {runId: string;fileId: number},
+ TContext
+ > => {
+
+ const mutationOptions = getDeleteAnalysisRunFileMutationOptions(options);
+
+ return useMutation(mutationOptions, queryClient);
+ }
+ /**
* @summary Get Analysis Status
*/
export type getAnalysisStatusResponse200 = {
diff --git a/src/shared/api/generated/clinics/clinics.ts b/src/shared/api/generated/clinics/clinics.ts
index 5b9fd76..90ac042 100644
--- a/src/shared/api/generated/clinics/clinics.ts
+++ b/src/shared/api/generated/clinics/clinics.ts
@@ -27,7 +27,9 @@ import type {
ClinicCreate,
ClinicCreateResponse,
ClinicHistoryResponse,
+ ClinicListResponse,
ClinicResponse,
+ GetClinicsParams,
HTTPValidationError
} from '../../model';
@@ -38,6 +40,132 @@ type SecondParameter unknown> = Parameters[1];
+/**
+ * @summary Get Clinics
+ */
+export type getClinicsResponse200 = {
+ data: ClinicListResponse
+ status: 200
+}
+
+export type getClinicsResponse422 = {
+ data: HTTPValidationError
+ status: 422
+}
+
+export type getClinicsResponseSuccess = (getClinicsResponse200) & {
+ headers: Headers;
+};
+export type getClinicsResponseError = (getClinicsResponse422) & {
+ headers: Headers;
+};
+
+export type getClinicsResponse = (getClinicsResponseSuccess | getClinicsResponseError)
+
+export const getGetClinicsUrl = (params?: GetClinicsParams,) => {
+ const normalizedParams = new URLSearchParams();
+
+ Object.entries(params || {}).forEach(([key, value]) => {
+
+ if (value !== undefined) {
+ normalizedParams.append(key, value === null ? 'null' : value.toString())
+ }
+ });
+
+ const stringifiedParams = normalizedParams.toString();
+
+ return stringifiedParams.length > 0 ? `/api/clinics?${stringifiedParams}` : `/api/clinics`
+}
+
+export const getClinics = async (params?: GetClinicsParams, options?: RequestInit): Promise => {
+
+ return customFetcher(getGetClinicsUrl(params),
+ {
+ ...options,
+ method: 'GET'
+
+
+ }
+);}
+
+
+
+
+
+export const getGetClinicsQueryKey = (params?: GetClinicsParams,) => {
+ return [
+ `/api/clinics`, ...(params ? [params]: [])
+ ] as const;
+ }
+
+
+export const getGetClinicsQueryOptions = >, TError = HTTPValidationError>(params?: GetClinicsParams, options?: { query?:Partial>, TError, TData>>, request?: SecondParameter}
+) => {
+
+const {query: queryOptions, request: requestOptions} = options ?? {};
+
+ const queryKey = queryOptions?.queryKey ?? getGetClinicsQueryKey(params);
+
+
+
+ const queryFn: QueryFunction>> = () => getClinics(params, requestOptions);
+
+
+
+
+
+ return { queryKey, queryFn, staleTime: 60000, ...queryOptions} as UseQueryOptions>, TError, TData> & { queryKey: DataTag }
+}
+
+export type GetClinicsQueryResult = NonNullable>>
+export type GetClinicsQueryError = HTTPValidationError
+
+
+export function useGetClinics>, TError = HTTPValidationError>(
+ params: undefined | GetClinicsParams, options: { query:Partial>, TError, TData>> & Pick<
+ DefinedInitialDataOptions<
+ Awaited>,
+ TError,
+ Awaited>
+ > , 'initialData'
+ >, request?: SecondParameter}
+ , queryClient?: QueryClient
+ ): DefinedUseQueryResult & { queryKey: DataTag }
+export function useGetClinics>, TError = HTTPValidationError>(
+ params?: GetClinicsParams, options?: { query?:Partial>, TError, TData>> & Pick<
+ UndefinedInitialDataOptions<
+ Awaited>,
+ TError,
+ Awaited>
+ > , 'initialData'
+ >, request?: SecondParameter}
+ , queryClient?: QueryClient
+ ): UseQueryResult & { queryKey: DataTag }
+export function useGetClinics>, TError = HTTPValidationError>(
+ params?: GetClinicsParams, options?: { query?:Partial>, TError, TData>>, request?: SecondParameter}
+ , queryClient?: QueryClient
+ ): UseQueryResult & { queryKey: DataTag }
+/**
+ * @summary Get Clinics
+ */
+
+export function useGetClinics>, TError = HTTPValidationError>(
+ params?: GetClinicsParams, options?: { query?:Partial>, TError, TData>>, request?: SecondParameter}
+ , queryClient?: QueryClient
+ ): UseQueryResult & { queryKey: DataTag } {
+
+ const queryOptions = getGetClinicsQueryOptions(params,options)
+
+ const query = useQuery(queryOptions, queryClient) as UseQueryResult & { queryKey: DataTag };
+
+ query.queryKey = queryOptions.queryKey ;
+
+ return query;
+}
+
+
+
+
/**
* @summary Create Clinic
*/
diff --git a/src/shared/api/generated/plans/plans.ts b/src/shared/api/generated/plan/plan.ts
similarity index 97%
rename from src/shared/api/generated/plans/plans.ts
rename to src/shared/api/generated/plan/plan.ts
index e31166f..f2b13f1 100644
--- a/src/shared/api/generated/plans/plans.ts
+++ b/src/shared/api/generated/plan/plan.ts
@@ -20,8 +20,8 @@ import type {
} from '@tanstack/react-query';
import type {
- GetPlan200,
- HTTPValidationError
+ HTTPValidationError,
+ PlanApiResponse
} from '../../model';
import { customFetcher } from '../../api';
@@ -35,7 +35,7 @@ type SecondParameter unknown> = Parameters[1];
* @summary Get Plan
*/
export type getPlanResponse200 = {
- data: GetPlan200
+ data: PlanApiResponse
status: 200
}
@@ -58,7 +58,7 @@ export const getGetPlanUrl = (runId: string,) => {
- return `/api/plans/${runId}`
+ return `/api/plan/${runId}`
}
export const getPlan = async (runId: string, options?: RequestInit): Promise => {
@@ -78,7 +78,7 @@ export const getPlan = async (runId: string, options?: RequestInit): Promise {
return [
- `/api/plans/${runId}`
+ `/api/plan/${runId}`
] as const;
}
diff --git a/src/shared/api/generated/reports/reports.ts b/src/shared/api/generated/report/report.ts
similarity index 96%
rename from src/shared/api/generated/reports/reports.ts
rename to src/shared/api/generated/report/report.ts
index af1e3ee..73589f6 100644
--- a/src/shared/api/generated/reports/reports.ts
+++ b/src/shared/api/generated/report/report.ts
@@ -20,8 +20,8 @@ import type {
} from '@tanstack/react-query';
import type {
- GetReport200,
- HTTPValidationError
+ HTTPValidationError,
+ MarketingReportResponse
} from '../../model';
import { customFetcher } from '../../api';
@@ -35,7 +35,7 @@ type SecondParameter unknown> = Parameters[1];
* @summary Get Report
*/
export type getReportResponse200 = {
- data: GetReport200
+ data: MarketingReportResponse
status: 200
}
@@ -58,7 +58,7 @@ export const getGetReportUrl = (runId: string,) => {
- return `/api/reports/${runId}`
+ return `/api/report/${runId}`
}
export const getReport = async (runId: string, options?: RequestInit): Promise => {
@@ -78,7 +78,7 @@ export const getReport = async (runId: string, options?: RequestInit): Promise {
return [
- `/api/reports/${runId}`
+ `/api/report/${runId}`
] as const;
}
diff --git a/src/shared/api/model/conversionStrategy.ts b/src/shared/api/model/additionalDomain.ts
similarity index 59%
rename from src/shared/api/model/conversionStrategy.ts
rename to src/shared/api/model/additionalDomain.ts
index 584280d..e99748b 100644
--- a/src/shared/api/model/conversionStrategy.ts
+++ b/src/shared/api/model/additionalDomain.ts
@@ -5,7 +5,7 @@
* OpenAPI spec version: 0.1.0
*/
-export interface ConversionStrategy {
- summary: string;
- actions: string[];
+export interface AdditionalDomain {
+ domain: string;
+ purpose: string;
}
diff --git a/src/shared/api/model/annotationType.ts b/src/shared/api/model/annotationType.ts
new file mode 100644
index 0000000..489688d
--- /dev/null
+++ b/src/shared/api/model/annotationType.ts
@@ -0,0 +1,16 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type AnnotationType = typeof AnnotationType[keyof typeof AnnotationType];
+
+
+// eslint-disable-next-line @typescript-eslint/no-redeclare
+export const AnnotationType = {
+ highlight: 'highlight',
+ arrow: 'arrow',
+ text: 'text',
+} as const;
diff --git a/src/shared/api/model/getPlan200.ts b/src/shared/api/model/asIsToBeItem.ts
similarity index 54%
rename from src/shared/api/model/getPlan200.ts
rename to src/shared/api/model/asIsToBeItem.ts
index fb75f97..6e1b7ee 100644
--- a/src/shared/api/model/getPlan200.ts
+++ b/src/shared/api/model/asIsToBeItem.ts
@@ -4,6 +4,9 @@
* FastAPI
* OpenAPI spec version: 0.1.0
*/
-import type { PlanOutput } from './planOutput';
-export type GetPlan200 = PlanOutput | null;
+export interface AsIsToBeItem {
+ area: string;
+ asIs: string;
+ toBe: string;
+}
diff --git a/src/shared/api/model/bodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost.ts b/src/shared/api/model/bodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost.ts
new file mode 100644
index 0000000..5924056
--- /dev/null
+++ b/src/shared/api/model/bodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost.ts
@@ -0,0 +1,14 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { FileType } from './fileType';
+
+export interface BodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost {
+ /** 업로드할 파일 */
+ file: string;
+ /** 파일 타입 (image/video/audio/document/file) */
+ file_type?: FileType;
+}
diff --git a/src/shared/api/model/getReport200.ts b/src/shared/api/model/brandColors.ts
similarity index 52%
rename from src/shared/api/model/getReport200.ts
rename to src/shared/api/model/brandColors.ts
index 005c321..f1ce5b2 100644
--- a/src/shared/api/model/getReport200.ts
+++ b/src/shared/api/model/brandColors.ts
@@ -4,6 +4,9 @@
* FastAPI
* OpenAPI spec version: 0.1.0
*/
-import type { ReportOutput } from './reportOutput';
-export type GetReport200 = ReportOutput | null;
+export interface BrandColors {
+ primary: string;
+ accent: string;
+ text: string;
+}
diff --git a/src/shared/api/model/brandGuide.ts b/src/shared/api/model/brandGuide.ts
index b28a597..5a1cd93 100644
--- a/src/shared/api/model/brandGuide.ts
+++ b/src/shared/api/model/brandGuide.ts
@@ -9,7 +9,7 @@ import type { FontSpec } from './fontSpec';
import type { LogoUsageRule } from './logoUsageRule';
import type { ToneOfVoice } from './toneOfVoice';
import type { ChannelBrandingRule } from './channelBrandingRule';
-import type { BrandInconsistency } from './brandInconsistency';
+import type { BrandPlanInconsistency } from './brandPlanInconsistency';
export interface BrandGuide {
colors: ColorSwatch[];
@@ -17,5 +17,5 @@ export interface BrandGuide {
logoRules: LogoUsageRule[];
toneOfVoice: ToneOfVoice;
channelBranding: ChannelBrandingRule[];
- brandInconsistencies: BrandInconsistency[];
+ brandInconsistencies: BrandPlanInconsistency[];
}
diff --git a/src/shared/api/model/brandPlanInconsistency.ts b/src/shared/api/model/brandPlanInconsistency.ts
new file mode 100644
index 0000000..541f737
--- /dev/null
+++ b/src/shared/api/model/brandPlanInconsistency.ts
@@ -0,0 +1,14 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { BrandPlanInconsistencyValue } from './brandPlanInconsistencyValue';
+
+export interface BrandPlanInconsistency {
+ field: string;
+ values: BrandPlanInconsistencyValue[];
+ impact: string;
+ recommendation: string;
+}
diff --git a/src/shared/api/model/reportOutputYoutube.ts b/src/shared/api/model/brandPlanInconsistencyValue.ts
similarity index 50%
rename from src/shared/api/model/reportOutputYoutube.ts
rename to src/shared/api/model/brandPlanInconsistencyValue.ts
index b1dd5c3..15478f6 100644
--- a/src/shared/api/model/reportOutputYoutube.ts
+++ b/src/shared/api/model/brandPlanInconsistencyValue.ts
@@ -4,6 +4,9 @@
* FastAPI
* OpenAPI spec version: 0.1.0
*/
-import type { ChannelScore } from './channelScore';
-export type ReportOutputYoutube = ChannelScore | null;
+export interface BrandPlanInconsistencyValue {
+ channel: string;
+ value: string;
+ isCorrect: boolean;
+}
diff --git a/src/shared/api/model/channelScore.ts b/src/shared/api/model/channelScore.ts
index 924af16..8cd3275 100644
--- a/src/shared/api/model/channelScore.ts
+++ b/src/shared/api/model/channelScore.ts
@@ -4,10 +4,13 @@
* FastAPI
* OpenAPI spec version: 0.1.0
*/
+import type { Severity } from './severity';
export interface ChannelScore {
+ channel: string;
+ icon: string;
score: number;
- summary: string;
- strengths: string[];
- weaknesses: string[];
+ maxScore: number;
+ status: Severity;
+ headline: string;
}
diff --git a/src/shared/api/model/channelStatus.ts b/src/shared/api/model/channelStatus.ts
new file mode 100644
index 0000000..5f8683b
--- /dev/null
+++ b/src/shared/api/model/channelStatus.ts
@@ -0,0 +1,17 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type ChannelStatus = typeof ChannelStatus[keyof typeof ChannelStatus];
+
+
+// eslint-disable-next-line @typescript-eslint/no-redeclare
+export const ChannelStatus = {
+ active: 'active',
+ inactive: 'inactive',
+ unknown: 'unknown',
+ not_found: 'not_found',
+} as const;
diff --git a/src/shared/api/model/clinicListItem.ts b/src/shared/api/model/clinicListItem.ts
new file mode 100644
index 0000000..fee02b5
--- /dev/null
+++ b/src/shared/api/model/clinicListItem.ts
@@ -0,0 +1,20 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { ClinicListItemHospitalNameEn } from './clinicListItemHospitalNameEn';
+import type { ClinicListItemRoadAddress } from './clinicListItemRoadAddress';
+import type { ClinicListItemUrl } from './clinicListItemUrl';
+
+export interface ClinicListItem {
+ hospital_id: string;
+ hospital_name: string;
+ hospital_name_en: ClinicListItemHospitalNameEn;
+ road_address: ClinicListItemRoadAddress;
+ url: ClinicListItemUrl;
+ status: string;
+ created_at: string;
+ updated_at: string;
+}
diff --git a/src/shared/api/model/clinicListItemHospitalNameEn.ts b/src/shared/api/model/clinicListItemHospitalNameEn.ts
new file mode 100644
index 0000000..83953ae
--- /dev/null
+++ b/src/shared/api/model/clinicListItemHospitalNameEn.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type ClinicListItemHospitalNameEn = string | null;
diff --git a/src/shared/api/model/clinicListItemRoadAddress.ts b/src/shared/api/model/clinicListItemRoadAddress.ts
new file mode 100644
index 0000000..ff9dd5d
--- /dev/null
+++ b/src/shared/api/model/clinicListItemRoadAddress.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type ClinicListItemRoadAddress = string | null;
diff --git a/src/shared/api/model/clinicListItemUrl.ts b/src/shared/api/model/clinicListItemUrl.ts
new file mode 100644
index 0000000..d22f813
--- /dev/null
+++ b/src/shared/api/model/clinicListItemUrl.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type ClinicListItemUrl = string | null;
diff --git a/src/shared/api/model/clinicListResponse.ts b/src/shared/api/model/clinicListResponse.ts
new file mode 100644
index 0000000..2415476
--- /dev/null
+++ b/src/shared/api/model/clinicListResponse.ts
@@ -0,0 +1,12 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { ClinicListItem } from './clinicListItem';
+
+export interface ClinicListResponse {
+ items: ClinicListItem[];
+ total: number;
+}
diff --git a/src/shared/api/model/clinicSnapshot.ts b/src/shared/api/model/clinicSnapshot.ts
new file mode 100644
index 0000000..2b0a32d
--- /dev/null
+++ b/src/shared/api/model/clinicSnapshot.ts
@@ -0,0 +1,35 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { LeadDoctor } from './leadDoctor';
+import type { PriceRange } from './priceRange';
+import type { ClinicSnapshotLogoImages } from './clinicSnapshotLogoImages';
+import type { ClinicSnapshotBrandColors } from './clinicSnapshotBrandColors';
+import type { ClinicSnapshotSource } from './clinicSnapshotSource';
+import type { ClinicSnapshotRegistryData } from './clinicSnapshotRegistryData';
+
+export interface ClinicSnapshot {
+ name: string;
+ nameEn: string;
+ established: string;
+ yearsInBusiness: number;
+ staffCount: number;
+ leadDoctor: LeadDoctor;
+ overallRating: number;
+ totalReviews: number;
+ priceRange: PriceRange;
+ certifications: string[];
+ mediaAppearances: string[];
+ medicalTourism: string[];
+ location: string;
+ nearestStation: string;
+ phone: string;
+ domain: string;
+ logoImages?: ClinicSnapshotLogoImages;
+ brandColors?: ClinicSnapshotBrandColors;
+ source?: ClinicSnapshotSource;
+ registryData?: ClinicSnapshotRegistryData;
+}
diff --git a/src/shared/api/model/reportOutputFacebook.ts b/src/shared/api/model/clinicSnapshotBrandColors.ts
similarity index 50%
rename from src/shared/api/model/reportOutputFacebook.ts
rename to src/shared/api/model/clinicSnapshotBrandColors.ts
index 322910e..072074f 100644
--- a/src/shared/api/model/reportOutputFacebook.ts
+++ b/src/shared/api/model/clinicSnapshotBrandColors.ts
@@ -4,6 +4,6 @@
* FastAPI
* OpenAPI spec version: 0.1.0
*/
-import type { ChannelScore } from './channelScore';
+import type { BrandColors } from './brandColors';
-export type ReportOutputFacebook = ChannelScore | null;
+export type ClinicSnapshotBrandColors = BrandColors | null;
diff --git a/src/shared/api/model/clinicSnapshotLogoImages.ts b/src/shared/api/model/clinicSnapshotLogoImages.ts
new file mode 100644
index 0000000..a3350f2
--- /dev/null
+++ b/src/shared/api/model/clinicSnapshotLogoImages.ts
@@ -0,0 +1,9 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { LogoImages } from './logoImages';
+
+export type ClinicSnapshotLogoImages = LogoImages | null;
diff --git a/src/shared/api/model/clinicSnapshotRegistryData.ts b/src/shared/api/model/clinicSnapshotRegistryData.ts
new file mode 100644
index 0000000..70955f6
--- /dev/null
+++ b/src/shared/api/model/clinicSnapshotRegistryData.ts
@@ -0,0 +1,9 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { RegistryData } from './registryData';
+
+export type ClinicSnapshotRegistryData = RegistryData | null;
diff --git a/src/shared/api/model/clinicSnapshotSource.ts b/src/shared/api/model/clinicSnapshotSource.ts
new file mode 100644
index 0000000..08957b4
--- /dev/null
+++ b/src/shared/api/model/clinicSnapshotSource.ts
@@ -0,0 +1,9 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { DataSource } from './dataSource';
+
+export type ClinicSnapshotSource = DataSource | null;
diff --git a/src/shared/api/model/contentPillar.ts b/src/shared/api/model/contentPillar.ts
index c3bc6f4..9132c02 100644
--- a/src/shared/api/model/contentPillar.ts
+++ b/src/shared/api/model/contentPillar.ts
@@ -8,7 +8,7 @@
export interface ContentPillar {
title: string;
description: string;
- relatedUSP: string;
+ relatedUsp: string;
exampleTopics: string[];
color: string;
}
diff --git a/src/shared/api/model/dataSource.ts b/src/shared/api/model/dataSource.ts
new file mode 100644
index 0000000..e0a38bd
--- /dev/null
+++ b/src/shared/api/model/dataSource.ts
@@ -0,0 +1,15 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type DataSource = typeof DataSource[keyof typeof DataSource];
+
+
+// eslint-disable-next-line @typescript-eslint/no-redeclare
+export const DataSource = {
+ registry: 'registry',
+ scrape: 'scrape',
+} as const;
diff --git a/src/shared/api/model/diagnosisItem.ts b/src/shared/api/model/diagnosisItem.ts
new file mode 100644
index 0000000..c263902
--- /dev/null
+++ b/src/shared/api/model/diagnosisItem.ts
@@ -0,0 +1,15 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { Severity } from './severity';
+import type { DiagnosisItemEvidenceIds } from './diagnosisItemEvidenceIds';
+
+export interface DiagnosisItem {
+ category: string;
+ detail: string;
+ severity: Severity;
+ evidenceIds?: DiagnosisItemEvidenceIds;
+}
diff --git a/src/shared/api/model/diagnosisItemEvidenceIds.ts b/src/shared/api/model/diagnosisItemEvidenceIds.ts
new file mode 100644
index 0000000..d59806b
--- /dev/null
+++ b/src/shared/api/model/diagnosisItemEvidenceIds.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type DiagnosisItemEvidenceIds = string[] | null;
diff --git a/src/shared/api/model/estimatedRevenue.ts b/src/shared/api/model/estimatedRevenue.ts
new file mode 100644
index 0000000..f31ce81
--- /dev/null
+++ b/src/shared/api/model/estimatedRevenue.ts
@@ -0,0 +1,11 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export interface EstimatedRevenue {
+ min: number;
+ max: number;
+}
diff --git a/src/shared/api/model/facebookAudit.ts b/src/shared/api/model/facebookAudit.ts
new file mode 100644
index 0000000..0e60b46
--- /dev/null
+++ b/src/shared/api/model/facebookAudit.ts
@@ -0,0 +1,16 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { FacebookPage } from './facebookPage';
+import type { DiagnosisItem } from './diagnosisItem';
+import type { BrandInconsistency } from './brandInconsistency';
+
+export interface FacebookAudit {
+ pages: FacebookPage[];
+ diagnosis: DiagnosisItem[];
+ brandInconsistencies: BrandInconsistency[];
+ consolidationRecommendation: string;
+}
diff --git a/src/shared/api/model/facebookPage.ts b/src/shared/api/model/facebookPage.ts
new file mode 100644
index 0000000..08df9f4
--- /dev/null
+++ b/src/shared/api/model/facebookPage.ts
@@ -0,0 +1,31 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { Language } from './language';
+import type { FacebookPagePostFrequency } from './facebookPagePostFrequency';
+import type { FacebookPageTopContentType } from './facebookPageTopContentType';
+import type { FacebookPageEngagement } from './facebookPageEngagement';
+
+export interface FacebookPage {
+ url: string;
+ pageName: string;
+ language: Language;
+ label: string;
+ followers: number;
+ following: number;
+ category: string;
+ bio: string;
+ logo: string;
+ logoDescription: string;
+ link: string;
+ linkedDomain: string;
+ reviews: number;
+ recentPostAge: string;
+ hasWhatsapp: boolean;
+ postFrequency?: FacebookPagePostFrequency;
+ topContentType?: FacebookPageTopContentType;
+ engagement?: FacebookPageEngagement;
+}
diff --git a/src/shared/api/model/facebookPageEngagement.ts b/src/shared/api/model/facebookPageEngagement.ts
new file mode 100644
index 0000000..afeda68
--- /dev/null
+++ b/src/shared/api/model/facebookPageEngagement.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type FacebookPageEngagement = string | null;
diff --git a/src/shared/api/model/facebookPagePostFrequency.ts b/src/shared/api/model/facebookPagePostFrequency.ts
new file mode 100644
index 0000000..1e5d9d5
--- /dev/null
+++ b/src/shared/api/model/facebookPagePostFrequency.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type FacebookPagePostFrequency = string | null;
diff --git a/src/shared/api/model/facebookPageTopContentType.ts b/src/shared/api/model/facebookPageTopContentType.ts
new file mode 100644
index 0000000..5851807
--- /dev/null
+++ b/src/shared/api/model/facebookPageTopContentType.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type FacebookPageTopContentType = string | null;
diff --git a/src/shared/api/model/fileListItem.ts b/src/shared/api/model/fileListItem.ts
new file mode 100644
index 0000000..c89d759
--- /dev/null
+++ b/src/shared/api/model/fileListItem.ts
@@ -0,0 +1,17 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { FileType } from './fileType';
+import type { FileListItemSizeBytes } from './fileListItemSizeBytes';
+
+export interface FileListItem {
+ id: number;
+ file_type: FileType;
+ file_name: string;
+ file_url: string;
+ size_bytes?: FileListItemSizeBytes;
+ created_at: string;
+}
diff --git a/src/shared/api/model/fileListItemSizeBytes.ts b/src/shared/api/model/fileListItemSizeBytes.ts
new file mode 100644
index 0000000..90c63c9
--- /dev/null
+++ b/src/shared/api/model/fileListItemSizeBytes.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type FileListItemSizeBytes = number | null;
diff --git a/src/shared/api/model/fileType.ts b/src/shared/api/model/fileType.ts
new file mode 100644
index 0000000..dd6807d
--- /dev/null
+++ b/src/shared/api/model/fileType.ts
@@ -0,0 +1,18 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type FileType = typeof FileType[keyof typeof FileType];
+
+
+// eslint-disable-next-line @typescript-eslint/no-redeclare
+export const FileType = {
+ image: 'image',
+ video: 'video',
+ audio: 'audio',
+ document: 'document',
+ file: 'file',
+} as const;
diff --git a/src/shared/api/model/fileUploadResponse.ts b/src/shared/api/model/fileUploadResponse.ts
new file mode 100644
index 0000000..ac2533e
--- /dev/null
+++ b/src/shared/api/model/fileUploadResponse.ts
@@ -0,0 +1,17 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { FileType } from './fileType';
+import type { FileUploadResponseSizeBytes } from './fileUploadResponseSizeBytes';
+
+export interface FileUploadResponse {
+ id: number;
+ analysis_run_id: string;
+ file_type: FileType;
+ file_name: string;
+ file_url: string;
+ size_bytes?: FileUploadResponseSizeBytes;
+}
diff --git a/src/shared/api/model/fileUploadResponseSizeBytes.ts b/src/shared/api/model/fileUploadResponseSizeBytes.ts
new file mode 100644
index 0000000..d1078a3
--- /dev/null
+++ b/src/shared/api/model/fileUploadResponseSizeBytes.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type FileUploadResponseSizeBytes = number | null;
diff --git a/src/shared/api/model/getClinicsParams.ts b/src/shared/api/model/getClinicsParams.ts
new file mode 100644
index 0000000..b8c3608
--- /dev/null
+++ b/src/shared/api/model/getClinicsParams.ts
@@ -0,0 +1,11 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type GetClinicsParams = {
+limit?: number;
+offset?: number;
+};
diff --git a/src/shared/api/model/index.ts b/src/shared/api/model/index.ts
index 62d19a4..12185b3 100644
--- a/src/shared/api/model/index.ts
+++ b/src/shared/api/model/index.ts
@@ -5,6 +5,7 @@
* OpenAPI spec version: 0.1.0
*/
+export * from './additionalDomain';
export * from './analysisCreate';
export * from './analysisOptions';
export * from './analysisStartResponse';
@@ -12,14 +13,20 @@ export * from './analysisStatus';
export * from './analysisStatusResponse';
export * from './analysisStatusResponseChannelErrors';
export * from './analysisStatusResponseCompletedAt';
+export * from './annotationType';
+export * from './asIsToBeItem';
export * from './assetCard';
export * from './assetCardSource';
export * from './assetCardStatus';
export * from './assetCardType';
export * from './assetCollectionData';
+export * from './bodyUploadAnalysisRunFileApiAnalysisRunIdFilesPost';
+export * from './brandColors';
export * from './brandGuide';
export * from './brandInconsistency';
export * from './brandInconsistencyValue';
+export * from './brandPlanInconsistency';
+export * from './brandPlanInconsistencyValue';
export * from './calendarData';
export * from './calendarEntry';
export * from './calendarEntryAiPromptSeed';
@@ -33,6 +40,7 @@ export * from './calendarWeek';
export * from './channelBrandingRule';
export * from './channelBrandingRuleCurrentStatus';
export * from './channelScore';
+export * from './channelStatus';
export * from './channelStrategyCard';
export * from './channelStrategyCardCustomerJourneyStage';
export * from './channelStrategyCardPriority';
@@ -46,43 +54,111 @@ export * from './clinicCreate';
export * from './clinicCreateResponse';
export * from './clinicHistoryResponse';
export * from './clinicHistoryResponseMetricsTimeseries';
+export * from './clinicListItem';
+export * from './clinicListItemHospitalNameEn';
+export * from './clinicListItemRoadAddress';
+export * from './clinicListItemUrl';
+export * from './clinicListResponse';
export * from './clinicResponse';
export * from './clinicResponseHospitalNameEn';
export * from './clinicResponseRawData';
export * from './clinicResponseRawDataAnyOf';
export * from './clinicResponseRoadAddress';
export * from './clinicResponseUrl';
+export * from './clinicSnapshot';
+export * from './clinicSnapshotBrandColors';
+export * from './clinicSnapshotLogoImages';
+export * from './clinicSnapshotRegistryData';
+export * from './clinicSnapshotSource';
export * from './colorSwatch';
export * from './contentCountSummary';
export * from './contentCountSummaryType';
export * from './contentPillar';
export * from './contentStrategyData';
export * from './contentTypeRow';
-export * from './conversionStrategy';
+export * from './dataSource';
+export * from './diagnosisItem';
+export * from './diagnosisItemEvidenceIds';
+export * from './estimatedRevenue';
+export * from './facebookAudit';
+export * from './facebookPage';
+export * from './facebookPageEngagement';
+export * from './facebookPagePostFrequency';
+export * from './facebookPageTopContentType';
+export * from './fileListItem';
+export * from './fileListItemSizeBytes';
+export * from './fileType';
+export * from './fileUploadResponse';
+export * from './fileUploadResponseSizeBytes';
export * from './fontSpec';
-export * from './getPlan200';
-export * from './getReport200';
+export * from './getClinicsParams';
export * from './hTTPValidationError';
+export * from './instagramAccount';
+export * from './instagramAudit';
+export * from './kPIMetric';
+export * from './language';
+export * from './leadDoctor';
+export * from './linkedUrl';
+export * from './logoImages';
+export * from './logoImagesCircle';
+export * from './logoImagesHorizontal';
+export * from './logoImagesKorean';
export * from './logoUsageRule';
-export * from './planOutput';
-export * from './planOutputRepurposingProposals';
-export * from './reportOutput';
-export * from './reportOutputFacebook';
-export * from './reportOutputGangnamUnni';
-export * from './reportOutputInstagram';
-export * from './reportOutputNaverBlog';
-export * from './reportOutputYoutube';
+export * from './marketingReportResponse';
+export * from './marketingReportResponseClinicName';
+export * from './marketingReportResponseClinicNameEn';
+export * from './marketingReportResponseScreenshots';
+export * from './newChannelProposal';
+export * from './otherChannel';
+export * from './otherChannelUrl';
+export * from './planApiResponse';
+export * from './planApiResponseClinicName';
+export * from './planApiResponseClinicNameEn';
+export * from './planApiResponseRepurposingProposals';
+export * from './platformStrategy';
+export * from './priceRange';
+export * from './registryData';
+export * from './registryDataBranches';
+export * from './registryDataBrandGroup';
+export * from './registryDataDistrict';
+export * from './registryDataGangnamUnniUrl';
+export * from './registryDataGoogleMapsUrl';
+export * from './registryDataNaverPlaceUrl';
+export * from './registryDataWebsiteEn';
export * from './repurposingOutput';
export * from './repurposingProposalItem';
export * from './repurposingProposalItemEstimatedEffort';
export * from './repurposingProposalItemPriority';
+export * from './roadmapMonth';
+export * from './roadmapTask';
export * from './runSummary';
export * from './runSummaryCompletedAt';
export * from './runSummaryOverallScore';
+export * from './screenshotAnnotation';
+export * from './screenshotAnnotationColor';
+export * from './screenshotAnnotationHeight';
+export * from './screenshotAnnotationLabel';
+export * from './screenshotAnnotationWidth';
+export * from './screenshotEvidence';
+export * from './screenshotEvidenceAnnotations';
+export * from './screenshotEvidenceSourceUrl';
+export * from './severity';
+export * from './snsLink';
+export * from './strategyDetail';
export * from './toneOfVoice';
+export * from './topVideo';
+export * from './topVideoDuration';
+export * from './trackingPixel';
+export * from './trackingPixelDetails';
+export * from './transformationProposal';
export * from './validationError';
export * from './validationErrorCtx';
export * from './validationErrorLocItem';
+export * from './videoType';
+export * from './websiteAudit';
+export * from './websiteAuditSnsLinksDetail';
+export * from './weeklyViewGrowth';
export * from './workflowStep';
+export * from './youTubeAudit';
export * from './youTubeRepurposeItem';
export * from './youTubeRepurposeItemType';
\ No newline at end of file
diff --git a/src/shared/api/model/instagramAccount.ts b/src/shared/api/model/instagramAccount.ts
new file mode 100644
index 0000000..44cf3c4
--- /dev/null
+++ b/src/shared/api/model/instagramAccount.ts
@@ -0,0 +1,23 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { Language } from './language';
+
+export interface InstagramAccount {
+ handle: string;
+ language: Language;
+ label: string;
+ posts: number;
+ followers: number;
+ following: number;
+ category: string;
+ profileLink: string;
+ highlights: string[];
+ reelsCount: number;
+ contentFormat: string;
+ profilePhoto: string;
+ bio: string;
+}
diff --git a/src/shared/api/model/instagramAudit.ts b/src/shared/api/model/instagramAudit.ts
new file mode 100644
index 0000000..863d71e
--- /dev/null
+++ b/src/shared/api/model/instagramAudit.ts
@@ -0,0 +1,13 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { InstagramAccount } from './instagramAccount';
+import type { DiagnosisItem } from './diagnosisItem';
+
+export interface InstagramAudit {
+ accounts: InstagramAccount[];
+ diagnosis: DiagnosisItem[];
+}
diff --git a/src/shared/api/model/kPIMetric.ts b/src/shared/api/model/kPIMetric.ts
new file mode 100644
index 0000000..41bc7d1
--- /dev/null
+++ b/src/shared/api/model/kPIMetric.ts
@@ -0,0 +1,13 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export interface KPIMetric {
+ metric: string;
+ current: string;
+ target3Month: string;
+ target12Month: string;
+}
diff --git a/src/shared/api/model/language.ts b/src/shared/api/model/language.ts
new file mode 100644
index 0000000..7cd3854
--- /dev/null
+++ b/src/shared/api/model/language.ts
@@ -0,0 +1,15 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type Language = typeof Language[keyof typeof Language];
+
+
+// eslint-disable-next-line @typescript-eslint/no-redeclare
+export const Language = {
+ KR: 'KR',
+ EN: 'EN',
+} as const;
diff --git a/src/shared/api/model/leadDoctor.ts b/src/shared/api/model/leadDoctor.ts
new file mode 100644
index 0000000..d770b42
--- /dev/null
+++ b/src/shared/api/model/leadDoctor.ts
@@ -0,0 +1,13 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export interface LeadDoctor {
+ name: string;
+ credentials: string;
+ rating: number;
+ reviewCount: number;
+}
diff --git a/src/shared/api/model/linkedUrl.ts b/src/shared/api/model/linkedUrl.ts
new file mode 100644
index 0000000..3e4f841
--- /dev/null
+++ b/src/shared/api/model/linkedUrl.ts
@@ -0,0 +1,11 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export interface LinkedUrl {
+ label: string;
+ url: string;
+}
diff --git a/src/shared/api/model/logoImages.ts b/src/shared/api/model/logoImages.ts
new file mode 100644
index 0000000..980ce7b
--- /dev/null
+++ b/src/shared/api/model/logoImages.ts
@@ -0,0 +1,15 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { LogoImagesCircle } from './logoImagesCircle';
+import type { LogoImagesHorizontal } from './logoImagesHorizontal';
+import type { LogoImagesKorean } from './logoImagesKorean';
+
+export interface LogoImages {
+ circle?: LogoImagesCircle;
+ horizontal?: LogoImagesHorizontal;
+ korean?: LogoImagesKorean;
+}
diff --git a/src/shared/api/model/logoImagesCircle.ts b/src/shared/api/model/logoImagesCircle.ts
new file mode 100644
index 0000000..7e0979a
--- /dev/null
+++ b/src/shared/api/model/logoImagesCircle.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type LogoImagesCircle = string | null;
diff --git a/src/shared/api/model/logoImagesHorizontal.ts b/src/shared/api/model/logoImagesHorizontal.ts
new file mode 100644
index 0000000..96a064a
--- /dev/null
+++ b/src/shared/api/model/logoImagesHorizontal.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type LogoImagesHorizontal = string | null;
diff --git a/src/shared/api/model/logoImagesKorean.ts b/src/shared/api/model/logoImagesKorean.ts
new file mode 100644
index 0000000..5231f79
--- /dev/null
+++ b/src/shared/api/model/logoImagesKorean.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type LogoImagesKorean = string | null;
diff --git a/src/shared/api/model/marketingReportResponse.ts b/src/shared/api/model/marketingReportResponse.ts
new file mode 100644
index 0000000..cdc4f27
--- /dev/null
+++ b/src/shared/api/model/marketingReportResponse.ts
@@ -0,0 +1,41 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { MarketingReportResponseClinicName } from './marketingReportResponseClinicName';
+import type { MarketingReportResponseClinicNameEn } from './marketingReportResponseClinicNameEn';
+import type { ClinicSnapshot } from './clinicSnapshot';
+import type { ChannelScore } from './channelScore';
+import type { YouTubeAudit } from './youTubeAudit';
+import type { InstagramAudit } from './instagramAudit';
+import type { FacebookAudit } from './facebookAudit';
+import type { OtherChannel } from './otherChannel';
+import type { WebsiteAudit } from './websiteAudit';
+import type { DiagnosisItem } from './diagnosisItem';
+import type { TransformationProposal } from './transformationProposal';
+import type { RoadmapMonth } from './roadmapMonth';
+import type { KPIMetric } from './kPIMetric';
+import type { MarketingReportResponseScreenshots } from './marketingReportResponseScreenshots';
+
+export interface MarketingReportResponse {
+ id: string;
+ clinicName?: MarketingReportResponseClinicName;
+ clinicNameEn?: MarketingReportResponseClinicNameEn;
+ createdAt: string;
+ targetUrl: string;
+ overallScore: number;
+ clinicSnapshot: ClinicSnapshot;
+ channelScores: ChannelScore[];
+ youtubeAudit: YouTubeAudit;
+ instagramAudit: InstagramAudit;
+ facebookAudit: FacebookAudit;
+ otherChannels: OtherChannel[];
+ websiteAudit: WebsiteAudit;
+ problemDiagnosis: DiagnosisItem[];
+ transformation: TransformationProposal;
+ roadmap: RoadmapMonth[];
+ kpiDashboard: KPIMetric[];
+ screenshots?: MarketingReportResponseScreenshots;
+}
diff --git a/src/shared/api/model/marketingReportResponseClinicName.ts b/src/shared/api/model/marketingReportResponseClinicName.ts
new file mode 100644
index 0000000..f93426d
--- /dev/null
+++ b/src/shared/api/model/marketingReportResponseClinicName.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type MarketingReportResponseClinicName = string | null;
diff --git a/src/shared/api/model/marketingReportResponseClinicNameEn.ts b/src/shared/api/model/marketingReportResponseClinicNameEn.ts
new file mode 100644
index 0000000..685e2e1
--- /dev/null
+++ b/src/shared/api/model/marketingReportResponseClinicNameEn.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type MarketingReportResponseClinicNameEn = string | null;
diff --git a/src/shared/api/model/marketingReportResponseScreenshots.ts b/src/shared/api/model/marketingReportResponseScreenshots.ts
new file mode 100644
index 0000000..5a985c2
--- /dev/null
+++ b/src/shared/api/model/marketingReportResponseScreenshots.ts
@@ -0,0 +1,9 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { ScreenshotEvidence } from './screenshotEvidence';
+
+export type MarketingReportResponseScreenshots = ScreenshotEvidence[] | null;
diff --git a/src/shared/api/model/newChannelProposal.ts b/src/shared/api/model/newChannelProposal.ts
new file mode 100644
index 0000000..92e5402
--- /dev/null
+++ b/src/shared/api/model/newChannelProposal.ts
@@ -0,0 +1,12 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export interface NewChannelProposal {
+ channel: string;
+ priority: string;
+ rationale: string;
+}
diff --git a/src/shared/api/model/otherChannel.ts b/src/shared/api/model/otherChannel.ts
new file mode 100644
index 0000000..9bd6b4d
--- /dev/null
+++ b/src/shared/api/model/otherChannel.ts
@@ -0,0 +1,15 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { ChannelStatus } from './channelStatus';
+import type { OtherChannelUrl } from './otherChannelUrl';
+
+export interface OtherChannel {
+ name: string;
+ status: ChannelStatus;
+ details: string;
+ url?: OtherChannelUrl;
+}
diff --git a/src/shared/api/model/otherChannelUrl.ts b/src/shared/api/model/otherChannelUrl.ts
new file mode 100644
index 0000000..21ec10e
--- /dev/null
+++ b/src/shared/api/model/otherChannelUrl.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type OtherChannelUrl = string | null;
diff --git a/src/shared/api/model/planOutput.ts b/src/shared/api/model/planApiResponse.ts
similarity index 54%
rename from src/shared/api/model/planOutput.ts
rename to src/shared/api/model/planApiResponse.ts
index 449c771..7b3c40a 100644
--- a/src/shared/api/model/planOutput.ts
+++ b/src/shared/api/model/planApiResponse.ts
@@ -4,18 +4,25 @@
* FastAPI
* OpenAPI spec version: 0.1.0
*/
+import type { PlanApiResponseClinicName } from './planApiResponseClinicName';
+import type { PlanApiResponseClinicNameEn } from './planApiResponseClinicNameEn';
import type { BrandGuide } from './brandGuide';
import type { ChannelStrategyCard } from './channelStrategyCard';
import type { ContentStrategyData } from './contentStrategyData';
import type { CalendarData } from './calendarData';
import type { AssetCollectionData } from './assetCollectionData';
-import type { PlanOutputRepurposingProposals } from './planOutputRepurposingProposals';
+import type { PlanApiResponseRepurposingProposals } from './planApiResponseRepurposingProposals';
-export interface PlanOutput {
+export interface PlanApiResponse {
+ id: string;
+ clinicName?: PlanApiResponseClinicName;
+ clinicNameEn?: PlanApiResponseClinicNameEn;
+ createdAt: string;
+ targetUrl: string;
brandGuide: BrandGuide;
channelStrategies: ChannelStrategyCard[];
contentStrategy: ContentStrategyData;
calendar: CalendarData;
assetCollection: AssetCollectionData;
- repurposingProposals?: PlanOutputRepurposingProposals;
+ repurposingProposals?: PlanApiResponseRepurposingProposals;
}
diff --git a/src/shared/api/model/planApiResponseClinicName.ts b/src/shared/api/model/planApiResponseClinicName.ts
new file mode 100644
index 0000000..1e5e295
--- /dev/null
+++ b/src/shared/api/model/planApiResponseClinicName.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type PlanApiResponseClinicName = string | null;
diff --git a/src/shared/api/model/planApiResponseClinicNameEn.ts b/src/shared/api/model/planApiResponseClinicNameEn.ts
new file mode 100644
index 0000000..e772c88
--- /dev/null
+++ b/src/shared/api/model/planApiResponseClinicNameEn.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type PlanApiResponseClinicNameEn = string | null;
diff --git a/src/shared/api/model/planOutputRepurposingProposals.ts b/src/shared/api/model/planApiResponseRepurposingProposals.ts
similarity index 68%
rename from src/shared/api/model/planOutputRepurposingProposals.ts
rename to src/shared/api/model/planApiResponseRepurposingProposals.ts
index 53e6ac8..038f3ca 100644
--- a/src/shared/api/model/planOutputRepurposingProposals.ts
+++ b/src/shared/api/model/planApiResponseRepurposingProposals.ts
@@ -6,4 +6,4 @@
*/
import type { RepurposingProposalItem } from './repurposingProposalItem';
-export type PlanOutputRepurposingProposals = RepurposingProposalItem[] | null;
+export type PlanApiResponseRepurposingProposals = RepurposingProposalItem[] | null;
diff --git a/src/shared/api/model/platformStrategy.ts b/src/shared/api/model/platformStrategy.ts
new file mode 100644
index 0000000..f0dfc09
--- /dev/null
+++ b/src/shared/api/model/platformStrategy.ts
@@ -0,0 +1,15 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { StrategyDetail } from './strategyDetail';
+
+export interface PlatformStrategy {
+ platform: string;
+ icon: string;
+ currentMetric: string;
+ targetMetric: string;
+ strategies: StrategyDetail[];
+}
diff --git a/src/shared/api/model/priceRange.ts b/src/shared/api/model/priceRange.ts
new file mode 100644
index 0000000..28100c0
--- /dev/null
+++ b/src/shared/api/model/priceRange.ts
@@ -0,0 +1,12 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export interface PriceRange {
+ min: string;
+ max: string;
+ currency: string;
+}
diff --git a/src/shared/api/model/registryData.ts b/src/shared/api/model/registryData.ts
new file mode 100644
index 0000000..87da8be
--- /dev/null
+++ b/src/shared/api/model/registryData.ts
@@ -0,0 +1,23 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { RegistryDataDistrict } from './registryDataDistrict';
+import type { RegistryDataBranches } from './registryDataBranches';
+import type { RegistryDataBrandGroup } from './registryDataBrandGroup';
+import type { RegistryDataWebsiteEn } from './registryDataWebsiteEn';
+import type { RegistryDataNaverPlaceUrl } from './registryDataNaverPlaceUrl';
+import type { RegistryDataGangnamUnniUrl } from './registryDataGangnamUnniUrl';
+import type { RegistryDataGoogleMapsUrl } from './registryDataGoogleMapsUrl';
+
+export interface RegistryData {
+ district?: RegistryDataDistrict;
+ branches?: RegistryDataBranches;
+ brandGroup?: RegistryDataBrandGroup;
+ websiteEn?: RegistryDataWebsiteEn;
+ naverPlaceUrl?: RegistryDataNaverPlaceUrl;
+ gangnamUnniUrl?: RegistryDataGangnamUnniUrl;
+ googleMapsUrl?: RegistryDataGoogleMapsUrl;
+}
diff --git a/src/shared/api/model/registryDataBranches.ts b/src/shared/api/model/registryDataBranches.ts
new file mode 100644
index 0000000..f8552bf
--- /dev/null
+++ b/src/shared/api/model/registryDataBranches.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type RegistryDataBranches = string | null;
diff --git a/src/shared/api/model/registryDataBrandGroup.ts b/src/shared/api/model/registryDataBrandGroup.ts
new file mode 100644
index 0000000..1716ebf
--- /dev/null
+++ b/src/shared/api/model/registryDataBrandGroup.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type RegistryDataBrandGroup = string | null;
diff --git a/src/shared/api/model/registryDataDistrict.ts b/src/shared/api/model/registryDataDistrict.ts
new file mode 100644
index 0000000..6f387d7
--- /dev/null
+++ b/src/shared/api/model/registryDataDistrict.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type RegistryDataDistrict = string | null;
diff --git a/src/shared/api/model/registryDataGangnamUnniUrl.ts b/src/shared/api/model/registryDataGangnamUnniUrl.ts
new file mode 100644
index 0000000..64aa11d
--- /dev/null
+++ b/src/shared/api/model/registryDataGangnamUnniUrl.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type RegistryDataGangnamUnniUrl = string | null;
diff --git a/src/shared/api/model/registryDataGoogleMapsUrl.ts b/src/shared/api/model/registryDataGoogleMapsUrl.ts
new file mode 100644
index 0000000..11eac8e
--- /dev/null
+++ b/src/shared/api/model/registryDataGoogleMapsUrl.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type RegistryDataGoogleMapsUrl = string | null;
diff --git a/src/shared/api/model/registryDataNaverPlaceUrl.ts b/src/shared/api/model/registryDataNaverPlaceUrl.ts
new file mode 100644
index 0000000..5514f74
--- /dev/null
+++ b/src/shared/api/model/registryDataNaverPlaceUrl.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type RegistryDataNaverPlaceUrl = string | null;
diff --git a/src/shared/api/model/registryDataWebsiteEn.ts b/src/shared/api/model/registryDataWebsiteEn.ts
new file mode 100644
index 0000000..5aaa638
--- /dev/null
+++ b/src/shared/api/model/registryDataWebsiteEn.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type RegistryDataWebsiteEn = string | null;
diff --git a/src/shared/api/model/reportOutput.ts b/src/shared/api/model/reportOutput.ts
deleted file mode 100644
index 6a05a44..0000000
--- a/src/shared/api/model/reportOutput.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Generated by orval v7.21.0 🍺
- * Do not edit manually.
- * FastAPI
- * OpenAPI spec version: 0.1.0
- */
-import type { ReportOutputInstagram } from './reportOutputInstagram';
-import type { ReportOutputFacebook } from './reportOutputFacebook';
-import type { ReportOutputNaverBlog } from './reportOutputNaverBlog';
-import type { ReportOutputYoutube } from './reportOutputYoutube';
-import type { ReportOutputGangnamUnni } from './reportOutputGangnamUnni';
-import type { ConversionStrategy } from './conversionStrategy';
-
-export interface ReportOutput {
- overall_score: number;
- instagram?: ReportOutputInstagram;
- facebook?: ReportOutputFacebook;
- naver_blog?: ReportOutputNaverBlog;
- youtube?: ReportOutputYoutube;
- gangnam_unni?: ReportOutputGangnamUnni;
- conversion_strategy: ConversionStrategy;
- roadmap: string[];
- kpis: string[];
-}
diff --git a/src/shared/api/model/reportOutputGangnamUnni.ts b/src/shared/api/model/reportOutputGangnamUnni.ts
deleted file mode 100644
index 1105de4..0000000
--- a/src/shared/api/model/reportOutputGangnamUnni.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * Generated by orval v7.21.0 🍺
- * Do not edit manually.
- * FastAPI
- * OpenAPI spec version: 0.1.0
- */
-import type { ChannelScore } from './channelScore';
-
-export type ReportOutputGangnamUnni = ChannelScore | null;
diff --git a/src/shared/api/model/reportOutputInstagram.ts b/src/shared/api/model/reportOutputInstagram.ts
deleted file mode 100644
index fe0295b..0000000
--- a/src/shared/api/model/reportOutputInstagram.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * Generated by orval v7.21.0 🍺
- * Do not edit manually.
- * FastAPI
- * OpenAPI spec version: 0.1.0
- */
-import type { ChannelScore } from './channelScore';
-
-export type ReportOutputInstagram = ChannelScore | null;
diff --git a/src/shared/api/model/reportOutputNaverBlog.ts b/src/shared/api/model/reportOutputNaverBlog.ts
deleted file mode 100644
index 85e8429..0000000
--- a/src/shared/api/model/reportOutputNaverBlog.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * Generated by orval v7.21.0 🍺
- * Do not edit manually.
- * FastAPI
- * OpenAPI spec version: 0.1.0
- */
-import type { ChannelScore } from './channelScore';
-
-export type ReportOutputNaverBlog = ChannelScore | null;
diff --git a/src/shared/api/model/roadmapMonth.ts b/src/shared/api/model/roadmapMonth.ts
new file mode 100644
index 0000000..06f35b8
--- /dev/null
+++ b/src/shared/api/model/roadmapMonth.ts
@@ -0,0 +1,14 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { RoadmapTask } from './roadmapTask';
+
+export interface RoadmapMonth {
+ month: number;
+ title: string;
+ subtitle: string;
+ tasks: RoadmapTask[];
+}
diff --git a/src/shared/api/model/roadmapTask.ts b/src/shared/api/model/roadmapTask.ts
new file mode 100644
index 0000000..a44519c
--- /dev/null
+++ b/src/shared/api/model/roadmapTask.ts
@@ -0,0 +1,11 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export interface RoadmapTask {
+ task: string;
+ completed: boolean;
+}
diff --git a/src/shared/api/model/screenshotAnnotation.ts b/src/shared/api/model/screenshotAnnotation.ts
new file mode 100644
index 0000000..7294527
--- /dev/null
+++ b/src/shared/api/model/screenshotAnnotation.ts
@@ -0,0 +1,21 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { AnnotationType } from './annotationType';
+import type { ScreenshotAnnotationWidth } from './screenshotAnnotationWidth';
+import type { ScreenshotAnnotationHeight } from './screenshotAnnotationHeight';
+import type { ScreenshotAnnotationLabel } from './screenshotAnnotationLabel';
+import type { ScreenshotAnnotationColor } from './screenshotAnnotationColor';
+
+export interface ScreenshotAnnotation {
+ type: AnnotationType;
+ x: number;
+ y: number;
+ width?: ScreenshotAnnotationWidth;
+ height?: ScreenshotAnnotationHeight;
+ label?: ScreenshotAnnotationLabel;
+ color?: ScreenshotAnnotationColor;
+}
diff --git a/src/shared/api/model/screenshotAnnotationColor.ts b/src/shared/api/model/screenshotAnnotationColor.ts
new file mode 100644
index 0000000..3fdb65c
--- /dev/null
+++ b/src/shared/api/model/screenshotAnnotationColor.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type ScreenshotAnnotationColor = string | null;
diff --git a/src/shared/api/model/screenshotAnnotationHeight.ts b/src/shared/api/model/screenshotAnnotationHeight.ts
new file mode 100644
index 0000000..43b8fbc
--- /dev/null
+++ b/src/shared/api/model/screenshotAnnotationHeight.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type ScreenshotAnnotationHeight = number | null;
diff --git a/src/shared/api/model/screenshotAnnotationLabel.ts b/src/shared/api/model/screenshotAnnotationLabel.ts
new file mode 100644
index 0000000..ca03b7c
--- /dev/null
+++ b/src/shared/api/model/screenshotAnnotationLabel.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type ScreenshotAnnotationLabel = string | null;
diff --git a/src/shared/api/model/screenshotAnnotationWidth.ts b/src/shared/api/model/screenshotAnnotationWidth.ts
new file mode 100644
index 0000000..4ab4d0e
--- /dev/null
+++ b/src/shared/api/model/screenshotAnnotationWidth.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type ScreenshotAnnotationWidth = number | null;
diff --git a/src/shared/api/model/screenshotEvidence.ts b/src/shared/api/model/screenshotEvidence.ts
new file mode 100644
index 0000000..b147eae
--- /dev/null
+++ b/src/shared/api/model/screenshotEvidence.ts
@@ -0,0 +1,18 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { ScreenshotEvidenceSourceUrl } from './screenshotEvidenceSourceUrl';
+import type { ScreenshotEvidenceAnnotations } from './screenshotEvidenceAnnotations';
+
+export interface ScreenshotEvidence {
+ id: string;
+ url: string;
+ channel: string;
+ capturedAt: string;
+ caption: string;
+ sourceUrl?: ScreenshotEvidenceSourceUrl;
+ annotations?: ScreenshotEvidenceAnnotations;
+}
diff --git a/src/shared/api/model/screenshotEvidenceAnnotations.ts b/src/shared/api/model/screenshotEvidenceAnnotations.ts
new file mode 100644
index 0000000..9ea5627
--- /dev/null
+++ b/src/shared/api/model/screenshotEvidenceAnnotations.ts
@@ -0,0 +1,9 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { ScreenshotAnnotation } from './screenshotAnnotation';
+
+export type ScreenshotEvidenceAnnotations = ScreenshotAnnotation[] | null;
diff --git a/src/shared/api/model/screenshotEvidenceSourceUrl.ts b/src/shared/api/model/screenshotEvidenceSourceUrl.ts
new file mode 100644
index 0000000..ecda4aa
--- /dev/null
+++ b/src/shared/api/model/screenshotEvidenceSourceUrl.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type ScreenshotEvidenceSourceUrl = string | null;
diff --git a/src/shared/api/model/severity.ts b/src/shared/api/model/severity.ts
new file mode 100644
index 0000000..1f0dcbb
--- /dev/null
+++ b/src/shared/api/model/severity.ts
@@ -0,0 +1,18 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type Severity = typeof Severity[keyof typeof Severity];
+
+
+// eslint-disable-next-line @typescript-eslint/no-redeclare
+export const Severity = {
+ critical: 'critical',
+ warning: 'warning',
+ good: 'good',
+ excellent: 'excellent',
+ unknown: 'unknown',
+} as const;
diff --git a/src/shared/api/model/snsLink.ts b/src/shared/api/model/snsLink.ts
new file mode 100644
index 0000000..fe36e14
--- /dev/null
+++ b/src/shared/api/model/snsLink.ts
@@ -0,0 +1,12 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export interface SnsLink {
+ platform: string;
+ url: string;
+ location: string;
+}
diff --git a/src/shared/api/model/strategyDetail.ts b/src/shared/api/model/strategyDetail.ts
new file mode 100644
index 0000000..a2bb53b
--- /dev/null
+++ b/src/shared/api/model/strategyDetail.ts
@@ -0,0 +1,11 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export interface StrategyDetail {
+ strategy: string;
+ detail: string;
+}
diff --git a/src/shared/api/model/topVideo.ts b/src/shared/api/model/topVideo.ts
new file mode 100644
index 0000000..d8f02d5
--- /dev/null
+++ b/src/shared/api/model/topVideo.ts
@@ -0,0 +1,16 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { VideoType } from './videoType';
+import type { TopVideoDuration } from './topVideoDuration';
+
+export interface TopVideo {
+ title: string;
+ views: number;
+ uploadedAgo: string;
+ type: VideoType;
+ duration?: TopVideoDuration;
+}
diff --git a/src/shared/api/model/topVideoDuration.ts b/src/shared/api/model/topVideoDuration.ts
new file mode 100644
index 0000000..d8a630b
--- /dev/null
+++ b/src/shared/api/model/topVideoDuration.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type TopVideoDuration = string | null;
diff --git a/src/shared/api/model/trackingPixel.ts b/src/shared/api/model/trackingPixel.ts
new file mode 100644
index 0000000..3468176
--- /dev/null
+++ b/src/shared/api/model/trackingPixel.ts
@@ -0,0 +1,13 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { TrackingPixelDetails } from './trackingPixelDetails';
+
+export interface TrackingPixel {
+ name: string;
+ installed: boolean;
+ details?: TrackingPixelDetails;
+}
diff --git a/src/shared/api/model/trackingPixelDetails.ts b/src/shared/api/model/trackingPixelDetails.ts
new file mode 100644
index 0000000..fca8a6a
--- /dev/null
+++ b/src/shared/api/model/trackingPixelDetails.ts
@@ -0,0 +1,8 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type TrackingPixelDetails = string | null;
diff --git a/src/shared/api/model/transformationProposal.ts b/src/shared/api/model/transformationProposal.ts
new file mode 100644
index 0000000..b5a0729
--- /dev/null
+++ b/src/shared/api/model/transformationProposal.ts
@@ -0,0 +1,17 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { AsIsToBeItem } from './asIsToBeItem';
+import type { PlatformStrategy } from './platformStrategy';
+import type { NewChannelProposal } from './newChannelProposal';
+
+export interface TransformationProposal {
+ brandIdentity: AsIsToBeItem[];
+ contentStrategy: AsIsToBeItem[];
+ platformStrategies: PlatformStrategy[];
+ websiteImprovements: AsIsToBeItem[];
+ newChannelProposals: NewChannelProposal[];
+}
diff --git a/src/shared/api/model/videoType.ts b/src/shared/api/model/videoType.ts
new file mode 100644
index 0000000..36be8b0
--- /dev/null
+++ b/src/shared/api/model/videoType.ts
@@ -0,0 +1,15 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export type VideoType = typeof VideoType[keyof typeof VideoType];
+
+
+// eslint-disable-next-line @typescript-eslint/no-redeclare
+export const VideoType = {
+ Short: 'Short',
+ Long: 'Long',
+} as const;
diff --git a/src/shared/api/model/websiteAudit.ts b/src/shared/api/model/websiteAudit.ts
new file mode 100644
index 0000000..860c7da
--- /dev/null
+++ b/src/shared/api/model/websiteAudit.ts
@@ -0,0 +1,18 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { AdditionalDomain } from './additionalDomain';
+import type { WebsiteAuditSnsLinksDetail } from './websiteAuditSnsLinksDetail';
+import type { TrackingPixel } from './trackingPixel';
+
+export interface WebsiteAudit {
+ primaryDomain: string;
+ additionalDomains: AdditionalDomain[];
+ snsLinksOnSite: boolean;
+ snsLinksDetail?: WebsiteAuditSnsLinksDetail;
+ trackingPixels: TrackingPixel[];
+ mainCta: string;
+}
diff --git a/src/shared/api/model/websiteAuditSnsLinksDetail.ts b/src/shared/api/model/websiteAuditSnsLinksDetail.ts
new file mode 100644
index 0000000..d1a0e56
--- /dev/null
+++ b/src/shared/api/model/websiteAuditSnsLinksDetail.ts
@@ -0,0 +1,9 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { SnsLink } from './snsLink';
+
+export type WebsiteAuditSnsLinksDetail = SnsLink[] | null;
diff --git a/src/shared/api/model/weeklyViewGrowth.ts b/src/shared/api/model/weeklyViewGrowth.ts
new file mode 100644
index 0000000..888ed3a
--- /dev/null
+++ b/src/shared/api/model/weeklyViewGrowth.ts
@@ -0,0 +1,11 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+
+export interface WeeklyViewGrowth {
+ absolute: number;
+ percentage: number;
+}
diff --git a/src/shared/api/model/youTubeAudit.ts b/src/shared/api/model/youTubeAudit.ts
new file mode 100644
index 0000000..6633095
--- /dev/null
+++ b/src/shared/api/model/youTubeAudit.ts
@@ -0,0 +1,30 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * FastAPI
+ * OpenAPI spec version: 0.1.0
+ */
+import type { WeeklyViewGrowth } from './weeklyViewGrowth';
+import type { EstimatedRevenue } from './estimatedRevenue';
+import type { LinkedUrl } from './linkedUrl';
+import type { TopVideo } from './topVideo';
+import type { DiagnosisItem } from './diagnosisItem';
+
+export interface YouTubeAudit {
+ channelName: string;
+ handle: string;
+ subscribers: number;
+ totalVideos: number;
+ totalViews: number;
+ weeklyViewGrowth: WeeklyViewGrowth;
+ estimatedMonthlyRevenue: EstimatedRevenue;
+ avgVideoLength: string;
+ uploadFrequency: string;
+ channelCreatedDate: string;
+ subscriberRank: string;
+ channelDescription: string;
+ linkedUrls: LinkedUrl[];
+ playlists: string[];
+ topVideos: TopVideo[];
+ diagnosis: DiagnosisItem[];
+}