Add project schema version

This commit is contained in:
Olive Vaughn 2026-09-28 21:03:18 -04:00
parent e22ee600b9
commit 73ab153b02
4 changed files with 24 additions and 5 deletions

View file

@ -0,0 +1,15 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("clips", "0005_footage_stream_alter_footage_video"),
]
operations = [
migrations.AddField(
model_name="project",
name="schema_version",
field=models.PositiveIntegerField(default=1),
),
]

View file

@ -199,14 +199,14 @@ class Block(models.Model):
class Project(models.Model): class Project(models.Model):
"""Tier 1: the document's root. """Tier 1: the document's root.
`seq` is the monotonic project version docs/architecture.md asks for. Every `schema_version` identifies the stored document format. `seq` counts writes
write bumps it, and a client that sees `seq > local + 1` refetches — which is to this particular project; it is not a format version. Every write bumps
what makes staleness self-healing rather than permanent once there is a `seq`, and a client that sees `seq > local + 1` refetches once broadcasts exist.
broadcast to miss.
""" """
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=200, default="untitled") name = models.CharField(max_length=200, default="untitled")
schema_version = models.PositiveIntegerField(default=1)
seq = models.PositiveBigIntegerField(default=0) seq = models.PositiveBigIntegerField(default=0)
palette = models.CharField(max_length=64, default="arthur/default") palette = models.CharField(max_length=64, default="arthur/default")
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)

View file

@ -379,6 +379,7 @@ class DocumentTests(TestCase):
self.assertEqual(5, len(response.json()["written"])) self.assertEqual(5, len(response.json()["written"]))
loaded = self.client.get(f"/api/projects/{self.project.id}").json() loaded = self.client.get(f"/api/projects/{self.project.id}").json()
self.assertEqual(1, loaded["schema_version"])
self.assertEqual(1, len(loaded["clips"])) self.assertEqual(1, len(loaded["clips"]))
clip = loaded["clips"][0] clip = loaded["clips"][0]
self.assertEqual("c1", clip["cid"]) self.assertEqual("c1", clip["cid"])

View file

@ -571,6 +571,7 @@ def _project_json(project: Project):
return { return {
"id": str(project.id), "id": str(project.id),
"name": project.name, "name": project.name,
"schema_version": project.schema_version,
"seq": project.seq, "seq": project.seq,
"palette": project.palette, "palette": project.palette,
"clips": clips, "clips": clips,
@ -583,7 +584,8 @@ def projects(request):
return JsonResponse( return JsonResponse(
{ {
"projects": [ "projects": [
{"id": str(p.id), "name": p.name, "seq": p.seq, {"id": str(p.id), "name": p.name,
"schema_version": p.schema_version, "seq": p.seq,
"updated": p.updated.isoformat()} "updated": p.updated.isoformat()}
for p in Project.objects.all()[:100] for p in Project.objects.all()[:100]
] ]
@ -690,6 +692,7 @@ def _save(project: Project, data):
return JsonResponse( return JsonResponse(
{ {
"id": str(project.id), "id": str(project.id),
"schema_version": project.schema_version,
"seq": seq, "seq": seq,
"written": sorted(written), "written": sorted(written),
"removed": sorted(removed), "removed": sorted(removed),