docs(timetable): close ART-OBSERVER-ADVANCE-AGGREGATE; wire event_id through createDraft
§17.3 footnote already accurately describes ArtistResolver::fromPortalToken (checked at commitcc48011). Wired event_id end-to-end on the cleaner path: FormSubmissionService::createDraft now accepts event_id via the \$context bag, and the EngagementPortalController passes it from \$resolved->eventId. Replaces the prior post-save fallback. Per WS-4 denormalisation requirement. ART-OBSERVER-ADVANCE-AGGREGATE moved from open to closed — landed in Session 3 as the AdvanceSectionObserver (commit1716e09). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -676,19 +676,6 @@ voor third-party integraties (ticketing, HR, etc.)
|
||||
|
||||
## Technische schuld
|
||||
|
||||
### ART-OBSERVER-ADVANCE-AGGREGATE — Recompute `advancing_*_count` op AdvanceSection lifecycle
|
||||
|
||||
**Aanleiding:** RFC-TIMETABLE v0.2 Session 1 landed `advancing_completed_count` en
|
||||
`advancing_total_count` op `artist_engagements` met `default 0`. De observer die
|
||||
deze tellers bijwerkt op AdvanceSection-lifecycle wijzigingen is nog niet geland.
|
||||
**Wat:** Implementeer een `AdvanceSectionObserver` die op create/update/delete
|
||||
(en submission-status transitions) de aggregaat-tellers op de parent-engagement
|
||||
herberekent. Trigger: section-level submit lands in Session 3.
|
||||
**Prioriteit:** Middel — alleen relevant zodra de section-lifecycle daadwerkelijk
|
||||
bestaat. Voor Session 1 is `default 0` voldoende.
|
||||
|
||||
---
|
||||
|
||||
### RFC-TIMETABLE-V0.2-DOC-CLEANUP — Strip ARCH-PLANNED-MODULES.md mentions from RFC v0.2
|
||||
|
||||
**Aanleiding:** RFC-TIMETABLE v0.2 §1 ("Bron-documenten") en §15
|
||||
@@ -1332,6 +1319,7 @@ deadline implementation).
|
||||
- ~~**WS-7 Observability — closure (mei 2026)**: 4 PRs gemerged op `feat/ws-7-observability` (infra `5f6fc07`, backend SDK `bdb89a2..0379016`, frontend SDK `bc47783..5c42f27`, docs `754222f..e9da01f`). 1551 backend + 252 frontend tests groen. Acceptance criteria 1-14 voldaan; observability volledig operationeel op `monitoring.hausdesign.nl`. Implementation criteria 3, 4, 5, 6, 8, 11, 12, 13, 14 via PRs; operationele criteria 1, 2, 7, 9, 10 via deploy-checklist (DNS, TLS, superuser+2FA, prod DSNs, email-alerting, retention 90d, cron backup). Architecturale patronen vastgelegd in `dev-docs/ARCH-OBSERVABILITY.md` (730 regels) + 2 runbooks (`observability-triage.md`, `observability-erasure.md`). Twee GlitchTip projecten (`crewli-api` + `crewli-app`), één DSN per project, runtime context-split via `actor_scope` tag. Patronen: explicit > implicit listener registration, default-in-listener / override-in-middleware voor binary tags, tenant resolution chain (route-param → portal-token → super_admin platform → user fallback). Volgsporen: OBS-1, OBS-4, OBS-6, OBS-7, OBS-9 (zie "Observability follow-ups" sectie hieronder).~~ ✅
|
||||
- ~~**WS-6 v1.3-delta — closure (mei 2026)**: Architecturele review-sessie 2026-05-07 identificeerde vijf verfijningen op RFC-WS-6 v1.2 (Q1 listener queueing, Q2 invariant cleanup, Q3 failure-UX additions, plus §19 BACKLOG-pointer). v1.3 amendement gecommit (`845b6e6`, 2026-05-07); v1.3.1 drift closure (`b255879`, 2026-05-08) sloot code-vs-docs gaten pre-implementation. Implementatie geland als D1 + D2: **D1** (PR #10 `c6f4d1b`) leverde de data-laag — `failure_response_code` kolom op `form_submissions`, abstract `FormBindingApplicatorException` hiërarchie + 4 reason-coded subclasses (`FormBindingSchemaConfigException`, `FormBindingInfraException`, `FormBindingApplicatorTimeoutException`, `FormBindingDataIntegrityException`), `IdentityMatchInvariantViolation` sibling, `FormBindingExceptionClassifier` helper, `FormSubmissionIdentityMatchResolved` broadcast event class, `FormFieldBindingMergeStrategy::validForTargetType` matrix method, cast + factory state. **D2** (PR #11 `23a5696`) wired alle building blocks in de listener-chain — `ApplyBindings` initial `pending` write + deadline wrapper + classifier in catch; `TriggerPersonIdentityMatch` queued + gating-invariant + invariant throw + broadcast dispatch; `routes/channels.php` + bootstrap routing (NIEUWE broadcast wiring, submitter-only auth); gating-invariant op `SyncTagPicker`; `AppServiceProvider::boot` v1.3 layout; `FormFailureRetryService::recordFailure` classifier + apply_completed_at symmetrie-fix; `apply_deadline_seconds` config key (default 5). Tests: pre-WS-6 baseline 1208 → pre-D1 1551 → post-D2 1621. 0 Larastan errors. Phase F (`ConditionalRequirement(public_token)` wrapper drop) was no-op — change had silently landed pre-D2. **Open follow-ups:** `TECH-CHANNEL-AUTH-ORG-ADMIN` (extend `submission.{id}` channel auth to org admins na Spatie Permission helper-audit); GlitchTip alert rule op `apply_status=failed AND form_schema.has_public_token=true` (operationele taak in GlitchTip web-UI op `monitoring.hausdesign.nl`; runbook procedure in `dev-docs/runbooks/observability-triage.md` §7); frontend Echo subscription voor `FormSubmissionIdentityMatchResolved` (separate frontend follow-up, out of WS-6 scope, backend-infra ready). `PARTIAL-BINDING-SUCCESS` en `FORM-SCHEMA-DRIFT-DETECTION` blijven open conform v1.3 amendement (trigger-condities nog niet gevuurd). Closure docs-PR: RFC-WS-6.md v1.3.1 implementation-status marker + §10 closure entry, ARCH-BINDINGS.md v1.2 onveranderd, runbook §7 toegevoegd.~~ ✅
|
||||
- ~~**ARCH-09 — Artist Eloquent model + migration — closure (mei 2026)**: Foundation for the Artist & Timetable module landed as RFC-TIMETABLE v0.2 Session 1 op `feat/timetable-session-1`. Delivered: 10 migrations (genres, artists, companies.handles_buma column, artist_contacts, stages, stage_days, artist_engagements, performances, advance_sections, advance_submissions); 7 PHP enums under `App\Enums\Artist\` (`ArtistEngagementStatus` D9 with Dutch labels, `BumaHandledBy` D26, `FeeType`, `PaymentStatus`, `AdvanceSectionType`, `AdvanceSectionSubmissionStatus`, `AdvanceSubmissionStatus`); 9 Eloquent models with `OrganisationScope` (direct on Artist/Genre/ArtistEngagement, FK-chain via `tenantScopeStrategy()` on the rest) and `LogsActivity` baseline; 2 observers (`ArtistEngagementObserver` for `organisation_id` denorm + cross-tenant guard via `CrossTenantEngagementException` + cascade soft-delete to performances + hard-delete to advance_sections; `PerformanceObserver` for D14 optimistic-lock `version` bump on UPDATE); 8 factories + `ArtistTimetableDevSeeder` reproducing the prototype fixture (4 stages, 12 stage_days, 6 artists, 12 engagements, 13 performances incl. 1 parked); `PURPOSE_SUBJECT_FQCN` switched from string-literal to `Artist::class` (MorphMapAlignmentTest green); SCHEMA.md §3.5.7 rewritten in place (ARCH-PLANNED-MODULES.md was assumed by the RFC pre-amble but did not exist — see `RFC-TIMETABLE-V0.2-DOC-CLEANUP`); ARCH-FORM-BUILDER.md §3.2.5 updated for engagement-scoped sections and §17.3 footnote on `ArtistResolver::fromPortalToken` engagement context resolution. PR #XX, 2026-05-08.~~ ✅
|
||||
- ~~**ART-OBSERVER-ADVANCE-AGGREGATE — closure (mei 2026)**: AdvanceSectionObserver implemented in RFC-TIMETABLE v0.2 Session 3 on `feat/timetable-session-3`. Recomputes `artist_engagements.advancing_completed_count` + `advancing_total_count` atomically on every section lifecycle event (created / updated-status-only / deleted). Concurrency safety via `DB::transaction` + `lockForUpdate` on both the parent engagement and sibling section rows; counter writes use `disableLogging()` so housekeeping doesn't pollute the activity log. Section's own `updated` event continues to log via `LogsActivity` on `AdvanceSection`.~~ ✅
|
||||
- ~~**TECH-CHANNEL-AUTH-ORG-ADMIN — closure (mei 2026)**: `submission.{id}` private channel auth uitgebreid van submitter-only naar drie-paths: submitter (`submitted_by_user_id === user.id`) → super_admin Spatie HasRoles app-wide bypass → org_admin van submission's organisatie via pivot-table check op `user_organisation` (`->wherePivot('role', 'org_admin')`). Pattern: directe port van `FormSubmissionActionFailurePolicy::canAccess`, codebase canonical (gebruikt in 17+ policy sites). Spatie teams is disabled in `config/permission.php`, dus org-scoping leeft in de pivot, niet in Spatie. **super_admin bypass is een audit-surfaced bonus** (origineel BACKLOG entry vroeg alleen om org-admin extension; tijdens Phase A audit bleek dat elke analoge policy super_admin bypass heeft, dus toegevoegd voor consistency — zonder die bypass zouden super_admins op de admin-panel banner mysterieus geen live updates krijgen). Tests: 4 nieuw (`test_super_admin_can_subscribe`, `test_organisation_admin_of_submission_org_can_subscribe`, `test_organisation_admin_of_different_org_cannot_subscribe` (kritische cross-tenant guard), `test_regular_organisation_member_cannot_subscribe`); 1 verwijderd (de "should flip" denied-by-default test uit PR #11). Test count: 1621 → 1624 (+3 net). 0 Larastan errors. Inline TODO uit `routes/channels.php` verwijderd. Sibling `FRONTEND-ECHO-IDENTITY-MATCH-SUBSCRIPTION` blijft open (frontend portal IdentityMatchBanner subscription is de pair met deze backend-auth uitbreiding).~~ ✅
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user