feat(528): 신규 프로젝트 그룹 공통 백엔드 — 종류 칸 · 산림청 판정 · D01 · E01 생성 API · 공유 GET 만 · 가입 go.kr = 산림청
- DB 020(추가만): projects 종류 · 사업연도 끝 · 설계속도 · 원본 칸 · plan_route_years · plan_route_assignees · 회사 「산림청」 행 - is_forest_email · is_forest_service · /api/auth/session 에 is_forest_service - require_project_access 한 곳 — 지정 회사 = GET · HEAD 만 · 그 밖 403 - POST /api/d01/project(산림청만 · PLAN · 설계속도 기본 = resolve_design_speed) · GET /api/dashboard/plan-routes/assigned - GET /api/e01/source-candidates · POST /api/e01/project(B06 완료만 · STABILITY · 원본 칸 · 자료 복사는 528-4) - 종류별 단계 시드(PLAN 3 · STABILITY 4) · storage 허용 D0x · E0x · B01 목록에 project_kind - 가입 인증 — 메일 *.go.kr = 회사 산림청 · ACTIVE · 화면 회사 칸 「산림청」 잠금 표시 - 지킴 시험 test_528_project_groups.py Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -148,6 +148,16 @@ async def get_optional_session(request: Request) -> dict[str, Any] | None:
|
||||
return None
|
||||
|
||||
|
||||
def is_forest_email(email: str | None) -> bool:
|
||||
"""메일이 *.go.kr(대소문자 무시) — 가입 때 회사 「산림청」 고정."""
|
||||
return bool(email) and email.strip().lower().endswith(".go.kr")
|
||||
|
||||
|
||||
def is_forest_service(session: dict[str, Any]) -> bool:
|
||||
"""산림청 = 시스템관리자 또는 메일 *.go.kr — 예정노선 생성 · 고침 권한."""
|
||||
return session.get("role") == "SYSTEM_ADMIN" or is_forest_email(session.get("email"))
|
||||
|
||||
|
||||
async def require_master(session: dict[str, Any] = Depends(verify_session)) -> dict[str, Any]:
|
||||
if not session["is_master"] and session["role"] != "SYSTEM_ADMIN":
|
||||
raise HTTPException(status_code=403, detail="마스터 권한이 필요합니다.")
|
||||
@@ -196,6 +206,19 @@ async def require_project_access(
|
||||
)
|
||||
row = await cursor.fetchone()
|
||||
|
||||
if row and row[0] != session["company_id"]:
|
||||
# 예정노선을 지정받은 회사 = 보기만(요구 345 · GET 만 통과).
|
||||
await cursor.execute(
|
||||
"SELECT 1 FROM plan_route_assignees"
|
||||
" WHERE project_id = %s AND company_id = %s LIMIT 1",
|
||||
(str(project_id), session["company_id"]),
|
||||
)
|
||||
shared = await cursor.fetchone()
|
||||
if shared:
|
||||
if request.method in ("GET", "HEAD"):
|
||||
return session
|
||||
raise HTTPException(status_code=403, detail="보기만 허용된 예정노선입니다.")
|
||||
|
||||
if not row:
|
||||
raise HTTPException(status_code=404, detail="프로젝트를 찾을 수 없습니다.")
|
||||
if row[0] != session["company_id"]:
|
||||
|
||||
Reference in New Issue
Block a user