diff --git a/ROADMAP_WBS.md b/ROADMAP_WBS.md index 2c4e21f..22daeec 100644 --- a/ROADMAP_WBS.md +++ b/ROADMAP_WBS.md @@ -2,67 +2,19 @@ 이 문서는 "완료 보고"가 아니라 검증 가능한 작업 목록이다. 각 WBS는 성공 기준을 통과해야 완료로 본다. +--- + ## 완료 판정 원칙 - 코드 변경만으로 완료 처리하지 않는다. -- 서버 배포 대상 기능은 CI/CD 성공과 Playwright 브라우저 테스트 통과를 모두 요구한다. +- 서버 배포 대상 기능은 CI/CD 성공과 실제 동작 확인을 요구한다. - API 기능은 단위 테스트 또는 통합 테스트와 함께 실제 HTTP 호출 결과를 확인한다. - DB 변경은 마이그레이션과 롤백 위험을 문서화한다. - 비밀값은 Gitea Secrets 또는 서버 환경변수로만 관리한다. -## WBS-OPS-01 배포 검증 게이트 고도화 +--- -목표: curl/API만이 아니라 실제 브라우저 검증까지 통과해야 배포를 성공으로 본다. - -성공 기준: -- `dotnet build TaxBaik.sln -c Release` 경고 0, 오류 0 -- `dotnet test TaxBaik.sln -c Release --no-build` 전체 통과 -- CI 배포 후 Playwright가 `/taxbaik/admin/login`에서 실제 로그인 수행 -- 로그인 후 `/taxbaik/admin/dashboard` 도달 -- 브라우저 console error 및 page error 0개 -- `blog-seo`, `contact-submit`, `admin-password-change`가 배포본 기준으로 통과 - -Todo: -- [x] Playwright Test 프로젝트 추가 -- [x] 관리자 로그인 E2E 추가 -- [x] CI 배포 후 Playwright 실행 단계 추가 -- [x] Playwright가 발견한 Blazor DI 결함 수정 -- [ ] CI run에서 Playwright 전체 통과 확인 -- [ ] 배포 검증에 블로그 상세/문의/비밀번호 변경 성공 기준 반영 확인 - -## WBS-AUTH-01 인증/비밀번호 운영 안정화 - -목표: DB 직접 수정 대신 API로 관리자 인증 운영 작업을 수행한다. - -성공 기준: -- 비밀번호 변경 API가 현재 비밀번호를 요구한다. -- 비밀번호 재설정 API는 운영 secret 없이는 동작하지 않는다. -- 실패 응답은 민감 정보를 노출하지 않는다. -- Playwright 로그인 테스트와 비밀번호 변경 테스트가 변경 후에도 통과한다. - -Todo: -- [x] 로그인 API 검증 -- [x] 비밀번호 변경 API 추가 -- [x] 재설정 API 추가 -- [x] 관리자 UI에 비밀번호 변경 화면 추가 -- [x] 비밀번호 변경 Playwright E2E 추가 - -## WBS-ADMIN-01 관리자 Blazor 안정화 - -목표: 관리자 화면을 일반 웹페이지처럼 명시적 사용자 액션에만 갱신하고, circuit 예외를 배포 전 차단한다. - -성공 기준: -- 관리자 주요 메뉴 대시보드/블로그/문의/설정 접근 시 circuit error 0개 -- 잘못된 DI 타입 주입 0건 -- 저장/삭제/상태 변경 액션은 성공/실패 메시지를 표시한다. -- Playwright가 주요 메뉴 smoke test를 수행한다. - -Todo: -- [x] 중복 `/admin` 라우트 제거 -- [x] MudBlazor DI 타입 오류 수정 -- [x] 관리자 메뉴 smoke E2E 추가 -- [x] 설정 저장 TODO를 실제 DB 기반 기능으로 전환 -- [x] 대시보드/목록 읽기 성능 개선 +## ── 홈페이지 · SEO · UX ─────────────────────────── ## WBS-UX-01 공개 홈페이지 UX/SEO 검증 @@ -86,24 +38,339 @@ Todo: - `tests/e2e/contact-submit.spec.ts` - `tests/e2e/inquiry-detail.spec.ts` +## WBS-UX-02 홈페이지 FAQ 섹션 + +목표: 방문자가 상담 전 자주 묻는 질문에서 직접 답을 얻고 전환율을 높인다. + +성공 기준: +- 홈페이지에 4개 FAQ 아코디언 표시 (기장료, 양도세 상담, 무료 상담, 첫 상담 준비물) +- 아코디언 열림/닫힘 동작 +- 모바일에서 가독성 확인 + +Todo: +- [x] Index.cshtml에 FAQ 아코디언 섹션 추가 (최종 CTA 앞) +- [x] site.css faq-accordion / faq-item / faq-question / faq-answer 스타일 +- [ ] 배포 후 브라우저 동작 확인 + +--- + +## ── 시즌별 마케팅 ─────────────────────────────── + +## WBS-MKT-01 시즌별 홈페이지 자동 전환 + +목표: 세무 신고 시즌마다 홈페이지 Hero·CTA·서비스 카드 순서가 자동 변경된다. + +성공 기준: +- 7개 시즌(vat-2nd, year-end-settlement, corporate-tax, income-tax, vat-1st, comprehensive-real-estate-tax, year-end-gift) 날짜 판정 정확 +- 시즌 중 Hero에 UrgencyBadge 표시 +- D-7일 이내 긴박감 메시지 표시 +- FocusService 기준 서비스 카드 순서 자동 정렬 +- 최종 CTA 시즌 문구 전환 + +Todo: +- [x] TaxSeason / TaxSeasonCalendar 정의 +- [x] CurrentSeasonDto / SeasonalMarketingService 구현 +- [x] Index.cshtml Hero 시즌 분기 렌더링 +- [x] Index.cshtml 서비스 카드 cardOrder 정렬 로직 +- [x] Index.cshtml 최종 CTA 시즌 전환 +- [x] CLAUDE.md 섹션 13 세무 캘린더 하네스 +- [ ] 배포 후 시즌 날짜 경계값 수동 확인 + +## WBS-MKT-02 관리자 공지사항 (Announcement) + +목표: 운영자가 홈페이지 최상단 배너를 등록·수정·삭제할 수 있다. + +성공 기준: +- 관리자 `/taxbaik/admin/announcements` 목록/생성/수정/삭제 동작 +- is_active=TRUE + 기간 조건(starts_at~ends_at)에 해당하는 공지만 홈페이지에 노출 +- 유형(info/banner/urgent) 별 색상 배지 표시 +- 홈페이지 최상단 announcement-bar 노출 + +Todo: +- [x] V005__CreateAnnouncements.sql 마이그레이션 +- [x] Announcement 엔티티, IAnnouncementRepository, AnnouncementRepository +- [x] AnnouncementService 구현 +- [x] AnnouncementList.razor, AnnouncementEdit.razor 관리자 화면 +- [x] Index.cshtml 공지사항 배너 렌더링 +- [x] MainLayout.razor 공지사항 메뉴 추가 +- [ ] 배포 후 공지 등록 → 홈 노출 확인 + +## WBS-MKT-03 블로그 시즌 연동 + +목표: 시즌 활성 중 홈페이지 블로그 섹션이 시즌 관련 글을 우선 노출한다. + +배경: 세무 시즌에 맞는 콘텐츠를 전면에 배치해 상담 전환율과 SEO 체류시간을 높인다. + +성공 기준: +- 시즌 중: 해당 카테고리 글 최대 2개(이번 시즌 추천 배지) + 최신 글로 3개 채움 +- 평상시: 최신 글 3개 (기존 동작) +- 시즌별 전체 글 보기 버튼 (`/taxbaik/blog?category=`) +- 배너 헤더가 시즌명 표시 + +카테고리 → 시즌 슬러그 매핑: +- `vat-2nd` / `vat-1st` → `vat` +- `income-tax` → `income-tax` +- `year-end-settlement` / `corporate-tax` → `business-tax` +- `comprehensive-real-estate-tax` → `real-estate-tax` +- `year-end-gift` → `family-asset` + +Todo: +- [x] TaxSeason.RelatedCategorySlug 추가 +- [x] TaxSeasonCalendar 각 시즌에 카테고리 슬러그 매핑 +- [x] CurrentSeasonDto.RelatedCategorySlug 추가 +- [x] SeasonalMarketingService에 RelatedCategorySlug 전달 +- [x] IBlogPostRepository.GetByCategorySlugAsync 추가 +- [x] BlogPostRepository.GetByCategorySlugAsync 구현 +- [x] BlogService.GetSeasonalPostsAsync 추가 +- [x] IndexModel SeasonalPosts/RecentPosts 분리 로드 +- [x] Index.cshtml 블로그 섹션 시즌 분기 렌더링 +- [x] site.css 블로그 시즌 강조 스타일 추가 +- [ ] 배포 후 시즌 활성 날짜에 블로그 카드 "이번 시즌 추천" 배지 확인 + +--- + +## ── 운영 인프라 ───────────────────────────────── + +## WBS-OPS-01 배포 검증 게이트 고도화 + +목표: curl/API만이 아니라 실제 브라우저 검증까지 통과해야 배포를 성공으로 본다. + +성공 기준: +- `dotnet build TaxBaik.sln -c Release` 경고 0, 오류 0 +- `dotnet test TaxBaik.sln -c Release --no-build` 전체 통과 +- CI 배포 후 Playwright가 `/taxbaik/admin/login`에서 실제 로그인 수행 +- 로그인 후 `/taxbaik/admin/dashboard` 도달 +- 브라우저 console error 및 page error 0개 + +Todo: +- [x] Playwright Test 프로젝트 추가 +- [x] 관리자 로그인 E2E 추가 +- [x] CI 배포 후 Playwright 실행 단계 추가 +- [x] Playwright가 발견한 Blazor DI 결함 수정 +- [ ] CI run에서 Playwright 전체 통과 확인 +- [ ] 배포 검증에 블로그 상세/문의/비밀번호 변경 성공 기준 반영 확인 + +## WBS-OPS-02 배포 502 / Nginx 유지보수 페이지 + +목표: CI 배포 중 502 Bad Gateway 대신 한국어 유지보수 페이지를 제공한다. + +성공 기준: +- Nginx error_page 502/503 → maintenance.html 직접 서빙 +- 배포 중 방문자는 유지보수 페이지(15초 자동 새로고침)를 본다. +- 배포 완료 후 정상 서비스 복구 + +Todo: +- [x] maintenance.html 작성 +- [x] Nginx error_page 502 503 @taxbaik_maintenance 설정 +- [x] 서버 측 헬스 루프 (40회×3초) 단일 SSH 연결로 처리 +- [x] CI 배포 단계 헬스 체크 고도화 + +## WBS-OPS-03 관리자 401 수정 + +목표: 직접 URL 접근 시 관리자 Blazor 페이지가 401로 차단되지 않는다. + +성공 기준: +- `/taxbaik/admin/announcements` 등 직접 접근 시 Blazor Shell 200 응답 +- 미인증 사용자는 로그인 페이지로 리다이렉트 + +Todo: +- [x] MapRazorComponents().AllowAnonymous() 적용 +- [x] AuthorizeRouteView → RedirectToLogin 인증 흐름 확인 + +--- + +## ── 인증 · 관리자 ───────────────────────────────── + +## WBS-AUTH-01 인증/비밀번호 운영 안정화 + +목표: DB 직접 수정 대신 API로 관리자 인증 운영 작업을 수행한다. + +성공 기준: +- 비밀번호 변경 API가 현재 비밀번호를 요구한다. +- 비밀번호 재설정 API는 운영 secret 없이는 동작하지 않는다. +- 실패 응답은 민감 정보를 노출하지 않는다. + +Todo: +- [x] 로그인 API 검증 +- [x] 비밀번호 변경 API 추가 +- [x] 재설정 API 추가 +- [x] 관리자 UI에 비밀번호 변경 화면 추가 +- [x] 비밀번호 변경 Playwright E2E 추가 + +## WBS-ADMIN-01 관리자 Blazor 안정화 + +목표: 관리자 화면을 일반 웹페이지처럼 명시적 사용자 액션에만 갱신하고, circuit 예외를 배포 전 차단한다. + +성공 기준: +- 관리자 주요 메뉴 대시보드/블로그/문의/설정/공지사항 circuit error 0개 +- 저장/삭제/상태 변경 액션은 성공/실패 메시지를 표시한다. + +Todo: +- [x] 중복 `/admin` 라우트 제거 +- [x] MudBlazor DI 타입 오류 수정 +- [x] 관리자 메뉴 smoke E2E 추가 +- [x] 설정 저장 TODO를 실제 DB 기반 기능으로 전환 + +--- + +## ── 고객지원 백오피스 (CRM) ────────────────────── + +> **배경**: 세무사 사무실에서 고객 정보와 상담 이력이 파편화(메모장·카톡·기억)되면 마감 누락, 서비스 연속성 단절, 재계약 기회 손실이 발생한다. +> 30년 경력 세무사가 혼자 또는 소수 인원으로 운영할 때 가장 먼저 필요한 것은 고객 카드와 상담 이력이다. + +## WBS-CRM-01 고객 카드 (Client Card) — Phase 1 + +목표: 고객별 기본 정보·서비스 유형·상태를 한 화면에서 관리한다. + +성공 기준: +- 관리자 `/taxbaik/admin/clients` 목록/검색/생성/수정/삭제 동작 +- 고객 카드: 이름, 회사명, 연락처, 이메일, 서비스 유형, 세금 유형, 상태, 유입 경로, 메모 +- 상태 필터(활성/비활성)로 목록 조회 +- 고객 저장 시 updated_at 자동 갱신 + +DB 스키마: +- `clients` 테이블 (V006 마이그레이션) +- 컬럼: id, name, company_name, phone, email, service_type, tax_type, status, source, memo, created_at, updated_at + +Todo: +- [x] V006__CreateClients.sql 마이그레이션 +- [x] Client 엔티티 (Domain) +- [x] IClientRepository 인터페이스 (Domain) +- [x] ClientRepository 구현 (Infrastructure) +- [x] ClientService 구현 (Application) +- [x] ClientList.razor 관리자 목록 화면 +- [x] ClientEdit.razor 관리자 등록/수정 화면 +- [x] MainLayout.razor 고객 메뉴 추가 +- [ ] 배포 후 고객 등록 → 목록 조회 확인 + +## WBS-CRM-02 상담 이력 (Consultation Log) — Phase 1 + +목표: 고객별 상담 일자·내용·결과·수수료를 기록해 "이 고객 지난번에 뭐 상담했더라?"를 해결한다. + +성공 기준: +- 고객 상세에서 상담 이력 목록/추가/삭제 동작 +- 상담 이력 필드: 날짜, 서비스 유형, 상담 요약, 결과(계약/보류/거절/완료), 수수료 +- 이력 없는 고객은 빈 목록 표시 + +DB 스키마: +- `consultations` 테이블 (V007 마이그레이션) +- 컬럼: id, client_id(FK), consultation_date, service_type, summary, result, fee, created_at + +Todo: +- [ ] V007__CreateConsultations.sql 마이그레이션 +- [ ] Consultation 엔티티 (Domain) +- [ ] IConsultationRepository 인터페이스 (Domain) +- [ ] ConsultationRepository 구현 (Infrastructure) +- [ ] ConsultationService 구현 (Application) +- [ ] ClientDetail.razor (고객 상세 + 상담 이력 탭) +- [ ] 배포 후 고객 상세에서 상담 이력 추가 확인 + +## WBS-CRM-03 문의 → 고객 전환 — Phase 1 + +목표: 홈페이지 문의 접수 건을 클릭 한 번으로 고객 카드로 등록한다. + +성공 기준: +- 문의 상세에 "고객으로 등록" 버튼 표시 +- 버튼 클릭 시 이름·연락처 자동 채워진 고객 생성 폼으로 이동 +- 이미 연결된 고객이 있으면 버튼 대신 고객 카드 링크 표시 +- inquiries 테이블에 client_id 컬럼 추가 + +Todo: +- [ ] inquiries 테이블에 client_id FK 컬럼 추가 (V008 마이그레이션) +- [ ] InquiryDetail.razor에 "고객으로 등록" 버튼 추가 +- [ ] ClientEdit.razor에 inquiry_id 파라미터 지원 (자동 채우기) +- [ ] 배포 후 문의 → 고객 전환 흐름 확인 + +--- + +## ── 고객지원 백오피스 Phase 2 ────────────────────── + +## WBS-CRM-04 신고 일정 캘린더 — Phase 2 + +목표: 고객별 신고 예정일과 마감일을 추적해 가산세 리스크를 방지한다. + +성공 기준: +- 관리자에서 고객별 세금 신고 일정 등록/수정/완료 처리 +- D-Day 표시 (D-7일 이내 강조) +- 이번 달 마감 목록을 대시보드 위젯으로 표시 + +DB 스키마: +- `tax_filings` 테이블 (V009 마이그레이션) +- 컬럼: id, client_id(FK), filing_type, due_date, status(pending/filed/overdue), memo + +Todo: +- [ ] V009__CreateTaxFilings.sql +- [ ] TaxFiling 엔티티, Repository, Service +- [ ] TaxFilingList.razor (관리자 신고 일정 화면) +- [ ] Dashboard.razor에 이번 달 마감 위젯 추가 +- [ ] 배포 후 신고 일정 등록 → D-Day 표시 확인 + +## WBS-CRM-05 문의 접수 현황 강화 — Phase 2 + +목표: 문의 상태를 세분화하고 담당자 메모를 기록해 처리 흐름을 추적한다. + +성공 기준: +- 문의 상태: 신규/상담중/계약완료/거절/종결 5단계 +- 목록에서 상태 칩 필터로 빠른 분류 +- 상태 변경 시 변경 일시 자동 기록 + +Todo: +- [ ] inquiries.status 컬럼 확장 (V010 마이그레이션) +- [ ] InquiryList.razor 상태 필터 추가 +- [ ] InquiryDetail.razor 상태 변경 버튼 추가 + +--- + +## ── 고객지원 백오피스 Phase 3 ────────────────────── + +## WBS-CRM-06 텔레그램 자동 리포트 — Phase 3 + +목표: 세무사에게 일/주 단위 신규 문의·처리 현황·마감 임박 건을 텔레그램으로 전송한다. + +성공 기준: +- 매일 오전 9시 신규 문의 수, 처리 대기 수 자동 전송 +- 매주 월요일 주간 리포트 (신규 고객, 이번 주 마감 신고 건) +- 텔레그램 전송 실패 시 로그만 남기고 앱 정상 운영 유지 + +Todo: +- [ ] BackgroundService 또는 Hangfire 기반 스케줄러 추가 +- [ ] 일간/주간 리포트 메시지 템플릿 +- [ ] TelegramNotificationService에 리포트 메서드 추가 + +## WBS-CRM-07 고객 포털 (읽기 전용) — Phase 3 + +목표: 기장 고객이 본인 신고 현황과 중요 알림을 직접 확인한다. + +성공 기준: +- 고객 전용 URL + 인증(단순 PIN 또는 링크 토큰) +- 본인 신고 일정, 상담 요약(세무사 허용 항목만) 조회 +- 개인정보 열람 범위는 세무사가 허용한 항목만 + +Todo: +- [ ] 고객 포털 설계 (인증 방식 결정) +- [ ] 고객 전용 Razor Pages 추가 +- [ ] 세무사 허용 권한 설정 UI + +--- + +## ── 유지보수성 ───────────────────────────────── + ## WBS-MAINT-01 유지보수성/파편화 축소 목표: 문서와 실제 구조의 불일치를 줄이고 단일 앱 운영 기준을 유지한다. -성공 기준: -- README/CLAUDE/DEPLOYMENT_GUIDE의 .NET 버전, 앱 구조, 테스트 기준이 실제 코드와 일치 -- 배포 문서에 Playwright 검증 절차 포함 -- 오래된 분리 Admin 서비스 문서 제거 또는 명확히 deprecated 처리 - Todo: - [x] README 테스트/배포 섹션 갱신 - [x] CLAUDE.md E2E 기준 갱신 - [x] 오래된 최종 보고 문서의 허위 완료 표현 정정 +- [x] CLAUDE.md 섹션 13 시즌별 마케팅 하네스 추가 + +--- ### 현재 검증 메모 -- `dotnet build TaxBaik.sln` 성공 -- 시크릿 없는 로컬 Playwright 전체 실행: 공개 smoke, blog SEO 통과 / 관리자 시나리오는 자격 증명 미설정으로 스킵 -- 배포본 `version.txt`: `8f0cb69` -- 배포본 블로그 상세: HTTP 200 -- CI Playwright 전체 통과는 최신 커밋 배포 후 재확인 필요 -- 비밀번호 변경 E2E는 배포 환경 자격 증명 확인 대기 + +- `dotnet build TaxBaik.sln` 성공 (2026-06-27 기준, 경고 0 오류 0) +- 배포 커밋: `77a5c44` (FAQ 섹션 추가, 푸시 대기 중) +- WBS-MKT-01/02/03 구현 완료, 배포 후 시각 검증 필요 +- WBS-CRM-01 구현 중 (Phase 1 고객 카드) +- WBS-CRM-02/03 Phase 1 구현 예정 (고객 카드 완료 후 순차 진행)