feat(paliadin/agent-glyph): t-paliad-161 Slice E — alongside 👀

When a pending row was drafted by Paliadin (requester_kind='agent' on
its in-flight approval_request), surface a sparkle  next to the
existing eye-pill 👀. The two glyphs are orthogonal: 👀 = "needs
approval",  = "Paliadin drafted this". Either can change without the
other, so the visual taxonomy stays decomposable for any future
autopilot mode where 👀 disappears but  stays.

Read-path:

- DeadlineService.ListVisibleForUser + AppointmentService.ListVisibleForUser
  LEFT JOIN paliad.approval_requests on pending_request_id and project
  ar.requester_kind into the row. NULL when no request is pending.
- models.DeadlineWithProject + AppointmentWithProject grow
  RequesterKind *string. The list-projection helpers
  (projectDeadline / projectAppointment in event_service.go) carry it
  into EventListItem.
- /api/events response now includes requester_kind on every pending
  row; /api/inbox already does (Slice D extended approvalRequestViewColumns).

Render-path:

- frontend/src/client/events.ts — new AGENT_PILL_GLYPH constant (""),
  agentPill rendered into the title cell next to the existing
  pendingPill when item.approval_status='pending' AND
  item.requester_kind='agent'. EventListItem TS shape gains
  `requester_kind?: "user" | "agent"`.
- frontend/src/client/agenda.ts — same pattern, agendaItem TS shape
  + agentPill rendered next to pendingPill in the headline span.
- frontend/src/client/inbox.ts — ApprovalRequestView gains
  requester_kind + agent_turn_id; the meta line replaces the
  requester's plain name with "Anna  Paliadin" when the request was
  drafted by the agent.

CSS: new .approval-pill--agent modifier in global.css using only
existing tokens (--color-bg-lime-tint / --color-surface-2 /
--color-text), mirroring the .approval-pill--icon shape so the two
glyphs sit side-by-side at the same baseline.

i18n: 3 new keys × 2 langs (approvals.agent.label /
approvals.agent.byline / approvals.agent.suggestion_pending) — total
1966 → 1969.

Build clean (frontend + go), tests green.

Refs: docs/design-paliadin-inline-2026-05-08.md §8.
This commit is contained in:
m
2026-05-08 20:04:10 +02:00
parent a3052eb085
commit 4ecea7a4bb
10 changed files with 87 additions and 4 deletions

View File

@@ -252,6 +252,11 @@ type DeadlineWithProject struct {
ProjectType string `db:"project_type" json:"project_type"`
RuleName *string `db:"rule_name" json:"rule_name,omitempty"`
RuleNameEN *string `db:"rule_name_en" json:"rule_name_en,omitempty"`
// RequesterKind is the kind of the in-flight approval request (when
// approval_status='pending'): 'user' or 'agent' (Paliadin-drafted —
// t-paliad-161). NULL when the row has no pending request. Powers
// the ✨ glyph alongside the eye-pill 👀.
RequesterKind *string `db:"requester_kind" json:"requester_kind,omitempty"`
}
// Appointment is one appointment. project_id is nullable: NULL = personal
@@ -291,6 +296,8 @@ type AppointmentWithProject struct {
ProjectReference *string `db:"project_reference" json:"project_reference,omitempty"`
ProjectTitle *string `db:"project_title" json:"project_title,omitempty"`
ProjectType *string `db:"project_type" json:"project_type,omitempty"`
// RequesterKind: see DeadlineWithProject (t-paliad-161 ✨).
RequesterKind *string `db:"requester_kind" json:"requester_kind,omitempty"`
}
// Note is one polymorphic note attached to exactly one parent row