feat(files): upload/preview/delete allegati su fatture, ULA, documenti
- models: colonne file inline (storage_path, mime, size_bytes, sha256, uploaded_by, uploaded_at) su remission_invoice, remission_ula_employee, remission_document - migrations: ALTER idempotente al lifespan per evolvere schema in sandbox - storage: FS adapter /var/uploads con validazione MIME/size, dedup sha256, sanitize - routers/files: POST upload / GET download (con ?inline=1) / DELETE matrix autorizzazioni: beneficiary su DRAFT|AWAITING_AMENDMENT, istruttore read-only, superadmin full - main: include router files, version bump 0.2.0 Testato E2E con admin JWT: upload 549B PDF -> DB coerente, storage 1/invoice/<uuid>/<sha12>-file.pdf, download con magic bytes PDF corretti, delete chirurgico con cleanup FS e metadata.
This commit is contained in:
@@ -4,7 +4,7 @@ Schema: gepafin_rendic (stesso DB del BE Gepafin sandbox).
|
||||
"""
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey, UniqueConstraint, Numeric, Boolean, Date
|
||||
from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey, UniqueConstraint, Numeric, Boolean, Date, BigInteger
|
||||
from sqlalchemy.dialects.postgresql import UUID, JSONB
|
||||
from sqlalchemy.sql import func
|
||||
from sqlalchemy.orm import relationship
|
||||
@@ -102,7 +102,15 @@ class RemissionInvoice(Base):
|
||||
taxable = Column(Numeric(14, 2), nullable=False) # imponibile
|
||||
vat = Column(Numeric(14, 2), nullable=False, default=0)
|
||||
total = Column(Numeric(14, 2), nullable=False)
|
||||
pdf_filename = Column(String(512), nullable=True) # per ora solo nome, upload vero dopo
|
||||
pdf_filename = Column(String(512), nullable=True) # nome originale
|
||||
|
||||
# File upload (bind mount /var/uploads dentro container)
|
||||
storage_path = Column(String(1024), nullable=True) # relativo a /var/uploads
|
||||
mime = Column(String(128), nullable=True)
|
||||
size_bytes = Column(BigInteger, nullable=True)
|
||||
sha256 = Column(String(64), nullable=True)
|
||||
uploaded_by = Column(Integer, nullable=True)
|
||||
uploaded_at = Column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
# Campi istruttoria (dual declared/verified)
|
||||
taxable_verified = Column(Numeric(14, 2), nullable=True)
|
||||
@@ -139,7 +147,15 @@ class RemissionUlaEmployee(Base):
|
||||
period_end_date = Column(Date, nullable=False)
|
||||
|
||||
supporting_doc_type = Column(String(64), nullable=True)
|
||||
supporting_doc_filename = Column(String(512), nullable=True)
|
||||
supporting_doc_filename = Column(String(512), nullable=True) # nome originale
|
||||
|
||||
# File upload
|
||||
storage_path = Column(String(1024), nullable=True)
|
||||
mime = Column(String(128), nullable=True)
|
||||
size_bytes = Column(BigInteger, nullable=True)
|
||||
sha256 = Column(String(64), nullable=True)
|
||||
uploaded_by = Column(Integer, nullable=True)
|
||||
uploaded_at = Column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
# Campi istruttoria
|
||||
fte_pct_verified = Column(Numeric(5, 4), nullable=True)
|
||||
@@ -164,11 +180,18 @@ class RemissionDocument(Base):
|
||||
nullable=False)
|
||||
|
||||
doc_code = Column(String(64), nullable=False) # DURC / VISURA_CAMERALE / ...
|
||||
filename = Column(String(512), nullable=True)
|
||||
filename = Column(String(512), nullable=True) # nome originale
|
||||
uploaded_at = Column(DateTime(timezone=True), nullable=True)
|
||||
expires_at = Column(Date, nullable=True)
|
||||
notes = Column(Text, nullable=True)
|
||||
|
||||
# File upload
|
||||
storage_path = Column(String(1024), nullable=True)
|
||||
mime = Column(String(128), nullable=True)
|
||||
size_bytes = Column(BigInteger, nullable=True)
|
||||
sha256 = Column(String(64), nullable=True)
|
||||
uploaded_by = Column(Integer, nullable=True)
|
||||
|
||||
# Campi istruttoria
|
||||
verification_status = Column(String(16), nullable=False, default="PENDING")
|
||||
# PENDING | VALIDO | NON_VALIDO | SCADUTO
|
||||
|
||||
Reference in New Issue
Block a user