Stream's bucket and scenario must belong to the same scenario #51
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Discovered during #50 (per-user ownership) planning. A
Streamhas two FKs:scenario— required (nullable: false, CASCADE)bucket— optional (nullable: true, SET NULL)There is currently no DB constraint or validator guaranteeing that
stream.bucketbelongs tostream.scenario. As a result a stream in scenario B can reference a bucket that lives in scenario A — a cross-scenario inconsistency the domain never intends (an expense stream earmarks a bucket within its own scenario).This is separate from ownership (#50). #50 ensures both the scenario and bucket IRIs on create belong to the caller, but two scenarios owned by the same user could still be crossed. This is a same-owner data-integrity gap, not an authorization gap.
Goal
When a
Streamhas a non-nullbucket, that bucket MUST belong to the samescenarioas the stream. Violations are rejected at the validation layer with a clean 422 (not a DB error, not a silent accept).Approach (locked direction)
stream/bucket).bucketis non-null (a null bucket — income/scenario-wide streams — needs no check).propertyPath(bucket) so the 422 body mirrors the existing invariant-violation contract ({violations:[{propertyPath,message,code}]}, top-level un-prefixedviolations).Tests
bucket.bucket = null→ 201 (no check fires).Out of scope
bucket = null).