# TaxBaik - 세무사 백원숙 전문성 표현 홈페이지 **온라인 세무 상담 플랫폼** | 블로그 SEO 최적화 | 전국 고객 확보 CI deploy trigger verification note. --- ## 개요 TaxBaik는 세무사 백원숙의 전문성을 온라인으로 표현하기 위해 설계된 풀스택 웹 애플리케이션입니다. ### 핵심 포지셔닝 > "사업자 세금 + 부동산 + 가족자산 = 맞춤형 세무 파트너" ### 전문가 자격 - 세무사 (세무 대리인, 기획세무사) - 부동산중개사 - 보험설계사 --- ## 기술 스택 | 계층 | 기술 | |-----|------| | **백엔드** | ASP.NET Core 10, C# | | **공개 사이트** | Razor Pages (SSR) | | **관리자** | Blazor Server + MudBlazor | | **데이터베이스** | PostgreSQL 18.4 | | **ORM** | Dapper | | **리버스 프록시** | Nginx | | **배포** | Gitea Actions CI/CD, systemd 단일 서비스 | | **아키텍처** | DDD (Domain-Driven Design), Layered Architecture | --- ## 프로젝트 구조 ``` TaxBaik/ ├── TaxBaik.Domain/ # 비즈니스 규칙, 엔티티, 인터페이스 ├── TaxBaik.Infrastructure/ # DB 접근, Dapper 구현체, 마이그레이션 ├── TaxBaik.Application/ # 서비스, DTO, 비즈니스 워크플로우 ├── TaxBaik.Web/ # Razor Pages + 관리자 통합 앱 (port 5001) ├── db/migrations/ # 데이터베이스 마이그레이션 SQL ├── deploy/ # systemd 서비스 파일, Nginx 설정 └── .gitea/workflows/ # CI/CD 파이프라인 ``` --- ## 주요 기능 ### 공개 사이트 (TaxBaik.Web) - **SEO 최적화 블로그** (5개 카테고리) - 사업자 세무 - 부동산 세금 - 종합소득세 - 부가가치세 - 가족자산·증여 - **온라인 상담 폼** - 이름, 연락처, 이메일 - 상담 분야 선택 - 문의 내용 - **반응형 디자인** - 모바일 우선 (375px+) - 데스크톱 최적화 - 접근성 고려 - **성능 최적화** - gzip 압축 - 이미지 lazy load - CSS/JS 최적화 ### 관리자 백오피스 (TaxBaik.Web 내 Blazor Server) - **대시보드** - 이번달 문의 수 - 신규 문의 수 - 포스트 통계 - **블로그 관리** - CRUD 기능 - 카테고리 관리 - SEO 메타데이터 - 발행/임시저장 - **문의 관리** - 문의 목록 - 상태 변경 (신규 → 연락함 → 완료) - 상세 보기 - **사이트 설정** - 연락처 정보 - 소셜 미디어 링크 --- ## 빠른 시작 ### 개발 환경 설정 **필수 요구사항:** - .NET 10.0 SDK - PostgreSQL 18.4 - Git **설정 단계:** ```bash # 1. 저장소 클론 git clone http://178.104.200.7/kjh2064/taxbaik.git cd taxbaik # 2. 데이터베이스 생성 createdb taxbaikdb psql -d taxbaikdb -f db/migrations/V001__InitialSchema.sql psql -d taxbaikdb -f db/migrations/V002__SeedData.sql psql -d taxbaikdb -f db/migrations/V003__SeedAdminAndBlogPosts.sql psql -d taxbaikdb -f db/migrations/V004__CreateSiteSettings.sql # 3. 환경 변수 설정 export ConnectionStrings__Default="Host=localhost;Database=taxbaikdb;Username=postgres;Password=password" # 4. 빌드 및 실행 dotnet build TaxBaik.sln dotnet run --project TaxBaik.Web # 5. 브라우저 열기 # 공개 사이트: http://localhost:5001/taxbaik # 관리자: http://localhost:5001/taxbaik/admin/login ``` ### 초기 로그인 정보 - **username**: `admin` - **password**: `` or current rotated admin password > ⚠️ **중요**: 프로덕션 배포 시 비밀번호 변경 필수이며, 검증용 비밀번호는 Gitea Secrets로 관리 --- ## 배포 ### 배포 방식 배포는 **Gitea Actions CI/CD**만 사용합니다. master 브랜치에 푸시하면 파이프라인이 다음 단계를 수행합니다. 1. .NET 빌드 (Release) 2. 단위 테스트 실행 3. Playwright 브라우저 검증 실행 4. `TaxBaik.Web` 게시 5. 원격 서버 배포 디렉토리 업로드 및 `taxbaik_active` 심링크 교체 6. systemd `taxbaik` 단일 서비스 재시작 7. `/taxbaik/`, `/taxbaik/admin/login`, `/taxbaik/blog/{slug}`, `/taxbaik/api/auth/login` 검증 배포 완료 판정은 위 단계가 모두 성공하고, 배포본 기준 Playwright E2E가 통과했을 때만 한다. **필수 Gitea Secrets 설정:** - `DEPLOY_USER`: kjh2064 - `DEPLOY_HOST`: 178.104.200.7 - `DEPLOY_SSH_KEY_B64`: base64로 인코딩한 SSH 개인키 - `TAXBAIK_ADMIN_TEST_PASSWORD`: 배포 검증용 관리자 비밀번호 - `Admin__PasswordResetToken`: 관리자 비밀번호 재설정 API용 서버 비밀값 배포는 Gitea Actions CI/CD로만 수행합니다. 수동 배포 경로는 CI 하네스로 차단되어 있으며, 실패 시 [DEPLOYMENT_GUIDE.md](./DEPLOYMENT_GUIDE.md)의 CI 점검 절차를 따릅니다. --- ## 개발 지침 ### 코드 컨벤션 모든 UI 문자열은 **한국어**로 작성합니다. ```csharp // ✅ Good public async Task SaveAsync() { ... } var message = "저장되었습니다."; // ❌ Bad public bool Save() { ... } var message = "Saved"; ``` ### SQL 쿼리 (Dapper) ```csharp // ✅ 파라미터화된 쿼리 (안전) await conn.QueryAsync( "SELECT * FROM blog_posts WHERE id = @Id", new { Id = id }); // ❌ 문자열 연결 금지 (SQL injection) var sql = "SELECT * FROM blog_posts WHERE id = " + id; ``` ### Repository 패턴 ```csharp public interface IBlogPostRepository { Task GetByIdAsync(int id); Task> GetPublishedAsync(); // ... } public class BlogPostRepository : IBlogPostRepository { private readonly IDbConnectionFactory _connectionFactory; public async Task GetByIdAsync(int id) { using var conn = _connectionFactory.CreateConnection(); return await conn.QueryFirstOrDefaultAsync(...); } } ``` ### 마이그레이션 ```sql -- db/migrations/V004__AddNewColumn.sql ALTER TABLE blog_posts ADD COLUMN status VARCHAR(50) DEFAULT 'draft'; ``` 마이그레이션은 자동으로 시작시 실행됩니다. --- ## 문제 해결 ### 마이그레이션 오류 ```bash # 마이그레이션 테이블 확인 SELECT * FROM schema_migrations; # 실패한 마이그레이션 롤백 (수동 실행 필요) psql -U taxbaik -d taxbaikdb -c "DELETE FROM schema_migrations WHERE version='004';" ``` ### 포트 충돌 ```bash # 포트 확인 lsof -i :5001 lsof -i :5001 # 프로세스 종료 kill -9 ``` ### 데이터베이스 연결 ```bash # 연결 테스트 psql -U taxbaik -d taxbaikdb -c "SELECT 1;" # 환경 변수 확인 echo $ConnectionStrings__Default ``` --- ## 문서 - [CLAUDE.md](./CLAUDE.md) - LLM 개발 지침 (9개 섹션) - [DEPLOYMENT_GUIDE.md](./DEPLOYMENT_GUIDE.md) - 배포 완전 가이드 - [SERVER_SETUP.sh](./SERVER_SETUP.sh) - 서버 자동 설치 스크립트 --- ## 연락처 - **전화**: 010-4122-8268 - **이메일**: taxbaik5668@gmail.com - **카카오 채널**: http://pf.kakao.com/_xoxchTX - **인스타그램**: https://www.instagram.com/taxtory5668/ --- ## 라이선스 내부 사용 전용 --- ## 개발 로그 ### W0 - 프로젝트 기반 구축 - ✅ Visual Studio 솔루션 + 5개 프로젝트 생성 - ✅ Git 초기화 및 Gitea 저장소 연결 - ✅ PostgreSQL 스키마 + 마이그레이션 파일 - ✅ Nginx 리버스 프록시 설정 ### W1 - LLM 개발 지침 - ✅ CLAUDE.md 작성 (9개 섹션, 500+ 라인) ### W2 - Domain/Infrastructure/Application - ✅ 엔티티: BlogPost, Category, Inquiry, AdminUser - ✅ Dapper Repository 패턴 구현 - ✅ 서비스 레이어 (BlogService, InquiryService) - ✅ DTO 및 예외 처리 ### W3 - 공개 홈페이지 (Razor Pages SSR) - ✅ 레이아웃 및 네비게이션 - ✅ 메인 랜딩 페이지 - ✅ 블로그 (목록 + 상세) - ✅ 문의 폼 (유효성 검증) - ✅ SEO 최적화 (메타 태그, sitemap.xml) - ✅ robots.txt ### W4 - 관리자 백오피스 (Blazor Server + MudBlazor) - ✅ 인증 (Cookie 기반, 8시간 세션) - ✅ 대시보드 (KPI 카드) - ✅ 블로그 CRUD - ✅ 문의 관리 - ✅ 사이트 설정 ### W5 - 스타일링 & 모바일 UX - ✅ CSS 디자인 시스템 (색상, 스페이싱, 전환) - ✅ 모바일 반응형 (375px 초소형 화면까지) - ✅ 성능 최적화 (gzip, lazy load, 폰트 preconnect) ### W6 - 출시 준비 - ✅ 자동 DB 마이그레이션 (MigrationRunner) - ✅ 초기 데이터 (관리자 + 블로그 5개 포스트) - ✅ E2E 테스트 절차 - ✅ 배포 가이드 - ✅ 서버 자동 설치 스크립트 - ✅ Gitea Actions CI/CD --- **최종 상태**: 진행 중 완료 판정은 실제 빌드, 테스트, 배포 검증, 브라우저 E2E 통과로만 한다.