src/
βββ api/
β βββ dto/ # [μλ² κ·κ²©] Request/Response μΈν°νμ΄μ€ μ μν¨
β β βββ auth.dto.ts # μΈμ¦ κ΄λ ¨ DTO
β β βββ presentations.dto.ts # νλ‘μ νΈ κ΄λ ¨ DTO
β β βββ video.dto.ts # λΉλμ€ μ
λ‘λ/μ‘°ν DTO
β β
β βββ endpoints/ # [ν΅μ λ‘μ§] μ€μ API νΈμΆ λ° λ°μ΄ν° λ³ν(toModel)ν¨
β βββ auth.ts
β βββ presentations.ts # Repository μν μνν¨
β βββ videos.ts
β
βββ hooks/ # [λΉμ¦λμ€ λ‘μ§] UIμμ νΈμΆν UseCase μ±κ²©μ ν
μ
β βββ useAuth.ts
β βββ usePresentation.ts # λ°μ΄ν° νΈμΆ, λ‘λ©/μλ¬ μν κ΄λ¦¬ν¨
β βββ useVideo.ts
β
βββ types/ # [λλ©μΈ λͺ¨λΈ] μ± λ΄λΆμμ 곡ν΅μΌλ‘ μ°λ μμ λ°μ΄ν° νμ
μ
βββ presentation.ts # camelCaseλ‘ μ μ λ νλ‘μ νΈ λͺ¨λΈμ
- DTO (Data Transfer Object): μλ² ν΅μ μ© λ°μ΄ν° κ·κ²©μ. μλ² μ€ν(JSON νλλͺ λ±)μ κ·Έλλ‘ λ°μν¨.
- Model (Domain Model): μ± λ΄λΆμ© μ μ λ°μ΄ν°μ. UIμμ μ°κΈ° μ’κ² νλλͺ
μ λ°κΎΈκ±°λ(
camelCase) κ°κ³΅ν ννμ. - Service (Endpoints): μ€μ ν΅μ μ μννλ λ‘μ§μ. DTOλ₯Ό λ°μ μλ²μ μκ³ , λ°μ λ°μ΄ν°λ₯Ό Modelλ‘ λ³ν(
toModel)ν΄μ€.
μλ²μ λ³κ²½μ΄ UIμ μ§μ μ μΈ μν₯μ μ£Όμ§ μλλ‘ DTOμ Model λΆλ¦¬
- DTO (Data Transfer Object): μλ² μλ΅ κ·κ²©κ³Ό 1:1 λ§€μΉ (
snake_caseλ± μλ² μ€ν μ μ§). - Model (Domain Model): μ± λ΄λΆμμ μ¬μ©νλ μ μ λ λ°μ΄ν° (
camelCaseλ‘ λ³ν λ° UI μΉνμ ꡬ쑰).
- μλ² μλ΅ κ·κ²©κ³Ό 1:1 λ§€μΉν¨.
- μλ² νλλͺ
μ΄
snake_caseλ©΄ κ·Έλλ‘ μ μ§ν΄μ νΌμ μ λ°©μ§ν¨.
/** λλ³Έ 볡μ μμ² DTO */
export interface RestoreScriptRequestDto {
version: number;
}
/** λλ³Έ 볡μ μλ΅ DTO */
export interface RestoreScriptResponseDto {
script_id: string; // μλ² κ³ μ μ€ν
content: string;
updated_at: string;
}- μ€μ
fetchλaxiosνΈμΆμ λ΄λΉν¨. - DTOλ₯Ό λ°μμ UIμμ μ°κΈ° νΈν Modelλ‘ λ³νν΄μ 리ν΄ν¨.
import { RestoreScriptRequestDto, RestoreScriptResponseDto } from '../dto/scripts.dto';
export const scriptService = {
restoreScript: async (projectId: string, dto: RestoreScriptRequestDto) => {
const response = await fetch(`/projects/${projectId}/scripts/restore`, {
method: 'POST',
body: JSON.stringify(dto),
});
const data: RestoreScriptResponseDto = await response.json();
// Modelλ‘ λ³νν΄μ λ°ν (UI 보νΈ)
return {
id: data.script_id,
content: data.content,
updatedAt: data.updated_at,
};
}
};UseCaseμ μν μ μννλ©°, μ»΄ν¬λνΈμμ μ¬μ©ν μνμ ν¨μλ₯Ό μ 곡ν©λλ€.
export const useRestoreScript = (projectId: string) => {
const [isLoading, setIsLoading] = useState(false);
const execute = async (version: number) => {
setIsLoading(true);
try {
return await scriptService.restoreScript(projectId, { version });
} finally {
setIsLoading(false);
}
};
return { execute, isLoading };
};- μν : λΉμ¦λμ€ λ‘μ§ λ° μν κ΄λ¦¬ λ΄λΉν¨.
- νΉμ§:
isLoading,isErrorκ°μ ν΅μ μνλ₯Ό μ»΄ν¬λνΈμ μ λ¬νκ³ , νμ μ λ°μ΄ν°λ₯Ό Modelλ‘ μ΅μ’ κ°κ³΅ν¨. - μ₯μ : UI μ»΄ν¬λνΈλ ν μ΄ μ£Όλ λ°μ΄ν°λ ν¨μλ§ μ°λ©΄ λ¨.