fix(projects): enforce single-customer projects (guard event attach + re-label)

A project must stay tied to one customer. The quote/contract/hours attach
paths already rejected a foreign customer (equality on project.customer_account_id);
the two remaining holes are closed here:

- assignEvent: an event may only join a project that shares its customer. The
  event's customer(s) come from event_customer_assignments; a customer-assigned
  project rejects an event for a different customer (PROJECT_CUSTOMER_MISMATCH),
  and an empty project ADOPTS a single-customer event's customer. This is why
  a foreign-customer event could previously be attached.

- updateProject: re-labelling a project to a customer that conflicts with the
  events/quotes/contracts it already holds is rejected (clearing to null is
  still allowed), so the customer can't be swapped out from under existing
  content.

Frontend: the cockpit attach-event action surfaces the translated mismatch
message; projects.error.customerMismatch reworded to read for both documents
and events (de + en).
This commit is contained in:
Luca
2026-06-13 13:09:55 +02:00
parent 9d13880f2b
commit 4b1e85c855
4 changed files with 71 additions and 5 deletions
+1 -1
View File
@@ -3453,7 +3453,7 @@
"previewFailed": "Vorschau konnte nicht geladen werden"
},
"error": {
"customerMismatch": "Dieses Projekt gehört zu einem anderen Kunden als dieser Eintrag."
"customerMismatch": "Das gehört zu einem anderen Kunden als dieses Projekt."
}
},
"calendar": {
+1 -1
View File
@@ -3453,7 +3453,7 @@
"previewFailed": "Could not load preview"
},
"error": {
"customerMismatch": "That project belongs to a different customer than this entry."
"customerMismatch": "That belongs to a different customer than this project."
}
},
"calendar": {