Files
dbx-main/docs/SERVER_ARCHITECTURE.md
king 9c58b022e2 feat(expense): 개인경비 모듈 + ERP 좌측메뉴 셸 + expense_db 연결
- ERP 셸: 좌측 사이드바 + 상단 헤더 + 콘텐츠 영역(erp_base.html)
- 분기: 슈퍼관리자 → 업무모듈 카드, 일반사용자 → ERP 메인(erp_home.html)
- 신규 라우트: /modules (슈퍼관리자 모듈 카드 재진입)
- 개인경비 모듈: app/modules/expense/ (라우터/저장소/템플릿)
  - JSON 저장소(ExpenseStore) + PostgreSQL 저장소(ExpenseDBStore)
  - 팩토리: EXPENSE_DB_URL 있으면 DB, 없으면 JSON 폴백
- DB: scripts/sql/expense_db_init.sql (멱등 DDL, postgres-db 컨테이너)
  - expense_db, 역할 expense_app, 테이블 expense_items, 인덱스/트리거
- 마이그레이션: scripts/migrate_expense_json_to_db.py (멱등, --dry-run)
- 의존성: psycopg[binary,pool]>=3.2
- 환경변수: EXPENSE_DB_URL 추가
- 문서: CLAUDE.md 작업 기준 + docs/{PROJECT_OVERVIEW,SERVER_ARCHITECTURE,DATABASES,DEPLOYMENT}.md
  - main-app 배포 경로 /opt/www/main 고정 명시
  - 위험 명령(DROP/TRUNCATE/rm -rf/volume 삭제) 사용자 승인 정책
2026-05-29 02:21:03 +09:00

91 lines
2.7 KiB
Markdown

# Server Architecture
## 전체 구성도
```text
[Windows 개발 PC]
│ Git push / 파일 수정
[Gitea Repository] (https://gitea.no1king.freeddns.org/king/dbx-main.git)
│ git pull
[Ubuntu Server / Proxmox VM]
├─ Nginx Proxy Manager (NPM)
│ dbx.no1king.freeddns.org → http://192.168.0.194:80
├─ Docker
│ ├─ main-app 컨테이너 (FastAPI / Uvicorn)
│ ├─ PostgreSQL 컨테이너
│ └─ 기타 부속 컨테이너
└─ PostgreSQL Databases
├─ itemcode_db
├─ orderlist_db
└─ return_db
```
---
## 요청 흐름
1. 사용자 브라우저 → `https://dbx.no1king.freeddns.org`
2. NPM(외부 HTTPS) → 내부 HTTP `192.168.0.194:80`
3. 서버 내부 Nginx/Compose 포워딩 → `main-app` 컨테이너 (FastAPI)
4. FastAPI → PostgreSQL 컨테이너(같은 Docker 네트워크) 또는 외부 쇼핑몰/택배 API
---
## 구성요소
| 구성요소 | 설명 |
| --- | --- |
| **Ubuntu Server** | 호스트 OS. 도커 호스트. systemd로 docker.service 관리 |
| **Docker** | 모든 앱·DB는 컨테이너로 운영. Compose 파일 단위 배포 |
| **PostgreSQL** | Docker 컨테이너에서 운영. 데이터는 named volume |
| **Nginx Proxy Manager** | 외부 HTTPS 종단, 인증서 자동 갱신, 호스트명 라우팅 |
| **FastAPI (main-app)** | 메인 ERP 백엔드. 인증·라우팅·외부 API 연동 |
| **Gitea** | 소스 저장소(사내 호스팅) |
---
## 네트워크 / 포트
| 항목 | 값 |
| --- | --- |
| 외부 도메인 | `dbx.no1king.freeddns.org` (HTTPS, NPM 종단) |
| 내부 호스트 | `192.168.0.194` |
| 내부 노출 포트 | `80` (NPM → 컨테이너) |
| 로컬 개발 포트 | `8080` |
| PostgreSQL | Docker 내부 네트워크에서만 접근 (호스트 노출 금지 권장) |
---
## 배포 경로
운영 서버 기준, 아래 중 하나에 클론한다. 상세는 `DEPLOYMENT.md`.
- `/opt/dbx-corm`
- `/opt/dbx-orderlist`
- `/opt/www/main`
> 같은 호스트에 여러 서비스를 운영하므로, 경로는 서비스별로 분리한다.
---
## 인증 흐름
1. 사용자가 `/auth/google` 진입 → Google OAuth 동의 화면
2. 콜백에서 `id_token` 검증 (`hd=dbxcorp.co.kr` 힌트는 참고용)
3. 서버에서 이메일 도메인 + `ALLOWED_EMAILS` 화이트리스트 검사
4. 통과 시 세션 쿠키 발급(`SESSION_SECRET_KEY` 서명)
---
## 운영 시 점검 포인트
- NPM 호스트 매핑이 살아있는가 (`dbx.no1king.freeddns.org → 192.168.0.194:80`)
- `docker compose ps``main-app`, `postgres` 컨테이너 상태
- PostgreSQL volume 마운트 경로와 백업 위치
- `.env` 값 유실 여부 (특히 `GOOGLE_CLIENT_*`, `SESSION_SECRET_KEY`)