printedparts stage 15: print-file revision history + role-based alerts
printeditemfiles lands as the plugin's first incremental migration (0002 on the plugin chain - the ADR-008 payoff). Revisions are append-only per item: upload assigns the next number, records the uploader from the JWT, enforces an extension allowlist and a 100 MB cap; download serves the original filename; a permission-gated delete covers wrong-file mistakes. The detail page gains the revision table with a current badge. Unique storedfilename is sized 191 so the index fits MySQL's 767-byte prefix - the per-plugin chain does not apply the core env's ROW_FORMAT hook. Alert recipients gain roles: Role joins the 0.13.0 surface, a role picker on the settings page, and every active member of the selected roles is folded into the deduped recipient list.
This commit is contained in:
@@ -93,3 +93,43 @@ class PrintedItemTransaction(BaseModel):
|
||||
'reason': self.reason,
|
||||
'transactiondate': self.transactiondate.isoformat() + 'Z' if self.transactiondate else None,
|
||||
}
|
||||
|
||||
|
||||
class PrintedItemFile(BaseModel):
|
||||
"""One uploaded revision of an item's print file (STL/3MF/gcode/...).
|
||||
|
||||
Revisions are append-only per item: uploading assigns the next revision
|
||||
number and never replaces earlier files, so the history of what was
|
||||
actually printed stays reconstructible. The current file is simply the
|
||||
highest revision.
|
||||
"""
|
||||
|
||||
__tablename__ = 'printeditemfiles'
|
||||
|
||||
fileid = db.Column(db.Integer, primary_key=True)
|
||||
printeditemid = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey('printeditems.printeditemid', ondelete='CASCADE'),
|
||||
nullable=False, index=True)
|
||||
revision = db.Column(db.Integer, nullable=False)
|
||||
filename = db.Column(db.String(255), nullable=False,
|
||||
comment='Original upload name, used for download')
|
||||
storedfilename = db.Column(db.String(191), nullable=False, unique=True,
|
||||
comment='191: unique index fits the 767-byte MySQL prefix')
|
||||
filesize = db.Column(db.Integer, nullable=False)
|
||||
uploadnote = db.Column(db.String(255),
|
||||
comment='What changed in this revision')
|
||||
uploadedby = db.Column(db.String(80), nullable=False,
|
||||
comment='Username of the uploader')
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
'fileid': self.fileid,
|
||||
'printeditemid': self.printeditemid,
|
||||
'revision': self.revision,
|
||||
'filename': self.filename,
|
||||
'filesize': self.filesize,
|
||||
'uploadnote': self.uploadnote,
|
||||
'uploadedby': self.uploadedby,
|
||||
'uploadeddate': self.createddate.isoformat() + 'Z' if self.createddate else None,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user