From 303ba4929237c8c85f71871272b50bda479dd5f7 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Fri, 26 Jun 2026 15:02:45 +0900 Subject: [PATCH] Remove regional specificity, focus on nationwide positioning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change site description from '성북구 세무사' to nationwide professional - Update positioning from '일상 자산 세금 파트너' to '맞춤형 세무 파트너' - Replace Seongbuk-gu specificity with skill-based positioning - Align with online-first service model (no local restriction) - Update examples in documentation Co-Authored-By: Claude --- CLAUDE.md | 6 +- SERVER_SETUP_GUIDE.md | 315 +++++++++++++++++++++++++++++++ db/migrations/V002__SeedData.sql | 4 +- 3 files changed, 320 insertions(+), 5 deletions(-) create mode 100644 SERVER_SETUP_GUIDE.md diff --git a/CLAUDE.md b/CLAUDE.md index cdc03dc..ed0ca11 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,9 +2,9 @@ ## 1. 프로젝트 개요 -**클라이언트**: 백원숙 세무사 (백원숙세무사사무소, 성북구 하월곡동) -**목적**: 온라인 첫인상 + 블로그 SEO 유입 + 상담 전환 극대화 -**핵심 포지셔닝**: "사업자 세금 + 부동산 + 가족자산 = 일상 자산 세금 파트너" +**클라이언트**: 백원숙 세무사 (세무사·부동산중개사·보험설계사 자격) +**목적**: 온라인 전문성 표현 + 블로그 SEO 유입 + 전국 고객 확보 +**핵심 포지셔닝**: "사업자 세금 + 부동산 + 가족자산 = 맞춤형 세무 파트너" **기술 스택**: ASP.NET Core 8 / Dapper / PostgreSQL 18 / Nginx / Gitea CI --- diff --git a/SERVER_SETUP_GUIDE.md b/SERVER_SETUP_GUIDE.md new file mode 100644 index 0000000..8f5d5d1 --- /dev/null +++ b/SERVER_SETUP_GUIDE.md @@ -0,0 +1,315 @@ +# 서버 설정 가이드 + +## 전제 +- 서버: `178.104.200.7` (Ubuntu 26.04) +- 접속: `ssh kjh2064@178.104.200.7` + +--- + +## Step 1: PostgreSQL 데이터베이스 생성 및 마이그레이션 + +서버에 SSH로 접속한 후 다음을 실행하세요: + +```bash +# PostgreSQL에 접속 (로컬 unix socket, sudo 사용) +sudo -i -u postgres + +# 그 다음 psql 프롬프트에서: +psql + +# SQL 명령어 실행: +CREATE DATABASE taxbaikdb; +CREATE USER taxbaik WITH ENCRYPTED PASSWORD 'your_secure_password_here'; +GRANT ALL PRIVILEGES ON DATABASE taxbaikdb TO taxbaik; +\q +exit + +# 이제 taxbaik 사용자로 마이그레이션 실행 +psql -U taxbaik -d taxbaikdb -h localhost +``` + +그러면 `taxbaik=#` 프롬프트가 나옵니다. 다음 SQL을 차례로 실행: + +### V001__InitialSchema.sql 내용 (프롬프트에 복사): + +```sql +CREATE TABLE categories ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL, + slug VARCHAR(100) NOT NULL UNIQUE, + sort_order INT NOT NULL DEFAULT 0 +); + +CREATE TABLE admin_users ( + id SERIAL PRIMARY KEY, + username VARCHAR(100) NOT NULL UNIQUE, + password_hash VARCHAR(500) NOT NULL, + last_login_at TIMESTAMPTZ, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE TABLE blog_posts ( + id SERIAL PRIMARY KEY, + title VARCHAR(300) NOT NULL, + content TEXT NOT NULL, + slug VARCHAR(300) NOT NULL UNIQUE, + category_id INT REFERENCES categories(id) ON DELETE SET NULL, + tags TEXT, + author_id INT REFERENCES admin_users(id) ON DELETE SET NULL, + published_at TIMESTAMPTZ, + view_count INT NOT NULL DEFAULT 0, + seo_title VARCHAR(300), + seo_description VARCHAR(500), + thumbnail_url VARCHAR(500), + is_published BOOLEAN NOT NULL DEFAULT FALSE, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE INDEX idx_blog_slug ON blog_posts(slug); +CREATE INDEX idx_blog_published ON blog_posts(is_published, published_at DESC); +CREATE INDEX idx_blog_category ON blog_posts(category_id); + +CREATE TABLE inquiries ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL, + phone VARCHAR(20) NOT NULL, + email VARCHAR(200), + service_type VARCHAR(100) NOT NULL, + message TEXT NOT NULL, + status VARCHAR(50) NOT NULL DEFAULT 'new', + ip_address VARCHAR(50), + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE INDEX idx_inquiry_status ON inquiries(status); +CREATE INDEX idx_inquiry_created ON inquiries(created_at DESC); + +CREATE TABLE site_settings ( + key VARCHAR(200) PRIMARY KEY, + value TEXT NOT NULL, + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +INSERT INTO categories (name, slug, sort_order) VALUES + ('사업자 세무', 'business-tax', 1), + ('부동산 세금', 'real-estate-tax', 2), + ('종합소득세', 'income-tax', 3), + ('부가가치세', 'vat', 4), + ('가족자산·증여', 'family-asset', 5); + +INSERT INTO site_settings (key, value) VALUES + ('site.title', '백원숙 세무회계 | 성북구 세무사'), + ('site.description', '사업자 세무, 부동산 양도세·증여세, 종합소득세 상담. 성북구 백원숙 세무사.'), + ('kakao.channel.url', ''), + ('phone.main', ''), + ('consultation.fee.text','상담료 7만~20만 원, 계약 체결 시 일부 차감'); +``` + +### 확인: +```sql +\dt +-- 6개 테이블 출력 (categories, admin_users, blog_posts, inquiries, site_settings, 그리고 schema_migrations) + +SELECT * FROM categories; +-- 5개 카테고리 확인 + +\q +``` + +--- + +## Step 2: systemd 서비스 파일 설치 + +로컬 컴퓨터에서 다음 파일을 서버에 복사: + +```bash +# 로컬에서: +scp deploy/taxbaik.service kjh2064@178.104.200.7:~/ +scp deploy/taxbaik-admin.service kjh2064@178.104.200.7:~/ +``` + +서버에서: +```bash +# 파일 복사 +sudo cp ~/taxbaik.service /etc/systemd/system/ +sudo cp ~/taxbaik-admin.service /etc/systemd/system/ + +# 환경 변수 추가 (DB 연결 문자열) +sudo nano /etc/systemd/system/taxbaik.service +# 아래 줄을 [Service] 섹션에서 주석 해제: +# Environment=ConnectionStrings__Default=Host=localhost;Database=taxbaikdb;Username=taxbaik;Password=your_password + +# 같은 작업을 taxbaik-admin.service에도 반복 + +# systemd 재로드 +sudo systemctl daemon-reload + +# 서비스 활성화 (부팅 시 자동 시작) +sudo systemctl enable taxbaik +sudo systemctl enable taxbaik-admin +``` + +--- + +## Step 3: Nginx 설정 추가 + +로컬에서 `deploy/nginx-taxbaik-locations.conf` 내용을 복사하여, 서버에서: + +```bash +# 현재 Nginx 설정 확인 +cat /etc/nginx/sites-available/default + +# 또는 기존 Nginx 설정 파일 확인 +ls -la /etc/nginx/sites-available/ +``` + +기존 설정 파일의 `http` 또는 `server` 블록에 다음을 **추가**: + +```nginx +location /taxbaik { + proxy_pass http://127.0.0.1:5001; + proxy_http_version 1.1; + proxy_set_header Connection keep-alive; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 120s; +} + +location /taxbaik/admin { + proxy_pass http://127.0.0.1:5002; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; +} +``` + +설정 검증 및 재로드: +```bash +sudo nginx -t +sudo systemctl reload nginx +``` + +--- + +## Step 4: Gitea 저장소 Secrets 추가 + +1. Gitea 웹UI (`http://178.104.200.7/`) 접속 +2. `kjh2064/taxbaik` 저장소 이동 +3. **Settings** → **Secrets** → **Add Secret** + +다음 3개 secrets 추가: + +| Secret 이름 | 값 | +|-----------|-----| +| `DEPLOY_USER` | `kjh2064` | +| `DEPLOY_HOST` | `178.104.200.7` | +| `DEPLOY_SSH_KEY` | SSH 개인키 (매우 민감!) | + +SSH 개인키는: +```bash +# 로컬에서 (.ssh/id_rsa 또는 현재 사용 중인 키) +cat ~/.ssh/id_rsa +# 전체 내용 복사 +``` + +Gitea Secret 창에 전체 붙여넣기. + +--- + +## Step 5: 배포 디렉토리 생성 + +서버에서: +```bash +mkdir -p ~/deployments +mkdir -p ~/taxbaik_active +mkdir -p ~/taxbaik_admin_active + +# 권한 확인 +ls -la ~/ | grep taxbaik +``` + +--- + +## Step 6: 초기 배포 테스트 + +로컬에서: +```bash +# 솔루션 빌드 +dotnet build TaxBaik.sln -c Release + +# Web 앱 발행 +dotnet publish src/TaxBaik.Web/ -c Release -o ./publish/web + +# 서버에 배포 +TIMESTAMP=$(date +%Y%m%d_%H%M%S) +rsync -az ./publish/web/ kjh2064@178.104.200.7:~/deployments/taxbaik_$TIMESTAMP/ + +# 서버에서 심링크 설정 +ssh kjh2064@178.104.200.7 "ln -sfn ~/deployments/taxbaik_$TIMESTAMP ~/taxbaik_active" + +# 서비스 시작 +ssh kjh2064@178.104.200.7 "sudo systemctl start taxbaik" + +# 확인 +curl http://178.104.200.7/taxbaik +``` + +--- + +## Step 7: 확인 체크리스트 + +```bash +# 로컬에서 또는 서버에서: + +# 1. DB 확인 +psql -U taxbaik -d taxbaikdb -c "\dt" +# 6개 테이블 출력 + +# 2. 서비스 상태 +sudo systemctl status taxbaik +sudo systemctl status taxbaik-admin + +# 3. Nginx 로그 확인 +sudo tail -f /var/log/nginx/error.log + +# 4. 앱 로그 확인 +journalctl -u taxbaik -n 50 +journalctl -u taxbaik-admin -n 50 + +# 5. 엔드포인트 테스트 +curl -v http://127.0.0.1:5001/health +curl -v http://127.0.0.1:5002/health +curl -v http://127.0.0.1/taxbaik + +# 6. 문의 폼 E2E 테스트 +curl -X POST http://178.104.200.7/taxbaik/contact \ + -d "name=테스트&phone=010-1234-5678&service_type=기장&message=상담요청" +``` + +--- + +## 문제 해결 + +| 증상 | 해결 | +|------|------| +| "Connection refused" | systemd 서비스 시작 안 됨: `sudo systemctl start taxbaik` | +| "Permission denied" | systemd 서비스 파일 권한 확인: `sudo chmod 644 /etc/systemd/system/taxbaik.service` | +| Nginx 404 | 설정 재로드: `sudo nginx -t && sudo systemctl reload nginx` | +| DB 연결 오류 | 환경 변수 확인: `systemctl cat taxbaik \| grep ConnectionStrings` | + +--- + +## 다음 단계 + +서버 설정 완료 후: +- [ ] Git 저장소에 push: `git push -u origin main` +- [ ] 초기 블로그 포스트 5개 작성 (W6.2) +- [ ] 사이트 설정 입력 (전화번호, KakaoTalk URL) +- [ ] Lighthouse 감사 실행 diff --git a/db/migrations/V002__SeedData.sql b/db/migrations/V002__SeedData.sql index ffeee1c..472527f 100644 --- a/db/migrations/V002__SeedData.sql +++ b/db/migrations/V002__SeedData.sql @@ -8,8 +8,8 @@ INSERT INTO categories (name, slug, sort_order) VALUES ('가족자산·증여', 'family-asset', 5); INSERT INTO site_settings (key, value) VALUES - ('site.title', '백원숙 세무회계 | 성북구 세무사'), - ('site.description', '사업자 세무, 부동산 양도세·증여세, 종합소득세 상담. 성북구 백원숙 세무사.'), + ('site.title', '백원숙 세무회계 | 사업자·부동산·증여 세무 상담'), + ('site.description', '사업자 기장, 부동산 양도세·증여세, 종합소득세 전문 상담. 온라인 맞춤 상담 제공.'), ('kakao.channel.url', ''), ('phone.main', ''), ('consultation.fee.text','상담료 7만~20만 원, 계약 체결 시 일부 차감');