2f66cdda8a
저장소=프로젝트 1:1 구조를 프로젝트 우선 + 프로젝트 1:N 저장소로 전환하는 리팩터의 기반. 기존 코드는 건드리지 않고 추가만 함(기존 저장소 기반 동작 유지). - Project / ProjectMember 엔티티 (isSystem '미분류' 버킷, admin/member/owner) - ProjectService: CRUD + 권한 헬퍼(assertProjectMember/Admin) + 부팅 시 '미분류' 시스템 프로젝트 보장 - ProjectMemberService: 초대/역할/제거 (활동·알림 배선은 Activity 이관 단계 TODO) - /projects, /projects/:id/members 라우트, app.module 등록 - docs/project-refactor-plan.md (리팩터 SSOT) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.5 KiB
4.5 KiB
프로젝트 우선 구조 리팩터 계획 (Project-First)
작성 2026-06-20. 현재 저장소(Repo)=프로젝트 1:1 구조를 프로젝트 우선 + 프로젝트 1:N 저장소 로 전환한다. 이 문서가 리팩터의 단일 진실 공급원(SSOT). 단계별로 갱신한다.
1. 목표 구조
Project (이름/설명/공개범위) ← 작업의 기본 단위(우선)
├─ ProjectMember (admin/member, isOwner) ← 멤버십을 프로젝트로 이동(RepoMember 폐지)
├─ Task (project, seq[프로젝트 내 순번], …) ← 업무는 프로젝트 소속
│ └─ checklist / comment / attachment (기존 그대로, Task 종속)
├─ Activity (project, taskSeq?, …) ← 활동도 프로젝트 단위
└─ Repo[] (project FK, gitea 필드…) ← 0~N개 저장소 연동(선택, 코드 연동 전용)
- 일반 프로젝트 = 연동 저장소 0개. 업무·멤버·활동 정상 사용.
- 저장소 연동 프로젝트 = 저장소 1~N개 링크. 추가로 Gitea/코드참조.
2. 확정된 설계 결정 (사용자 합의 2026-06-20)
- 업무·멤버·활동 = 프로젝트 단위.
Task→Repo종속을Task→Project로 이동.RepoMember폐지 →ProjectMember. - Gitea 자동 가져오기(역방향 동기화) → import 저장소는 "미분류" 기본 프로젝트에 연결. 관리자가 나중에 적절한 프로젝트로 이동.
- dev DB 초기화(volume 재생성). 마이그레이션 스크립트 불필요.
3. 추가 설계 결정 (구현자 판단 — 변경 가능)
- 라우팅: 업무는 프로젝트 직속, 저장소는 형제 부속.
/projects·/projects/:projectId(상세=업무목록) ·/projects/:projectId/{members,activity,settings}/projects/:projectId/tasks/:seq(업무 상세) ·/projects/:projectId/tasks/new/projects/:projectId/repos(연동 저장소 목록·링크) ·/projects/:projectId/repos/:repoSlug(저장소 상세/설정)/tasks(내 업무, 프로젝트 횡단 — 경로 유지)
- 저장소 식별자:
slugName은 Gitea 조직 내 유일이므로 전역 유일 유지(프로젝트 내 유일로 바꾸지 않음). Repo 에project_idFK만 추가. - Task.seq:
@Unique(['repo','seq'])→@Unique(['project','seq'])(프로젝트 내 순번 #N). - 권한:
assertMember/assertAdmin(repo.id, …)→assertProjectMember/assertProjectAdmin(project.id, …). 저장소 단위 세분 권한은 두지 않음(프로젝트 멤버면 연동 저장소 전체 접근). 향후 옵션. - 저장소 자체엔 멤버 없음. 저장소는 순수 Gitea 연동 메타. 멤버십/권한은 소유 프로젝트가 결정.
- "미분류" 기본 프로젝트: 시스템 예약 프로젝트 1개(부팅 시 보장 생성). Gitea import 대상.
4. 단계별 실행 계획
Phase 1 — 백엔드 데이터 모델 + Project 모듈 (핵심)
Project·ProjectMember엔티티 +ProjectModule/ProjectService/ProjectController(CRUD + 멤버 초대/역할/제거 + 권한 가드)- "미분류" 기본 프로젝트 부팅 보장(OnApplicationBootstrap)
Repo에projectFK 추가.RepoMember폐지. Repo 생성/수정/삭제가 프로젝트 권한으로 게이트.Task를project종속으로 변경(@Unique(['project','seq'])), 권한 체인 프로젝트로 교체, 담당자=프로젝트 멤버.Activity를project종속으로. (taskSeq 유지)RepoSyncService: import → "미분류" 프로젝트 연결.AiService.suggestChecklist: 프로젝트/저장소 컨텍스트 정합.- 컨트롤러 라우트 재배치(
/projects/...). 기존/repos/...제거 또는 이전. - 검증: build/lint/test.
Phase 2 — 프론트 프로젝트 중심 재구성
project.store·useProject·types/project.ts- 신규 페이지: ProjectListPage(진입점)·ProjectDetailPage(업무목록)·ProjectSettingsPage·ProjectMembersPage·ProjectActivityPage
- 저장소: 프로젝트 내 "연동 저장소" 섹션 + RepoLinkPage(기존 RepoCreate 재구성)
- task/member/activity 스토어를 projectId 키로 재설계
- 라우팅 전면 교체, AppShell 네비(프로젝트/내 업무)
- 검증: type-check/lint/build.
Phase 3 — 마무리
- 문서(api-contract.md)·메모리 갱신, 잔여 UI 정리, 런타임 점검.
5. 진행 로그
- (작성됨) Phase 0: 계획 수립. 다음 = Phase 1 백엔드.