fix(api): align zone content kind validation with model
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -21,8 +21,8 @@ def _maybe_migrate_tab_json_to_zone():
|
|||||||
class Zone(Model):
|
class Zone(Model):
|
||||||
"""Preset layout row (stored in ``db/zone.json``); legacy storage was ``tab.json`` / Tab.
|
"""Preset layout row (stored in ``db/zone.json``); legacy storage was ``tab.json`` / Tab.
|
||||||
|
|
||||||
Optional ``content_kind`` on a row: ``\"presets\"`` (preset tiles only) or ``\"sequences\"``
|
Optional legacy ``content_kind`` (``\"presets\"`` / ``\"sequences\"``) is kept for older data;
|
||||||
(sequence tiles only). Legacy rows without ``content_kind`` are inferred on load.
|
zones may hold both preset tiles and ``sequence_ids``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -95,13 +95,8 @@ class Zone(Model):
|
|||||||
return "presets"
|
return "presets"
|
||||||
|
|
||||||
def _enforce_content_kind_invariants(self, doc):
|
def _enforce_content_kind_invariants(self, doc):
|
||||||
"""Presets-only zones hold no sequences; sequences-only hold no preset tiles."""
|
"""No-op: presets and sequences may coexist on one zone."""
|
||||||
kind = self._normalized_content_kind(doc)
|
_ = doc
|
||||||
if kind == "presets":
|
|
||||||
doc["sequence_ids"] = []
|
|
||||||
elif kind == "sequences":
|
|
||||||
doc["presets"] = []
|
|
||||||
doc["presets_flat"] = []
|
|
||||||
|
|
||||||
def create(self, name="", names=None, presets=None, group_ids=None, content_kind=None):
|
def create(self, name="", names=None, presets=None, group_ids=None, content_kind=None):
|
||||||
next_id = self.get_next_id()
|
next_id = self.get_next_id()
|
||||||
@@ -135,13 +130,7 @@ class Zone(Model):
|
|||||||
if id_str not in self:
|
if id_str not in self:
|
||||||
return False
|
return False
|
||||||
patch = dict(data) if isinstance(data, dict) else {}
|
patch = dict(data) if isinstance(data, dict) else {}
|
||||||
doc = self[id_str]
|
|
||||||
locked_kind = self._normalized_content_kind(doc) or self._infer_content_kind(doc)
|
|
||||||
if "content_kind" in patch:
|
|
||||||
patch["content_kind"] = locked_kind
|
|
||||||
self[id_str].update(patch)
|
self[id_str].update(patch)
|
||||||
if "content_kind" in patch:
|
|
||||||
self._enforce_content_kind_invariants(self[id_str])
|
|
||||||
self.save()
|
self.save()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
"""Zone content_kind is fixed after create."""
|
"""Zones may hold both presets and sequences."""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
@@ -12,7 +12,7 @@ sys.path.insert(0, str(PROJECT_ROOT / "src"))
|
|||||||
from models.zone import Zone # noqa: E402
|
from models.zone import Zone # noqa: E402
|
||||||
|
|
||||||
|
|
||||||
def test_update_cannot_change_content_kind():
|
def test_zone_presets_and_sequences_can_coexist():
|
||||||
with tempfile.TemporaryDirectory() as tmp:
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
path = os.path.join(tmp, "zone.json")
|
path = os.path.join(tmp, "zone.json")
|
||||||
with open(path, "w", encoding="utf-8") as f:
|
with open(path, "w", encoding="utf-8") as f:
|
||||||
@@ -20,8 +20,16 @@ def test_update_cannot_change_content_kind():
|
|||||||
z = Zone()
|
z = Zone()
|
||||||
z.file = path
|
z.file = path
|
||||||
z.clear()
|
z.clear()
|
||||||
zid = z.create("preset zone", group_ids=[], content_kind="presets")
|
zid = z.create("mixed zone", group_ids=[], content_kind="presets")
|
||||||
z.update(zid, {"content_kind": "sequences", "name": "preset zone"})
|
z.update(
|
||||||
|
zid,
|
||||||
|
{
|
||||||
|
"presets": [["p1", "p2"]],
|
||||||
|
"sequence_ids": ["seq1"],
|
||||||
|
},
|
||||||
|
)
|
||||||
doc = z.read(zid)
|
doc = z.read(zid)
|
||||||
assert doc["content_kind"] == "presets"
|
assert doc.get("sequence_ids") == ["seq1"]
|
||||||
assert doc.get("sequence_ids") == []
|
preset_ids = Zone._preset_ids_in_doc(doc)
|
||||||
|
assert "p1" in preset_ids
|
||||||
|
assert "p2" in preset_ids
|
||||||
|
|||||||
Reference in New Issue
Block a user