UI completion pass + accountability & benchmarking

UI (daily-drivable now):
- Board: dnd-kit drag-and-drop between columns; click a card → task detail drawer (Sheet)
  with status, member assignee picker, send-to-AI-seat dispatch, description/artifact,
  parent/children navigation; seat-triad assignee chips (AI indigo monogram / human slate).
- Cartable page (the personal pending slice), Members & invitations page (invite + copy
  join token; V1 sends no email), Review inbox now shows a word-level diff of your edits
  vs the proposal (lib/diff.ts, LCS), Org chart page (React Flow: org → teams → seats in
  the human/open/AI triad). Nav reordered; nothing left "soon".

Accountability & benchmarking:
- Identity: GET /members (directory + org role) and GET /invitations (with join token,
  inviter-only) — the directory also resolves names client-side everywhere.
- OrgBoard: work_item_transitions recorded on every status change (AddWorkItemTransitions
  migration); GET /performance — per assignee (human and AI on the same scale): pending by
  column, done, worked hours (time in InProgress), avg cycle time (start of work → done),
  plus the unassigned-pending count. Owner-level capability.
- Performance page: benchmark table merging board metrics with AI trust metrics (approval
  rate + edit distance from analytics); flags work with no one accountable.

Verified: build green; ArchitectureTests 8/8; IntegrationTests 43/43 (new: directory,
invitations list + Member 403s, transition-derived worked-hours/cycle-time, unassigned
count); client npm build green (TS strict).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-10 12:54:13 +03:30
parent 82033c2733
commit d853609213
21 changed files with 1907 additions and 130 deletions
@@ -208,6 +208,43 @@ namespace TeamUp.Modules.OrgBoard.Persistence.Migrations
b.ToTable("work_items", "orgboard");
});
modelBuilder.Entity("TeamUp.Modules.OrgBoard.Domain.WorkItemTransition", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid?>("ActorMemberId")
.HasColumnType("uuid");
b.Property<string>("FromStatus")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<DateTimeOffset>("OccurredAtUtc")
.HasColumnType("timestamp with time zone");
b.Property<Guid>("TeamId")
.HasColumnType("uuid");
b.Property<string>("ToStatus")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<Guid>("WorkItemId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("TeamId");
b.HasIndex("WorkItemId");
b.ToTable("work_item_transitions", "orgboard");
});
#pragma warning restore 612, 618
}
}