프로젝트·파일 데이터 모델
프로젝트와 파일·폴더 엔티티를 정의하고 소유 관계와 계층 구조를 구성합니다.
프로젝트 및 파일 관리 API 구현
앞 문서의 User와 Project는 owner와 projects로 연결됩니다. Project의 files와 folders는 각각 File과 Folder의 project 관계에 대응합니다. 두 자식 관계에는 Project 삭제 시 자식도 삭제하는 CASCADE가 설정되어 있고, path는 부모 관계가 아닌 문자열입니다.
- User — 앞 문서의 외부참조
id- Project
id,ownerId- File
id,projectId, 문자열path예:/src/main.ts- Folder
id,projectId, 문자열path예:/src
- User 1 : Project N —
User.projects와Project.owner - Project 1 : File N —
Project.files와File.project - Project 1 : Folder N —
Project.folders와Folder.project
1:N은 일대다 관계를 나타냅니다. 필드는 관계 식별에 필요한 부분만 표시했습니다.
- Project 삭제 → 해당 File·Folder 삭제.
File.project와Folder.project에onDelete: 'CASCADE'가 설정되어 있습니다. - path는 경로 문자열입니다. 이 엔티티에는 폴더의 부모 FK나 File–Folder 관계가 없습니다. 폴더 경로 삭제는 별도 서비스 로직입니다.
이제 사용자 인증이 완료된 후 접근할 수 있는 프로젝트 및 파일 관리 API를 구현합니다.
Project Entity
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, CreateDateColumn, UpdateDateColumn } from 'typeorm';
import { User } from '../../auth/entities/user.entity'; // User 엔티티 임포트
import { File } from '../../file/entities/file.entity'; // File 엔티티 임포트 (미리 정의했다고 가정)
import { Folder } from '../../folder/entities/folder.entity'; // Folder 엔티티 임포트 (미리 정의했다고 가정)
@Entity()
export class Project {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ nullable: false })
name: string;
@Column({ nullable: false })
ownerId: string; // 소유자 ID
@ManyToOne(() => User, user => user.projects)
owner: User; // User 엔티티와의 관계
@OneToMany(() => File, file => file.project)
files: File[];
@OneToMany(() => Folder, folder => folder.project)
folders: Folder[];
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
}File & Folder Entities
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, CreateDateColumn, UpdateDateColumn } from 'typeorm';
import { Project } from '../../project/entities/project.entity';
@Entity()
export class File {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ nullable: false })
name: string;
@Column({ nullable: false })
path: string; // 예: '/src/main.ts'
@Column({ type: 'text', nullable: true })
content: string; // 파일 내용 (TEXT 타입)
@Column({ nullable: true })
type: string; // 파일 타입 (예: 'javascript', 'python')
@Column({ nullable: false })
projectId: string;
@ManyToOne(() => Project, project => project.files, { onDelete: 'CASCADE' }) // 프로젝트 삭제 시 파일도 삭제
project: Project;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
}import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, CreateDateColumn, UpdateDateColumn } from 'typeorm';
import { Project } from '../../project/entities/project.entity';
@Entity()
export class Folder {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ nullable: false })
name: string;
@Column({ nullable: false })
path: string; // 예: '/src'
@Column({ nullable: false })
projectId: string;
@ManyToOne(() => Project, project => project.folders, { onDelete: 'CASCADE' }) // 프로젝트 삭제 시 폴더도 삭제
project: Project;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
}