refactor: 프로젝트에서 공개 범위(visibility) 제거
불필요한 프로젝트 공개 범위 데이터를 백엔드·프론트에서 일괄 제거(저장소 Repo 의 visibility 는 Gitea 연동용이라 유지). 백엔드: - Project 엔티티 visibility 컬럼·ProjectVisibility 타입 제거(dev synchronize 가 컬럼 DROP) - create/update DTO, ProjectResponse, create/update/ensureUnassigned/toResponse 에서 제거 - ai.service 프로젝트 컨텍스트 문자열에서 공개범위 표기 제거 - activity 타입 project.visibility_changed 제거 프론트: - types/project·project.store·mock Project 에서 visibility 제거 - ProjectCreatePage·ProjectSettingsPage 공개 범위 입력 폼+CSS 제거 - ProjectListPage 공개여부 세그먼트 필터+배지 제거, ProjectHeader 배지 제거 - activity 타입/스토어 project.visibility_changed 케이스 제거 런타임 검증: DB projects.visibility 컬럼 DROP, 생성/목록 응답에 visibility 없음, CRUD 정상. 백엔드 build/lint 0·14 tests, 프론트 type-check/lint/build 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,6 @@ export type ActivityType =
|
||||
// 프로젝트(설정)
|
||||
| 'project.created'
|
||||
| 'project.renamed'
|
||||
| 'project.visibility_changed'
|
||||
// 저장소 연동
|
||||
| 'repo.linked'
|
||||
| 'repo.unlinked'
|
||||
|
||||
@@ -395,10 +395,7 @@ export class AiService {
|
||||
lines.push('- (없음)');
|
||||
} else {
|
||||
for (const p of projects.items) {
|
||||
const vis = p.visibility === 'private' ? '비공개' : '공개';
|
||||
lines.push(
|
||||
`- ${p.name} — ${vis}, 업무 ${p.doneCount}/${p.totalCount}건`,
|
||||
);
|
||||
lines.push(`- ${p.name} — 업무 ${p.doneCount}/${p.totalCount}건`);
|
||||
}
|
||||
if (projects.total > projects.items.length) {
|
||||
lines.push(`- … 외 ${projects.total - projects.items.length}개`);
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
import {
|
||||
IsIn,
|
||||
IsNotEmpty,
|
||||
IsOptional,
|
||||
IsString,
|
||||
MaxLength,
|
||||
} from 'class-validator';
|
||||
import { IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import type { ProjectVisibility } from '../entities/project.entity';
|
||||
|
||||
// 프로젝트 생성 DTO
|
||||
export class CreateProjectDto {
|
||||
@@ -24,13 +17,4 @@ export class CreateProjectDto {
|
||||
@IsString()
|
||||
@MaxLength(300)
|
||||
description?: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: '공개 범위',
|
||||
enum: ['private', 'public'],
|
||||
required: false,
|
||||
})
|
||||
@IsOptional()
|
||||
@IsIn(['private', 'public'], { message: '공개 범위를 선택해 주세요.' })
|
||||
visibility?: ProjectVisibility;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { IsIn, IsOptional, IsString, MaxLength } from 'class-validator';
|
||||
import { IsOptional, IsString, MaxLength } from 'class-validator';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import type { ProjectVisibility } from '../entities/project.entity';
|
||||
|
||||
// 프로젝트 수정 DTO — 제공된 필드만 갱신
|
||||
export class UpdateProjectDto {
|
||||
@@ -15,13 +14,4 @@ export class UpdateProjectDto {
|
||||
@IsString()
|
||||
@MaxLength(300)
|
||||
description?: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: '공개 범위',
|
||||
enum: ['private', 'public'],
|
||||
required: false,
|
||||
})
|
||||
@IsOptional()
|
||||
@IsIn(['private', 'public'], { message: '공개 범위를 선택해 주세요.' })
|
||||
visibility?: ProjectVisibility;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,6 @@ import {
|
||||
} from 'typeorm';
|
||||
import { ProjectMember } from './project-member.entity';
|
||||
|
||||
// 프로젝트 공개 범위
|
||||
export type ProjectVisibility = 'private' | 'public';
|
||||
|
||||
// 프로젝트 엔티티 — 작업의 기본 단위(우선). 저장소(Repo)는 프로젝트에 0~N개 연동된다.
|
||||
@Entity('projects')
|
||||
export class Project {
|
||||
@@ -27,10 +24,6 @@ export class Project {
|
||||
@Column({ type: 'varchar', nullable: true })
|
||||
description!: string | null;
|
||||
|
||||
// 공개 범위
|
||||
@Column({ type: 'varchar', default: 'private' })
|
||||
visibility!: ProjectVisibility;
|
||||
|
||||
// 시스템 예약 프로젝트 여부 — "미분류"(Gitea import 기본 버킷)는 true. 삭제/이름변경 보호.
|
||||
@Column({ name: 'is_system', default: false })
|
||||
isSystem!: boolean;
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
resolvePage,
|
||||
type PaginatedResult,
|
||||
} from '../../common/pagination/pagination';
|
||||
import { Project, type ProjectVisibility } from './entities/project.entity';
|
||||
import { Project } from './entities/project.entity';
|
||||
import { ProjectMember } from './entities/project-member.entity';
|
||||
import { Repo } from '../repo/entities/repo.entity';
|
||||
import { Task } from '../task/entities/task.entity';
|
||||
@@ -28,7 +28,6 @@ export interface ProjectResponse {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string | null;
|
||||
visibility: ProjectVisibility;
|
||||
isSystem: boolean;
|
||||
members: PublicUser[];
|
||||
memberCount: number;
|
||||
@@ -120,7 +119,6 @@ export class ProjectService implements OnApplicationBootstrap {
|
||||
this.projectRepo.create({
|
||||
name: dto.name,
|
||||
description: dto.description ?? null,
|
||||
visibility: dto.visibility ?? 'private',
|
||||
isSystem: false,
|
||||
}),
|
||||
);
|
||||
@@ -155,7 +153,6 @@ export class ProjectService implements OnApplicationBootstrap {
|
||||
}
|
||||
if (dto.name !== undefined) project.name = dto.name;
|
||||
if (dto.description !== undefined) project.description = dto.description;
|
||||
if (dto.visibility !== undefined) project.visibility = dto.visibility;
|
||||
await this.projectRepo.save(project);
|
||||
return this.findOne(project.id, userId);
|
||||
}
|
||||
@@ -187,7 +184,6 @@ export class ProjectService implements OnApplicationBootstrap {
|
||||
this.projectRepo.create({
|
||||
name: UNASSIGNED_PROJECT_NAME,
|
||||
description: 'Gitea 에서 가져온, 아직 프로젝트에 배정되지 않은 저장소',
|
||||
visibility: 'private',
|
||||
isSystem: true,
|
||||
}),
|
||||
);
|
||||
@@ -275,7 +271,6 @@ export class ProjectService implements OnApplicationBootstrap {
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
description: project.description,
|
||||
visibility: project.visibility,
|
||||
isSystem: project.isSystem,
|
||||
members: members
|
||||
.filter((m) => m.user)
|
||||
|
||||
Reference in New Issue
Block a user