Archive copy must succeed before a packet counts as filed (Gitea issue 57)
FILE checks the archive folder and copies the packet inside the filing transaction. A failed check or copy rolls the filing back, so the packet stays in its previous stage; the person filing gets 503 archive_failed, and in its own transaction the server writes an archive.filing_blocked audit row and raises the critical archive_failed condition to Admin for that packet (who tried, folder, error). The next successful filing clears it. The archive-copy job now only catches up filings made while the archive was off. PLAN question 53, CHANGELOG, FEED and SECURITY updated. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -833,7 +833,8 @@ def apply_transition(w: Write) -> None:
|
||||
def _file(w: Write) -> None:
|
||||
"""FILE: the data book date, the seal, and the data book built and stored on the seal, all in this transaction.
|
||||
|
||||
A data book that cannot be built answers 500 databook_failed and the whole filing rolls back."""
|
||||
A data book that cannot be built answers 500 databook_failed and the whole filing rolls back. So does an archive
|
||||
copy that fails (archive.FilingCopyFailed, answered 503 archive_failed by the transition endpoint)."""
|
||||
key = _seal_key(w)
|
||||
_set_packet(w, "databook_at = now()")
|
||||
row = packets.load_row(w.conn, w.id)
|
||||
@@ -850,11 +851,13 @@ def _file(w: Write) -> None:
|
||||
w.log_also("Data book filed", f"{pages} pages")
|
||||
w.detail["seal_id"] = int(seal_id)
|
||||
w.detail["databook_pages"] = pages
|
||||
# The archive copy runs in the worker after this commits. A failed copy never blocks filing.
|
||||
# The archive copy must succeed before the packet counts as filed (Gitea issue 57). A failure raises
|
||||
# archive.FilingCopyFailed and the whole filing rolls back; the transition endpoint records it for Admin.
|
||||
from . import archive
|
||||
|
||||
if archive.on_filed(w.conn, _settings(w), w.user_id, w.id):
|
||||
w.detail["archive_requested"] = True
|
||||
copied = archive.copy_at_filing(w.conn, _settings(w), w.id, int(seal_id))
|
||||
if copied is not None:
|
||||
w.detail["archive_folder"] = copied["folder"]
|
||||
|
||||
|
||||
def _file_databook(w: Write, row: Mapping[str, Any], seal: dict[str, Any], seal_id: int) -> int:
|
||||
|
||||
Reference in New Issue
Block a user