Files
delphi-database/app/models/templates.py
2025-08-15 17:19:51 -05:00

99 lines
3.4 KiB
Python

"""
Document Template and Version models
"""
from sqlalchemy import Column, Integer, String, Text, ForeignKey, Boolean, UniqueConstraint
from sqlalchemy.orm import relationship
from app.models.base import BaseModel
class DocumentTemplate(BaseModel):
"""
High-level template metadata and current version pointer.
"""
__tablename__ = "document_templates"
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
name = Column(String(200), unique=True, nullable=False, index=True)
description = Column(Text)
category = Column(String(100), index=True, default="GENERAL")
active = Column(Boolean, default=True, nullable=False)
# Creator username (optional)
created_by = Column(String(150), ForeignKey("users.username"), nullable=True)
# Pointer to the currently-approved version
current_version_id = Column(Integer, ForeignKey("document_template_versions.id", use_alter=True), nullable=True)
# Relationships
current_version = relationship(
"DocumentTemplateVersion",
foreign_keys=[current_version_id],
post_update=True,
primaryjoin="DocumentTemplate.current_version_id==DocumentTemplateVersion.id",
uselist=False,
)
versions = relationship(
"DocumentTemplateVersion",
back_populates="template",
cascade="all, delete-orphan",
order_by="desc(DocumentTemplateVersion.created_at)",
foreign_keys="DocumentTemplateVersion.template_id",
)
keywords = relationship(
"TemplateKeyword",
back_populates="template",
cascade="all, delete-orphan",
order_by="asc(TemplateKeyword.keyword)",
foreign_keys="TemplateKeyword.template_id",
)
class DocumentTemplateVersion(BaseModel):
"""
Template binary version metadata and storage location
"""
__tablename__ = "document_template_versions"
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
template_id = Column(Integer, ForeignKey("document_templates.id"), nullable=False, index=True)
semantic_version = Column(String(50), nullable=False, index=True) # e.g., 1.0.0
storage_path = Column(String(512), nullable=False) # local path or S3 URI
mime_type = Column(String(100), nullable=False)
size = Column(Integer, nullable=False, default=0)
checksum = Column(String(64), nullable=False) # sha256 hex
changelog = Column(Text)
created_by = Column(String(150), ForeignKey("users.username"), nullable=True)
is_approved = Column(Boolean, default=True, nullable=False)
# Relationships
template = relationship(
"DocumentTemplate",
back_populates="versions",
foreign_keys=[template_id],
primaryjoin="DocumentTemplateVersion.template_id==DocumentTemplate.id",
)
class TemplateKeyword(BaseModel):
"""
Keyword/tag assigned to a DocumentTemplate.
"""
__tablename__ = "template_keywords"
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
template_id = Column(Integer, ForeignKey("document_templates.id"), nullable=False, index=True)
keyword = Column(String(100), nullable=False, index=True)
__table_args__ = (
UniqueConstraint("template_id", "keyword", name="uq_template_keyword"),
)
template = relationship(
"DocumentTemplate",
back_populates="keywords",
foreign_keys=[template_id],
primaryjoin="TemplateKeyword.template_id==DocumentTemplate.id",
)