Repository navigation
Conversation
…moment Versions are numbered per locale, so "version 3" names a different state in every language. Nothing identifies one moment across locales, which a printed carrier needs: the passport state a product was placed on the market with is one moment, not one per language. Add `publication_releases`: one row per minted version, with a `sequence` that is monotonic per publication, minted inside the same lock as the version number. `publication_versions.release_id` points at it. Existing versions are backfilled, one release each in publish order. `PublicationRelease::versionsAsOf()` resolves the state as of a release: for every locale, the most recent version minted at or before it. That is the read a per-release public route needs and nothing else; this change alters no public behaviour. Releases are immutable like versions (update/delete throw), and `release_id` is sealed on the version.
Contributor
Author
|
Context, motivation and suggested review order for this and the related PRs: #683 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Versions are numbered per locale, so "version 3" names a different state in every language. There is nothing that identifies one publish moment across locales.
That matters for the Digital Product Passport: the state a product was placed on the market with is one moment, not one per language, and a printed carrier needs one number that keeps meaning that moment. Today the only cross-locale handle is a timestamp lookup, which is nothing you can print or reason about.
Change
New table
publication_releases:publication_id,sequence(monotonic per publication, unique on(publication_id, sequence)),published_at,published_by_id. One release is minted per minted version, inside the same publication row lock that already protects the version number, soMAX(sequence) + 1cannot race for the same reasonMAX(version) + 1cannot.publication_versions.release_id(nullable FK,restrictOnDelete), set by bothpublish()andrepublishFrom(). The version'spublished_atis now taken from the release so the two never drift.Backfill in the same migration: every existing version becomes its own release, numbered per publication in
(published_at, id)order. Uses the query builder only, so it runs on MySQL and PostgreSQL alike and respects the table prefix.Immutability: releases refuse
update()anddelete()withImmutableVersionException, like versions.release_idis not in a version's mutable-after-publish set, so moving a version to another release throws.PublicationRelease::versionsAsOf(): the state of the publication as of that release, for every locale the most recent version minted at or before it, keyed bylocale_id. Redacted versions are included; rendering them is the caller's decision. This is the read a per-release public route needs and nothing else.No public behaviour changes in this PR. Routes, templates and JSON-LD are untouched.
Tests
versionsAsOf()resolves the right version per locale for each of three consecutive releases, while version numbers keep running per localerepublishFrom()mints a release tooBackfill was additionally exercised by rolling the migration back on a database with interleaved versions across two publications and migrating forward again: sequences come out per publication in publish order, and no
release_idis left null.Related
Follows #677, #678 and #679, which make a sealed version's documents and redaction trustworthy. A per-release public route builds on this.