from fastapi import FastAPI, UploadFile, File, Form from fastapi.middleware.cors import CORSMiddleware from sqlalchemy import text from .database import get_db from sqlalchemy.orm import Session from fastapi import Depends from typing import Optional, List, Dict import os import shutil # 설정 및 로깅 import from .config import get_settings from .utils.logger import get_logger from .utils.error_handlers import setup_error_handlers # 설정 로드 settings = get_settings() # 로거 설정 logger = get_logger(__name__) # FastAPI 앱 생성 app = FastAPI( title=settings.app_name, description="자재 분류 및 프로젝트 관리 시스템", version=settings.app_version, debug=settings.debug ) # 에러 핸들러 설정 setup_error_handlers(app) # CORS 설정 (환경별 분리) cors_config = settings.get_cors_config() app.add_middleware( CORSMiddleware, **cors_config ) logger.info(f"CORS origins configured for {settings.environment}: {settings.security.cors_origins}") # 라우터들 import 및 등록 try: from .routers import files app.include_router(files.router, prefix="/files", tags=["files"]) except ImportError: logger.warning("files 라우터를 찾을 수 없습니다") try: from .routers import jobs app.include_router(jobs.router, prefix="/jobs", tags=["jobs"]) except ImportError: logger.warning("jobs 라우터를 찾을 수 없습니다") try: from .routers import purchase app.include_router(purchase.router, tags=["purchase"]) except ImportError: logger.warning("purchase 라우터를 찾을 수 없습니다") try: from .routers import material_comparison app.include_router(material_comparison.router, tags=["material-comparison"]) except ImportError: logger.warning("material_comparison 라우터를 찾을 수 없습니다") try: from .routers import tubing app.include_router(tubing.router, prefix="/tubing", tags=["tubing"]) except ImportError: logger.warning("tubing 라우터를 찾을 수 없습니다") # 파일 관리 API 라우터 등록 try: from .api import file_management app.include_router(file_management.router, tags=["file-management"]) logger.info("파일 관리 API 라우터 등록 완료") except ImportError as e: logger.warning(f"파일 관리 라우터를 찾을 수 없습니다: {e}") # 인증 API 라우터 등록 try: from .auth import auth_router app.include_router(auth_router, prefix="/auth", tags=["authentication"]) logger.info("인증 API 라우터 등록 완료") except ImportError as e: logger.warning(f"인증 라우터를 찾을 수 없습니다: {e}") # 프로젝트 관리 API (비활성화 - jobs 테이블 사용) # projects 테이블은 더 이상 사용하지 않음 # ): # """프로젝트 수정""" # try: # update_query = text(""" # UPDATE projects # SET project_name = :project_name, status = :status # WHERE id = :project_id # """) # # db.execute(update_query, { # "project_id": project_id, # "project_name": project_data["project_name"], # "status": project_data["status"] # }) # # db.commit() # return {"success": True} # except Exception as e: # db.rollback() # return {"error": f"프로젝트 수정 실패: {str(e)}"} # @app.delete("/projects/{project_id}") # async def delete_project( # project_id: int, # db: Session = Depends(get_db) # ): # """프로젝트 삭제""" # try: # delete_query = text("DELETE FROM projects WHERE id = :project_id") # db.execute(delete_query, {"project_id": project_id}) # db.commit() # return {"success": True} # except Exception as e: # db.rollback() # return {"error": f"프로젝트 삭제 실패: {str(e)}"} @app.get("/") async def root(): return { "message": "TK-MP BOM Management API", "version": "1.0.0", "endpoints": ["/docs", "/jobs", "/files", "/projects"] } # Jobs API # @app.get("/jobs") # async def get_jobs(db: Session = Depends(get_db)): # """Jobs 목록 조회""" # try: # # jobs 테이블에서 데이터 조회 # query = text(""" # SELECT # job_no, # job_name, # client_name, # end_user, # epc_company, # status, # created_at # FROM jobs # WHERE is_active = true # ORDER BY created_at DESC # """) # # result = db.execute(query) # jobs = result.fetchall() # # return [ # { # "job_no": job.job_no, # "job_name": job.job_name, # "client_name": job.client_name, # "end_user": job.end_user, # "epc_company": job.epc_company, # "status": job.status or "진행중", # "created_at": job.created_at # } # for job in jobs # ] # except Exception as e: # print(f"Jobs 조회 에러: {str(e)}") # return {"error": f"Jobs 조회 실패: {str(e)}"} # 파일 업로드는 /files/upload 엔드포인트를 사용하세요 (routers/files.py) # parse_file과 classify_material_item 함수는 routers/files.py로 이동되었습니다 @app.get("/health") async def health_check(): return {"status": "healthy", "timestamp": "2024-07-15"} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)