chore: 잔존 '저장소' 주석·문구를 '프로젝트'로 정리

저장소 기능 제거 후 남은 '저장소' 표현을 프로젝트로 통일:
- 백엔드: activity/notification/task 주석·ApiResponse 문구, AI 시스템 프롬프트
  (SUGGEST_SYSTEM_PROMPT 의 저장소→프로젝트, 무의미해진 'slug=영문이름' 지시 제거),
  CONTEXT_REPO_LIMIT→CONTEXT_PROJECT_LIMIT(프로젝트 컨텍스트 한도)
- 프론트: 페이지/스토어 주석 및 TaskCreate/TaskDetail 의 사용자 노출 문구('저장소'→'프로젝트')
- 단, auth OAuth state 'store' 의미의 '저장소'(cookie-state/strategies)는 정당하여 유지

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

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-21 01:57:06 +09:00
parent be0a1bc9d1
commit 32a87d8f62
15 changed files with 42 additions and 36 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ import type { Paginated } from '@/types/pagination'
export function useMember() {
const api = useApi()
// 멤버 목록 (멤버 또는 공개 저장소) — 백엔드가 페이지네이션 { items, total, ... } 반환
// 멤버 목록 (멤버 또는 공개 프로젝트) — 백엔드가 페이지네이션 { items, total, ... } 반환
async function list(
projectId: string,
page = 1,
+1 -1
View File
@@ -29,7 +29,7 @@ const verifyBanner = computed<{ ok: boolean; text: string } | null>(() => {
return null
})
// 로그인 처리 — 성공 시 항상 저장소 목록으로 진입(이전 화면/딥링크로 복귀하지 않음)
// 로그인 처리 — 성공 시 항상 프로젝트 목록으로 진입(이전 화면/딥링크로 복귀하지 않음)
async function onLogin() {
if (submitting.value) return
submitting.value = true
@@ -19,7 +19,7 @@ const projectStore = useProjectStore()
const taskStore = useTaskStore()
const { tasks, counts, hasMore, loadingMore, loading } = storeToRefs(taskStore)
// 저장소 헤더/진행률 — API 연동
// 프로젝트 헤더/진행률 — API 연동
const repo = ref<Project | null>(null)
async function loadProject() {
try {
@@ -56,7 +56,7 @@ async function loadMoreTasks() {
}
}
// 저장소 전환 시 헤더 + 목록 리셋 로드
// 프로젝트 전환 시 헤더 + 목록 리셋 로드
watch(
projectId,
() => {
@@ -66,7 +66,7 @@ watch(
{ immediate: true },
)
// 세그먼트 변경 시 목록만 리셋 로드(저장소 재조회 불필요)
// 세그먼트 변경 시 목록만 리셋 로드(프로젝트 재조회 불필요)
watch(segment, loadTasks)
// 검색어는 디바운스 후 리셋 로드(연속 입력 시 호출 폭주 방지)
@@ -116,7 +116,7 @@ const STATUS_LABEL: Record<TaskStatus, string> = {
<b>{{ repo.name }}</b>
</div>
<!-- 저장소 헤더(공통) 진행률 스트립을 extra 슬롯으로 주입 -->
<!-- 프로젝트 헤더(공통) 진행률 스트립을 extra 슬롯으로 주입 -->
<ProjectHeader
:repo="repo"
:meta-text="repo.updatedAgo"
@@ -409,7 +409,7 @@ const STATUS_LABEL: Record<TaskStatus, string> = {
</button>
</div>
<!-- 저장소 찾지 못한 경우 -->
<!-- 프로젝트 찾지 못한 경우 -->
<div
v-else
class="page"
+1 -1
View File
@@ -219,7 +219,7 @@ const filteredProjects = computed(() =>
color: var(--text-2);
}
/* 저장소 행 */
/* 프로젝트 행 */
.repo-row {
display: flex;
align-items: center;
+1 -1
View File
@@ -103,7 +103,7 @@ const points = [
팀에 합류하고<br>업무 지시를 시작하세요
</div>
<div class="bp-sub">
계정을 만들면 저장소 초대되어, 받은 업무를 확인하고 직접 업무를 지시할 있습니다.
계정을 만들면 프로젝트 초대되어, 받은 업무를 확인하고 직접 업무를 지시할 있습니다.
</div>
<div class="bp-points">
<div
+6 -6
View File
@@ -51,7 +51,7 @@ function toDateInput(iso: string): string {
return `${y}-${m}-${day}`
}
// 저장소 헤더(빵부스러기) — API 연동
// 프로젝트 헤더(빵부스러기) — API 연동
const repo = ref<Project | null>(null)
async function loadProject() {
try {
@@ -163,7 +163,7 @@ const aiSuggestions = ref<ChecklistSuggestionGroup[] | null>(null)
const aiError = ref<string | null>(null)
const canRequestAi = computed(() => !aiSuggesting.value && title.value.trim().length > 0)
// 저장소 설명 + 제목/내용을 분석해 카테고리별 할 일 추천을 받는다
// 프로젝트 설명 + 제목/내용을 분석해 카테고리별 할 일 추천을 받는다
async function requestAiSuggestions() {
if (!canRequestAi.value) return
aiSuggesting.value = true
@@ -326,14 +326,14 @@ function goBack() {
to="/projects"
class="lnk"
>
저장소
프로젝트
</RouterLink>
<span class="sep">/</span>
<RouterLink
:to="`/projects/${projectId}`"
class="lnk"
>
{{ repo?.name ?? '저장소' }}
{{ repo?.name ?? '프로젝트' }}
</RouterLink>
<span class="sep">/</span>
{{ isEdit ? '수정' : '새 업무' }}
@@ -353,7 +353,7 @@ function goBack() {
class="btn ai"
type="button"
:disabled="!canRequestAi"
title="저장소·업무 내용을 분석해 할 일을 추천합니다"
title="프로젝트·업무 내용을 분석해 할 일을 추천합니다"
@click="requestAiSuggestions"
>
<svg
@@ -595,7 +595,7 @@ function goBack() {
v-if="aiSuggesting"
class="ai-suggest-msg"
>
저장소 업무 내용을 분석하고 있어요
프로젝트 업무 내용을 분석하고 있어요
</div>
<div
v-else-if="aiError"
+2 -2
View File
@@ -101,7 +101,7 @@ function closeAllOverlays() {
moreOpen.value = false
}
// 모달에서 삭제 확정 → DELETE 후 저장소 상세로 이동
// 모달에서 삭제 확정 → DELETE 후 프로젝트 상세로 이동
async function confirmDelete() {
if (!task.value) return
showDelete.value = false
@@ -320,7 +320,7 @@ function badgeFor(name: string | undefined): { label: string; cls: string } {
to="/projects"
class="lnk"
>
저장소
프로젝트
</RouterLink>
<span class="sep">/</span>
<RouterLink
+2 -2
View File
@@ -112,14 +112,14 @@ function toProjectActivityItem(api: ApiActivity): ProjectActivityItem {
}
}
// 활동 스토어 — 저장소 활동 피드(날짜 그룹)
// 활동 스토어 — 프로젝트 활동 피드(날짜 그룹)
export const useActivityStore = defineStore('activity', () => {
const days = ref<ProjectActivityDay[]>([])
const loading = ref(false)
const activityApi = useActivity()
// 저장소 활동 조회 → 날짜 그룹으로 묶기(목록은 최신순이라 같은 날은 연속)
// 프로젝트 활동 조회 → 날짜 그룹으로 묶기(목록은 최신순이라 같은 날은 연속)
async function fetch(projectId: string): Promise<void> {
loading.value = true
try {
+1 -1
View File
@@ -27,7 +27,7 @@ function toMemberView(api: ApiProjectMember, currentUserId: string | null): Memb
}
}
// 프로젝트 멤버 스토어 — 현재 저장소의 멤버 목록 상태 + 초대/역할변경/제거 액션
// 프로젝트 멤버 스토어 — 현재 프로젝트의 멤버 목록 상태 + 초대/역할변경/제거 액션
export const useMemberStore = defineStore('member', () => {
const members = ref<MemberView[]>([])
const loading = ref(false)