Commit Graph

169 Commits

Author SHA1 Message Date
ttipo fa4bc40761 docs: 8단계 진행현황·API 계약 갱신 + 알림/Redis 검토 문서 추가
- integration-progress/api-contract: 8-1 페이지네이션·8-2 알림·8-3 Redis 캐싱 반영.
- notification-review.md: 알림 시스템 전수 검토(유형/빠짐/주의) + 보완 이력.
- redis-cache-review.md: Redis 캐시 전수 검토 + 보완 이력.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 13:13:07 +09:00
ttipo 47567b94a0 fix: 로그인 후 항상 저장소 목록으로 진입
미인증으로 보호 라우트 진입 시 가드가 붙이던 redirect 쿼리로 로그인 후 이전 화면에
복귀하던 동작 제거. LoginPage 는 항상 /repos 로 이동하고, 가드는 redirect 쿼리를
더 이상 보존하지 않는다(딥링크 복귀 제거).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 13:12:56 +09:00
ttipo d87726194b feat: 실시간 알림(인앱+SSE, Redis pub/sub) + Redis 캐싱 (8단계)
알림(8-2):
- Notification 모듈 + SSE 스트림(@Sse, @SkipTransform 으로 표준 래퍼 우회).
- 12종 알림 적재(업무 지시/해제/승인요청/승인/수정요청/시작/마감변경/삭제/댓글·답글,
  멤버 초대/역할변경/제거). 행위자 제외 + 중복 dedup. AppShell 종(미읽음 뱃지·드롭다운).
- 실시간 fan-out: REDIS_HOST 시 ioredis pub/sub(다중 인스턴스), 미설정 시 인메모리 폴백.

Redis 캐싱(8-3):
- CacheModule → @keyv/redis(미설정 시 인메모리 폴백). 저장소 목록을 버전 네임스페이스로
  캐시, 생성/수정/삭제·동기화·멤버 초대/제거 시 무효화(공유 버전 키라 다중 인스턴스 정합).
- enableShutdownHooks 로 종료 시 Redis 연결 graceful close.

검증: 백엔드 build/lint 0·20 tests, 프론트 build/lint/type-check 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 13:12:47 +09:00
ttipo ef858f6e34 feat: 저장소 업무 세그먼트·검색·더보기 + 멤버 전체 로드 (8-1 페이지네이션 마무리)
- 저장소 업무 목록(RepoDetailPage): 세그먼트/검색을 백엔드로 이전(클라 필터 제거),
  응답 counts 로 세그먼트 배지, 더보기(오프셋) 추가. task.store 에 total/counts/hasMore/loadMore.
- 멤버: member.store.fetchList 가 페이지네이션 API 를 끝까지 순회해 전체 로드
  (역할/검색 카운트 전수 + TaskCreatePage 담당자 후보 보장).
- 타입 신설: TaskSegment/TaskSegmentCounts/ApiRepoTaskListResult.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 13:12:21 +09:00
ttipo c128b19599 fix: 목록 페이지네이션 응답 계약 불일치 및 업무 목록 쿼리 크래시 수정
페이지네이션 도입 후 백엔드 목록 API 가 { items, total, ... } 를 반환하는데
프론트 멤버·업무 소비처가 배열로 기대해 list.map 이 깨지고, 멤버 탭과 업무
목록이 비어 보이던 회귀를 수정.

- backend(task): 업무 목록 쿼리에서 to-many 조인 컬럼(checklist.sort_order)
  으로 정렬해 페이지네이션 시 TypeORM 이 터지던 문제 제거(task.seq 만 정렬).
  목록 응답은 체크리스트 [완료/전체] 수만 쓰므로 항목 순서가 불필요.
- frontend(member/task): list 컴포저블이 Paginated<T> 를 반환하도록 맞추고
  스토어에서 .items 로 언래핑(저장소·내업무와 동일 계약).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 00:23:01 +09:00
