a977aedc95aa24c2927014cc1a1353f05eaf3677
The Agents tab's add-an-agent form opened with
<label class="form-label">User ID</label>
<input v-model="agentForm.user_id" required type="number"
placeholder="User ID" class="form-input" />
<p class="form-hint">Find IDs in Admin → Users</p>
— a primary key asked of an office administrator, on the one screen #4806
documents as the only recovery for a help desk group whose last manager can no
longer act. `exists:users,id` refuses an id nobody holds, so the failure that
mattered was never a typo that errors: 47 typed for 74 is two real accounts,
and the one written is handed `agent` — or `manager` — over a whole queue, with
the person named nowhere before the press or after it. #4781's audit row was
therefore the first place anybody could find out.
Two writes here, both small:
* `searchUsers()` — `q` over name and email, answered by `PersonChip::rows()`,
the platform's one serializer for a searchable person (#871), so the
operator's People setting reaches this picker like every other one. The
gate is the page's own requireAgentAccess() and not a per-group one: the
form picks the PERSON before the GROUP, and the write still goes through
requireManagerAccessOrOrphanRecovery() unchanged.
* `storeAgent()`'s flash names the appointee, through `PersonNames::display()`
so it reads the way the chip above it does (#524). The recovery sentence
keeps every word it had and gains the other half of itself.
The shell half — the picker's markup, its proofs and the chip-surface
registration — is on dashboard-shell card/4926-….
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
dashboard-ticketing
Description
Languages
PHP
100%