Title
Summary: Test

Backend asks — Studio, from building S23
Frontend, 2026-09-21. Everything below was measured against the running
backend today, not read out of staff-api.md. Ranked by how much each one
unblocks.
Context: we sliced S23 (Deliverables and assignment) to the register and the
crew. It runs. These are what stop the rest of it, plus three bugs we hit on
the way.
1. The register lists deliverables whose record read refuses — 0 of 14
This is the one that matters. GET /deliverables carries no visibility
scope; GET /deliverables/{id} does. So the list shows work that cannot be
opened.
Measured as hana.abdelaziz@ment.example — a Department Leader, the role
this screen is for, holding deliverables.show:
Call | Result |
|---|---|
| 200, 14 rows |
| 404 on all 14 |
Same ids as | 200 |
Everything in the deliverable's workspace — the scale strip, the lock stamp,
the three deadlines, the counters — comes from that detail read, so the
screen is empty for its own audience.
We are not guessing which way to fix it: either scope the register the same
way as the record, or widen the record read to what the register already
lists. Both are correct; the two disagreeing is what produces a screen that
lists work nobody can open.
(The 404-not-403 is understood and we are not asking for it to change — the
API refuses to leak that a record exists. It does mean the client cannot
tell "gone" from "not yours", so we show the refusal verbatim rather than
guessing.)
2. deliverables_required has no producer anywhere
The artboard's "From the brief" panel lists the line items the Account
Manager ticked, with a Create button per uncreated one — that is
SC-M3-10, bulk create from the brief list, and one of S23's ten inventory
rows.
The string deliverables_required appears in zero files acrossModules/. track_payload exists on TrackResource, but not that key.
So the panel and the bulk create cannot be built at all. If the line items
live somewhere else under another name, tell us where; if nothing writes
them yet, that is the answer and we will drop the panel from the spec.
3. Nothing reads deadline_revisions back
S23's "Deadline history" tab lists every movement of the internal deadline
with shift_working_minutes, reason_code, source and affects_scoring.
The table exists and is append-only. It is written byPUT /deliverables/{id}/deadline, by every handoff and by every approved
extension. Nothing returns it:
DeadlineRevisionInterfaceexposes one method,revise()there is no
DeadlineRevisionResourcein the codebaseno route in any module mentions
deadline-revisions
The ingredients are all written already — DeadlineRevisionRepository,DeadlineRevisionFilter, DeadlineRevisionReasonCode,DeadlineRevisionSource, AffectsScoringTable. This looks like a resource
and a route, not a feature.
Ask: GET /deliverables/{id}/deadline-revisions.
Nothing else on the wire carries the shift, the reason or the scoring flag,
so until it exists the tab has no data source and we have left it out.
4. The list row carries no lead, so the register cannot show who holds what
DeliverableSummaryResource has no lead, no assignee. The artboard's row
shows the lead's avatar and name ("Omar", "Moataz +1") — on an assignment
screen that is arguably the most important column.
The only source is GET /deliverables/{id}/assignments, which is one call
per row (40 calls on a 40-row register) behind assignments.manage, a key
designers do not hold.
Ask: a lead block — {id, name} — on DeliverableSummaryResource,
and ideally a supporting_count.
5. AssignmentResource never names anybody
user.name is null on every row, verified on live data:
"user": { "id": "01a0c364-1b90-72bd-8e75-2c1072198aaa", "name": null }AssignmentResource:64 builds the ref from the id alone. We currently
resolve names against /users/list-dropdown to avoid rendering a blank
crew, which works but means an extra read on every screen that shows an
assignment.
6. Assignment history has no read
GET /deliverables/{id}/assignments returns only rows whereeffective_to IS NULL — the active crew. SC-M3-18 is a history table: every
lead and supporting change, each one's window, the handoff that split the
rows, and voided handoffs struck through.
Ask: the same route with ?include=closed (or a sibling) returning the
closed windows too. AssignmentFilter already exists and no route uses it.
7. /studio/queue and /workload return nulls for most of the row
Not an S23 blocker but it will stop S22 and the department board dead, and
it looks like a key mismatch rather than missing data.
StudioBoardService writes late, blocked, lead_user_id;StudioQueueRowResource reads late_flag, blocked_flag,assignee_user_id. The service also formats the dates as ATOM strings whileShapesApiPayloads::iso() returns null for anything that is not aDateTimeInterface.
Measured — GET /api/v1/studio/queue as Super Admin, first row:
null: deliverable_type_code, deliverable_type_label, working_sub_status,
working_sub_status_label, assignee, current_deadline_at, clock_state,
clock_label, open_information_request_id, current_version_number,
row_version
late_flag: false (regardless of the row)8. Two smaller contract oddities
*
POST /deliverables/{id}/assignmentsrequiressupporting..shareand
then discards it.** AssignmentController::supportingUserIds keeps only
the ids and the service computes each share from ShareCalculator. We
have left supporting designers out of the assign dialog rather than ship a
control whose value is thrown away — either drop the field from the
FormRequest or honour it.
**
POST /assignment-handoffs/{id}/acceptdoes not persist what it
validates.** handover_checklist_complete, open_items_at_handoff andhandover_completed_on_behalf_flag are required by the request and never
written by HandoffService::accept, which also ignores row_version.
Still open from S24
The Art Studio role grant (ask 1 of Docs/backend-asks-s24.md, sent
2026-09-20) is still outstanding: RolesSeeder's ART_STUDIO asks fordeliverables.submit and versions.manage, neither declared in anyacl.php, so a designer gets 403 on four of the five actions on their own
screen.
One operational note, not an ask
Studio's routes were missing from bootstrap/cache/routes-v7.php from
2026-09-20 12:04 until this morning — the cache was built during the window
when SlaPauseService did not implement SlaPauseInterface::forSubject and
the module fatally failed to boot. Every Studio route answered 404 for every
account, including ones with no permission key at all, while other modules
were fine. php artisan route:clear fixed it.
Flagging only because it presents as an empty screen rather than an error,
and it cost us most of a debugging session before we thought to check the
route table.