ttipo 9b01fbaf2f fix: 미정의 예외 로깅에서 메시지·스택 유실 수정
HttpException 이 아닌 예외를 Logger.error 두 번째 인자(스택 문자열 자리)에
Error 객체째로 넘겨, nest-winston 직렬화 과정에서 message/stack 이 사라지고
`{ stack: [ {} ] }` 로만 찍히던 문제를 수정. 메시지는 message 로, 스택은
문자열로 분리해 실제 원인이 로그에 남도록 한다.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 00:22:48 +09:00
ttipo a056d7f55a feat: 업무 상세 부속·활동 피드·내 업무 집계 + 페이지네이션 (5~8단계)
- 5단계(업무 상세 부속): 체크리스트(상세 읽기전용/수정폼 추가·삭제)·댓글/답글·파일 첨부(서버 로컬 업로드 폴더)·승인 워크플로우(요청/승인/수정요청 노트)
- 6단계(활동 피드): 저장소/멤버/업무 행위를 이벤트로 자동 적재, 저장소 활동 피드·업무 활동 탭 실연동(프론트가 type+payload로 문구 조립)
- 7단계(내 업무): 담당/지시 저장소 횡단 집계, MyTasksPage 실연동, TaskAssigneePage(/view) 제거
- 8단계(진행): 목록 페이지네이션 통일 — 백엔드 전체(공통 유틸 + 5개 목록, 저장소 업무는 세그먼트/검색/카운트) + 프론트 더보기(저장소 목록·내 업무 완료, 멤버·저장소 업무 대기)
- UI 보강: 업무 목록 댓글/첨부 분리표기, 첨부 배지 색상·라벨 통일, 완료 업무 D-Day 배지, 활동 이벤트 점검·보강(업무 수정/삭제·답글·첨부 삭제)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 18:13:17 +09:00
ttipo 875eddf659 feat: 업무(Task) 모듈 4단계 — CRUD·상태머신·진행률 집계·역할 기반 상세 UI
백엔드
- Task/ChecklistItem 엔티티(저장소 내 순번 seq, jsonb content, assignees ManyToMany, checklist)
- GET/POST/PATCH/DELETE /repos/:repoId/tasks[/:taskId] + POST .../status
- 상태 머신(todo→prog→review→done, review→changes, changes→{review,prog}) + 전이별 역할 검증
- 담당자=저장소 멤버만 지정, 승인 완료(→done) 시 체크리스트 일괄 완료(영속)
- 저장소 doneCount/totalCount·멤버 taskCount 실집계(RepoModule→TaskModule)
- Task.repo FK 컬럼명 snake_case 고정(@JoinColumn), task.service 단위 테스트

프론트
- types/task·useTask·task.store, format.ts 라벨 파생(상태/마감/dday)
- RepoDetailPage 업무 목록, TaskCreatePage 생성/수정 겸용(편집 라우트)
- TaskDetailPage 역할 기반 액션 분기(지시자 승인/수정요청, 담당자 시작/승인요청)
- 액션 카드·상태 뱃지 디자인 시안 정렬, 작성폼/목록 UI 정리

문서: api-contract·integration-progress 4단계 반영

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 18:12:11 +09:00
ttipo c01f8e535c feat: 멤버 관리 연동 + 사용자 검색 API (3단계)
- 멤버 목록/초대/역할변경/제거 프론트 연동(RepoMembersPage), 초대 자동완성
- GET /users 사용자 검색 API + UserController
- RepoMembersPage 역할 변경 드롭다운 잘림(overflow) 수정
- InviteMember/UpdateMember DTO, RepoMember 엔티티 정비

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 18:11:46 +09:00
ttipo e2fe089321 feat: Gitea 프론트 연동(클론바·원격없음 배지)·import-admin 인프라 마무리
- GiteaRepoBar 컴포넌트(클론 주소 복사 + Gitea 열기)를 RepoSettingsPage 에 적용
- repo.store 뷰에 cloneUrl/htmlUrl/giteaMissing 매핑
- repo-sync: import 저장소 owner-admin 자동 지정(REPO_IMPORT_ADMIN_EMAIL)
- env example·docker-compose.dev 에 Gitea/import-admin 키 정비

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 18:11:16 +09:00
ttipo b626bbdf6c chore: 브랜드 로고 에셋 추가 (logo png/svg)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 18:10:28 +09:00
ttipo ae385355b8 feat: Gitea 조직 저장소 역방향 동기화 (기동 시·매시간 import)
- GiteaService.listOrgRepos(): 조직 저장소 페이지네이션 조회
- RepoSyncService: OnApplicationBootstrap(비차단) + @Cron(매시간) 동기화
  - 추가형 import(멤버 0명), 연동정보 backfill, Gitea 누락 시 giteaMissing 표기
