feat(project): 아사나식 프로젝트 관리 모듈 추가

- project_db 신규(projects/members/stages/tasks/comments/activity, project_app CRUD)
- 프로젝트/서브프로젝트(self-FK), 업무·진행단계(칸반), 멤버 배정
- 메인 뷰 달력(FullCalendar)/타임라인(vis-timeline) 토글 + 보드/리스트
- 진입은 로그인 회사 직원 전원, 생성/배정은 관리자 전용
- 업무 배정·완료 시 관리자 메일 알림(app/mail.py, SMTP_* env, 미설정 시 skip)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-25 11:22:05 +09:00
parent 8d7fe01c2d
commit c192d61c71
14 changed files with 2404 additions and 1 deletions
+34
View File
@@ -0,0 +1,34 @@
"""프로젝트 관리(아사나식) 모듈.
라우터/저장소/템플릿을 한 디렉토리에서 관리한다(malaysia/dispatch 패턴).
- 라우터: `router.py` (FastAPI APIRouter, prefix=/project)
- 저장소: `db.py` (project_db / PostgreSQL 전용) + `store.py` (상수/순수 검증)
- 템플릿: `templates/project/`
- 메일: 전역 `app.mail.send_email` (업무 배정/완료 시 관리자 알림)
데이터 저장은 project_db 전용이다. PROJECT_DB_URL 미설정 시
build_project_store 는 None 을 반환하고, 라우터가 "설정 필요" 안내 페이지를
보여준다(앱은 죽지 않음).
권한: 로그인한 회사(dbxcorp.co.kr) 직원은 모듈 진입 가능. 프로젝트 생성/삭제·
사용자 배정은 ERP 관리자(is_admin)만. 배정된 멤버는 서브프로젝트/업무/단계 관리.
"""
from typing import Any
from . import store
from .router import router
__all__ = ["router", "store", "build_project_store"]
def build_project_store(*, dsn: str | None) -> Any:
"""PROJECT_DB_URL 이 있으면 ProjectStore, 없으면 None.
JSON 폴백을 두지 않는다(운영 데이터 분기 방지). None 이면 라우터가 안내 페이지 표시.
"""
if not dsn:
return None
from .db import ProjectStore # 지연 import (개발 환경 deps 없을 수 있음)
return ProjectStore(dsn)