Core modules: - Laws: CRUD, search, AI-powered QA - Analysis: legal research and case management - Contracts: lifecycle management with templates - Signatures: electronic signature workflow Infrastructure: - FastAPI + SQLite + async SQLAlchemy - Docker deployment support - 54 unit tests passing Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
132 lines
4.6 KiB
Python
132 lines
4.6 KiB
Python
"""Contract model."""
|
|
import enum
|
|
from datetime import date, datetime
|
|
from typing import Optional
|
|
|
|
from sqlalchemy import String, Text, Date, DateTime, Enum as SQLEnum, Integer, ForeignKey
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
|
|
from app.core.database import Base
|
|
|
|
|
|
class ContractStatus(str, enum.Enum):
|
|
"""Contract status enumeration."""
|
|
DRAFT = "draft"
|
|
PENDING_APPROVAL = "pending_approval"
|
|
APPROVED = "approved"
|
|
PENDING_SIGNATURE = "pending_signature"
|
|
SIGNED = "signed"
|
|
ARCHIVED = "archived"
|
|
REJECTED = "rejected"
|
|
|
|
|
|
class Contract(Base):
|
|
"""Contract model."""
|
|
|
|
__tablename__ = "contracts"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
|
template_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("contract_templates.id"), nullable=True)
|
|
title: Mapped[str] = mapped_column(String(200), index=True)
|
|
contract_number: Mapped[Optional[str]] = mapped_column(String(50), nullable=True)
|
|
party_a: Mapped[str] = mapped_column(String(100))
|
|
party_b: Mapped[str] = mapped_column(String(100))
|
|
content: Mapped[str] = mapped_column(Text)
|
|
status: Mapped[ContractStatus] = mapped_column(
|
|
SQLEnum(ContractStatus),
|
|
default=ContractStatus.DRAFT
|
|
)
|
|
effective_date: Mapped[Optional[date]] = mapped_column(Date, nullable=True)
|
|
expiry_date: Mapped[Optional[date]] = mapped_column(Date, nullable=True)
|
|
file_path: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
|
|
created_by: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"))
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
|
|
def __init__(
|
|
self,
|
|
title: str,
|
|
party_a: str,
|
|
party_b: str,
|
|
content: str,
|
|
created_by: int,
|
|
template_id: Optional[int] = None,
|
|
contract_number: Optional[str] = None,
|
|
status: ContractStatus = ContractStatus.DRAFT,
|
|
effective_date: Optional[date] = None,
|
|
expiry_date: Optional[date] = None,
|
|
file_path: Optional[str] = None,
|
|
**kwargs
|
|
):
|
|
self.title = title
|
|
self.party_a = party_a
|
|
self.party_b = party_b
|
|
self.content = content
|
|
self.created_by = created_by
|
|
self.template_id = template_id
|
|
self.contract_number = contract_number
|
|
self.status = status
|
|
self.effective_date = effective_date
|
|
self.expiry_date = expiry_date
|
|
self.file_path = file_path
|
|
self.created_at = datetime.utcnow()
|
|
self.updated_at = datetime.utcnow()
|
|
|
|
|
|
class ContractTemplate(Base):
|
|
"""Contract template model."""
|
|
|
|
__tablename__ = "contract_templates"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
|
name: Mapped[str] = mapped_column(String(100))
|
|
contract_type: Mapped[Optional[str]] = mapped_column(String(50), nullable=True)
|
|
content: Mapped[str] = mapped_column(Text)
|
|
variables: Mapped[Optional[dict]] = mapped_column(String, nullable=True) # JSON string
|
|
created_by: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"))
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
|
|
def __init__(
|
|
self,
|
|
name: str,
|
|
content: str,
|
|
created_by: int,
|
|
contract_type: Optional[str] = None,
|
|
variables: Optional[dict] = None,
|
|
**kwargs
|
|
):
|
|
self.name = name
|
|
self.content = content
|
|
self.created_by = created_by
|
|
self.contract_type = contract_type
|
|
self.variables = variables
|
|
self.created_at = datetime.utcnow()
|
|
|
|
|
|
class ContractApproval(Base):
|
|
"""Contract approval model."""
|
|
|
|
__tablename__ = "contract_approvals"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
|
contract_id: Mapped[int] = mapped_column(Integer, ForeignKey("contracts.id"), index=True)
|
|
approver_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), index=True)
|
|
status: Mapped[ContractStatus] = mapped_column(SQLEnum(ContractStatus))
|
|
comment: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
approved_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
|
|
|
|
def __init__(
|
|
self,
|
|
contract_id: int,
|
|
approver_id: int,
|
|
status: ContractStatus,
|
|
comment: Optional[str] = None,
|
|
**kwargs
|
|
):
|
|
self.contract_id = contract_id
|
|
self.approver_id = approver_id
|
|
self.status = status
|
|
self.comment = comment
|
|
self.created_at = datetime.utcnow()
|