- Repo.giteaMissing 컬럼 + RepoResponse/프론트 ApiRepo 노출
- GET /repos 를 '조직 저장소 전체'(findAll)로, 단건은 인증 사용자 열람 허용
- docs(api-contract·integration-progress) 2.6단계 반영

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 13:16:20 +09:00
ttipo 2b38e21188 chore: env example 파일 정비 (루트·프론트 추가, 단독 실행 예시 제거)
- 루트 .env.{development,production}.example 신규 (비밀값 placeholder 마스킹)
- frontend .env.{development,production}.example 신규 (docker build arg 주입 설명)
- backend example 의 단독 실행(non-Docker) 예시 블록 제거

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 13:16:03 +09:00
ttipo a8069aa72b docs: 진행현황 갱신 — 생성폼 보강(소유자/설명/템플릿) 반영
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 00:29:27 +09:00
ttipo 7f432a0013 feat: 저장소 생성 시 설명 필수화 + 템플릿 복제 생성
- 프로젝트 설명을 생성 필수 항목으로 변경(CreateRepoDto.description required + 프론트 검증)
- 템플릿 복제: useTemplate=true 면 Gitea generate API 로 GITEA_TEMPLATE_OWNER/REPO
  (기본 TtiPo/project-base) 저장소를 복제 생성(브랜치는 템플릿을 따름)
- GET /repos/owner → /repos/meta 로 확장({ owner, template }) — 생성폼 메타 일괄 제공
- 프론트 생성폼: 가짜 템플릿 목록 제거 → 실제 템플릿 옵션, 설명 필수 UI
- env.example/ api-contract/ 진행현황 문서 갱신

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 00:20:21 +09:00
ttipo 6652e79768 feat: 저장소 소유자(조직)를 백엔드 설정값으로 표시
생성 폼/목록의 하드코딩된 'marketing-team' 을 실제 설정값으로 교체한다.
- 백엔드: GET /repos/owner ({ owner }) — GITEA_ORG(미연동 시 기본 상수) 반환
- 프론트: useRepo.owner() + repo.store owner/fetchOwner(캐시)
- RepoCreatePage 소유자 고정 표시, RepoListPage 배너를 실제 조직명으로

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 23:53:39 +09:00
ttipo efe7b29581 feat: 저장소 멤버 관리 API 추가 (3단계)
저장소별 멤버 초대/역할변경/제거 엔드포인트를 추가한다.
- MemberService/MemberController: GET/POST/PATCH/DELETE /repos/:repoId/members
- 권한: 목록=멤버+, 변경=admin, 소유자(owner) 역할변경·제거 불가
- 초대는 가입된 사용자만(이메일 조회), 미가입/중복 시 BIZ_001
- InviteMemberDto/UpdateMemberDto, member.service.spec(가드 단위 테스트)
- 멤버는 Gitea 미동기화(조직 토큰 단일 모델), api-contract/진행현황 갱신

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 23:41:44 +09:00
ttipo 6027856cbb feat: 저장소 생성 시 Gitea 조직 연동 추가
외부 Gitea 인스턴스의 조직에 저장소를 자동 동기화한다.
- GiteaService: /api/v1 클라이언트(내장 fetch, 새 의존성 없음), enabled 게이트
- Repo 엔티티에 연동 컬럼(giteaRepoId/giteaFullName/cloneUrl/htmlUrl) 추가
- RepoService 생성/수정/삭제에 Gitea 동기화 와이어링(생성 우선·실패 시 롤백)
- GITEA_* env 문서화(.env.example), api-contract/진행현황 문서 갱신

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 22:17:33 +09:00
ttipo e1bc5a1dfc first commit 2026-06-16 17:12:08 +09:00