Files
dbx-main/app/modules/expense/__init__.py
T
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

36 lines
1.1 KiB
Python

"""개인경비(expense) 모듈.
라우터/저장소/템플릿을 한 디렉토리에서 관리한다.
- 라우터: `router.py` (FastAPI APIRouter, prefix=/expense)
- 저장소: `store.py` (DATA_DIR/expense.json, 향후 expense_db 후보)
- 템플릿: `templates/expense/index.html`
"""
from pathlib import Path
from typing import Any
from .router import router
from .store import CATEGORIES, METHODS, STATUSES, ExpenseStore
__all__ = [
"router",
"ExpenseStore",
"CATEGORIES",
"METHODS",
"STATUSES",
"build_expense_store",
]
def build_expense_store(*, dsn: str | None, json_path: Path) -> Any:
"""env 의 EXPENSE_DB_URL 이 있으면 DB 저장소, 없으면 JSON 저장소.
DB 저장소 실패(드라이버 미설치/접속 실패) 시 예외를 그대로 전파한다 —
의도치 않게 JSON 으로 폴백해 운영 데이터가 갈라지는 것을 막기 위함.
"""
if dsn:
from .db import ExpenseDBStore # 지연 import (개발 환경 deps 없을 수 있음)
return ExpenseDBStore(dsn)
return ExpenseStore(json_path)