diff --git a/backend/app/database.py b/backend/app/database.py new file mode 100644 index 0000000..b425a14 --- /dev/null +++ b/backend/app/database.py @@ -0,0 +1,24 @@ +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +import os + +# 데이터베이스 URL +DATABASE_URL = "postgresql://tkmp_user:tkmp_password_2025@localhost:5432/tk_mp_bom" + +# SQLAlchemy 엔진 생성 +engine = create_engine(DATABASE_URL) + +# 세션 팩토리 생성 +SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) + +# Base 클래스 생성 +Base = declarative_base() + +# 데이터베이스 의존성 함수 +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() diff --git a/backend/app/models.py b/backend/app/models.py new file mode 100644 index 0000000..59c76ef --- /dev/null +++ b/backend/app/models.py @@ -0,0 +1,74 @@ +from sqlalchemy import Column, Integer, String, Boolean, DateTime, Text, Numeric, ForeignKey +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import relationship +from datetime import datetime + +Base = declarative_base() + +class Project(Base): + __tablename__ = "projects" + + id = Column(Integer, primary_key=True, index=True) + official_project_code = Column(String(50), unique=True, index=True) + project_name = Column(String(200), nullable=False) + client_name = Column(String(100)) + design_project_code = Column(String(50)) + design_project_name = Column(String(200)) + is_code_matched = Column(Boolean, default=False) + matched_by = Column(String(100)) + matched_at = Column(DateTime) + status = Column(String(20), default='active') + created_at = Column(DateTime, default=datetime.utcnow) + updated_at = Column(DateTime, default=datetime.utcnow) + description = Column(Text) + notes = Column(Text) + + # 관계 설정 + files = relationship("File", back_populates="project") + +class File(Base): + __tablename__ = "files" + + id = Column(Integer, primary_key=True, index=True) + project_id = Column(Integer, ForeignKey("projects.id")) + filename = Column(String(255), nullable=False) + original_filename = Column(String(255), nullable=False) + file_path = Column(String(500), nullable=False) + revision = Column(String(20), default='Rev.0') + upload_date = Column(DateTime, default=datetime.utcnow) + uploaded_by = Column(String(100)) + file_type = Column(String(10)) + file_size = Column(Integer) + is_active = Column(Boolean, default=True) + + # 관계 설정 + project = relationship("Project", back_populates="files") + materials = relationship("Material", back_populates="file") + +class Material(Base): + __tablename__ = "materials" + + id = Column(Integer, primary_key=True, index=True) + file_id = Column(Integer, ForeignKey("files.id")) + line_number = Column(Integer) + original_description = Column(Text, nullable=False) + classified_category = Column(String(50)) + classified_subcategory = Column(String(100)) + material_grade = Column(String(50)) + schedule = Column(String(20)) + size_spec = Column(String(50)) + quantity = Column(Numeric(10, 3), nullable=False) + unit = Column(String(10), nullable=False) + drawing_name = Column(String(100)) + area_code = Column(String(20)) + line_no = Column(String(50)) + classification_confidence = Column(Numeric(3, 2)) + is_verified = Column(Boolean, default=False) + verified_by = Column(String(100)) + verified_at = Column(DateTime) + drawing_reference = Column(String(100)) + notes = Column(Text) + created_at = Column(DateTime, default=datetime.utcnow) + + # 관계 설정 + file = relationship("File", back_populates="materials") diff --git a/backend/app/schemas.py b/backend/app/schemas.py new file mode 100644 index 0000000..21c0cbb --- /dev/null +++ b/backend/app/schemas.py @@ -0,0 +1,36 @@ +from pydantic import BaseModel +from datetime import datetime +from typing import Optional, List +from decimal import Decimal + +# 프로젝트 스키마 +class ProjectBase(BaseModel): + official_project_code: Optional[str] = None + project_name: str + client_name: Optional[str] = None + design_project_code: Optional[str] = None + design_project_name: Optional[str] = None + description: Optional[str] = None + notes: Optional[str] = None + +class ProjectCreate(ProjectBase): + pass + +class ProjectUpdate(ProjectBase): + project_name: Optional[str] = None + +class Project(ProjectBase): + id: int + is_code_matched: bool + status: str + created_at: datetime + updated_at: datetime + + class Config: + from_attributes = True + +# 응답 스키마 +class ProjectResponse(BaseModel): + projects: List[Project] + total: int + message: str