- FastAPI + SQLAlchemy(aiosqlite) 기반 SR 상태 머신 (RECEIVED → PARSED → PENDING_APPROVAL → APPROVED → IN_PROGRESS → PENDING_PM_VALIDATION → COMPLETED / FAILED_ROLLBACK) - PM 승인 워크플로우 (ApprovalFlow 테이블) - SHA-256 해시 체인 감사 로그 (위변조 방지) - AES-256-GCM 서버 자격증명 암호화 (IP/PW API 미노출) - CMDB: 기관(MOF/MOIS/MSS) + 서버 정보 관리 - 더미 데이터 자동 시딩 (6개 SR, 3개 기관, 6개 서버) - Dark-theme SPA: 대시보드 / 칸반 보드 / SR 목록 / 감사 로그 / CMDB Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
35 lines
1.2 KiB
Python
35 lines
1.2 KiB
Python
"""CMDB: Institution + Server management endpoints."""
|
|
from typing import List
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from database import get_db
|
|
from models import Institution, InstitutionOut, Server, ServerOut
|
|
|
|
router = APIRouter(prefix="/api/cmdb", tags=["cmdb"])
|
|
|
|
|
|
@router.get("/institutions", response_model=List[InstitutionOut])
|
|
async def list_institutions(db: AsyncSession = Depends(get_db)):
|
|
result = await db.execute(select(Institution).order_by(Institution.inst_name))
|
|
return result.scalars().all()
|
|
|
|
|
|
@router.get("/institutions/{inst_code}/servers", response_model=List[ServerOut])
|
|
async def list_servers(inst_code: str, db: AsyncSession = Depends(get_db)):
|
|
r = await db.execute(
|
|
select(Institution).where(Institution.inst_code == inst_code)
|
|
)
|
|
inst = r.scalars().first()
|
|
if not inst:
|
|
from fastapi import HTTPException
|
|
raise HTTPException(404, detail="기관을 찾을 수 없습니다.")
|
|
|
|
result = await db.execute(
|
|
select(Server).where(Server.inst_id == inst.id, Server.is_active == True)
|
|
.order_by(Server.server_name)
|
|
)
|
|
return result.scalars().all()
|