Skip to content

Commit c86fa1a

Browse files
authored
Merge pull request #651 from cluesmith/builder/aspir-650-team-page-show-issue-pr-detail
[Spec 650] Team page: show issue/PR details and activity feed
2 parents f1c7bfe + 4c0c6a1 commit c86fa1a

10 files changed

Lines changed: 743 additions & 22 deletions

File tree

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# Plan: Team Page — Show Issue/PR Details and Activity Feed
2+
3+
## Metadata
4+
- **ID**: plan-2026-04-01-team-page-detail
5+
- **Status**: draft
6+
- **Specification**: codev/specs/650-team-page-show-issue-pr-detail.md
7+
- **Created**: 2026-04-01
8+
9+
## Executive Summary
10+
Expand the team page to show individual issue/PR titles with GitHub links (instead of just counts) and add a combined activity feed. Requires a minimal backend fix to add `url` to recent activity GraphQL fragments, then frontend changes to `TeamView.tsx` and `index.css`.
11+
12+
## Success Metrics
13+
- [ ] Member cards show issue/PR titles with clickable GitHub links
14+
- [ ] Combined activity feed below Messages section
15+
- [ ] Activity feed sorted reverse chronologically with correct attribution
16+
- [ ] Empty states handled (`github_data: null` hides sections; empty arrays show text)
17+
- [ ] Long titles truncated with ellipsis
18+
- [ ] Build passes, no regressions
19+
20+
## Phases (Machine Readable)
21+
22+
```json
23+
{
24+
"phases": [
25+
{"id": "backend-url-fix", "title": "Add URL to recent activity data"},
26+
{"id": "expanded-member-cards", "title": "Expand member cards with issue/PR lists"},
27+
{"id": "activity-feed", "title": "Add combined activity feed"}
28+
]
29+
}
30+
```
31+
32+
## Phase Breakdown
33+
34+
### Phase 1: Add URL to recent activity data
35+
**Dependencies**: None
36+
37+
#### Objectives
38+
- Add `url` field to merged PRs and closed issues in the GraphQL query and types
39+
40+
#### Deliverables
41+
- [ ] Updated GraphQL query fragments in `team-github.ts`
42+
- [ ] Updated TypeScript types in `team-github.ts` and `api.ts`
43+
- [ ] Updated response parsing to include `url`
44+
45+
#### Implementation Details
46+
47+
**File: `packages/codev/src/lib/team-github.ts`**
48+
- `TeamMemberGitHubData.recentActivity.mergedPRs`: add `url: string` to type (line 26)
49+
- `TeamMemberGitHubData.recentActivity.closedIssues`: add `url: string` to type (line 27)
50+
- GraphQL query `_merged` fragment (line 94): add `url``nodes { ... on PullRequest { number title url mergedAt } }`
51+
- GraphQL query `_closed` fragment (line 97): add `url``nodes { ... on Issue { number title url closedAt } }`
52+
- `parseTeamGraphQLResponse` (lines 123-124): update type casts and map to include `url`
53+
54+
**File: `packages/codev/dashboard/src/lib/api.ts`**
55+
- `TeamMemberGitHubData.recentActivity.mergedPRs`: add `url: string` (line 60)
56+
- `TeamMemberGitHubData.recentActivity.closedIssues`: add `url: string` (line 61)
57+
58+
#### Acceptance Criteria
59+
- [ ] `url` field present on all recent activity items
60+
- [ ] Update existing unit test mocks in `team-github.test.ts` to include `url` field
61+
- [ ] Existing unit tests still pass
62+
- [ ] Build succeeds
63+
64+
---
65+
66+
### Phase 2: Expand member cards with issue/PR lists
67+
**Dependencies**: Phase 1
68+
69+
#### Objectives
70+
- Replace count-only display with individual issue/PR title lists in `MemberCard`
71+
72+
#### Deliverables
73+
- [ ] Updated `MemberCard` component showing issue/PR titles
74+
- [ ] CSS styles for issue/PR lists
75+
- [ ] Empty state handling
76+
77+
#### Implementation Details
78+
79+
**File: `packages/codev/dashboard/src/components/TeamView.tsx`**
80+
- Replace the `team-member-stats` div (lines 29-32) with two sections:
81+
- "Working on" section: render `gh.assignedIssues` as a list of `<a>` tags with `#{number} {title}`
82+
- "Open PRs" section: render `gh.openPRs` as a list of `<a>` tags with `#{number} {title}`
83+
- When `github_data` is `null`: hide both sections entirely
84+
- When arrays are empty: show "No assigned issues" / "No open PRs" text
85+
- Keep existing recent activity summary (merged/closed counts with "last 7d")
86+
87+
**File: `packages/codev/dashboard/src/index.css`**
88+
- Add styles for `.team-member-issues` and `.team-member-prs` list containers
89+
- Style `.team-item-link`: `display: block`, `text-overflow: ellipsis`, `overflow: hidden`, `white-space: nowrap` (block-level with constrained width for ellipsis to work)
90+
- Style section labels (small, muted headers for "Working on" / "Open PRs")
91+
92+
#### Acceptance Criteria
93+
- [ ] Each issue/PR title displayed as clickable link
94+
- [ ] Links open in new tab with `noopener noreferrer`
95+
- [ ] Long titles truncated with ellipsis
96+
- [ ] `github_data: null` hides sections
97+
- [ ] Empty arrays show placeholder text
98+
99+
---
100+
101+
### Phase 3: Add combined activity feed
102+
**Dependencies**: Phase 1, Phase 2
103+
104+
#### Objectives
105+
- Add a unified activity timeline below the Messages section
106+
107+
#### Deliverables
108+
- [ ] New `ActivityFeed` component
109+
- [ ] CSS styles for activity feed
110+
- [ ] Relative date formatting helper
111+
112+
#### Implementation Details
113+
114+
**File: `packages/codev/dashboard/src/components/TeamView.tsx`**
115+
- Add `ActivityFeed` component that:
116+
1. Aggregates `recentActivity.mergedPRs` and `recentActivity.closedIssues` across all members
117+
2. Tags each item with the member's `name` and `github` handle
118+
3. Sorts by timestamp (mergedAt/closedAt) in reverse chronological order
119+
4. Renders each entry as: `{relativeDate} @{github} {merged|closed} #{number} {title}`
120+
5. Each entry rendered as a single `<a>` anchor wrapping the entire row (entire row clickable), with `target="_blank"` and `rel="noopener noreferrer"`, linking to GitHub via `url` field
121+
- Add inline `relativeDate(isoString: string)` helper: returns "just now" (<1h), "Xh ago" (1-23h), "Xd ago" (1d+)
122+
- Add the feed as a third section in `TeamView` after Messages
123+
- Show "No recent activity" when feed is empty
124+
125+
**File: `packages/codev/dashboard/src/index.css`**
126+
- Style `.team-activity-feed` container
127+
- Style `.team-activity-entry`: row layout, muted date, action text
128+
- Style `.team-activity-author`: `@handle` display
129+
130+
#### Acceptance Criteria
131+
- [ ] Activity feed shows entries from all members
132+
- [ ] Entries sorted reverse chronologically
133+
- [ ] Relative dates display correctly
134+
- [ ] Links open in new tab
135+
- [ ] Empty state shows "No recent activity"
136+
137+
## Dependency Map
138+
```
139+
Phase 1 (backend-url-fix) ──→ Phase 2 (expanded-member-cards) ──→ Phase 3 (activity-feed)
140+
```
141+
142+
## Risk Analysis
143+
| Risk | Probability | Impact | Mitigation |
144+
|------|------------|--------|------------|
145+
| GraphQL url field not available | Very Low | Medium | Verified: GitHub API exposes `url` on Issue and PullRequest |
146+
| CSS layout breakage on narrow widths | Low | Low | Existing `minmax(200px, 1fr)` grid handles this; add `text-overflow: ellipsis` |
147+
148+
## Validation Checkpoints
149+
1. **After Phase 1**: `npm run build` passes, types are consistent
150+
2. **After Phase 2**: Member cards render titles in dashboard
151+
3. **After Phase 3**: Full feature complete, activity feed renders correctly
152+
153+
## Expert Review
154+
**Date**: 2026-04-01
155+
**Models Consulted**: Gemini, Codex, Claude
156+
**Key changes from consultation**:
157+
- Added explicit unit test update task for Phase 1 (Gemini, Codex)
158+
- Specified "entire row clickable" as single `<a>` anchor for activity feed (Codex)
159+
- Added "just now" fallback for sub-1h relative dates (Codex)
160+
- Clarified CSS ellipsis requires block-level display (Gemini)
161+
162+
## Approval
163+
- [ ] Technical Lead Review
164+
- [x] Expert AI Consultation Complete

codev/resources/arch.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,8 @@ packages/codev/dashboard/
645645
**Team View** (Spec 587):
646646
- Conditional tab — only appears when `codev/team/people/` has 2+ valid member files
647647
- `teamEnabled` boolean in `DashboardState` controls tab visibility (set by `hasTeam()` in `/api/state`)
648-
- Member cards: name, role badge, GitHub handle link, assigned issues, open PRs, recent activity (last 7 days)
648+
- Member cards: name, role badge, GitHub handle link, clickable issue/PR title lists, recent activity counts (last 7 days)
649+
- Combined activity feed: unified reverse-chronological timeline of merged PRs and closed issues across all members
649650
- Message log from `codev/team/messages.md` displayed in reverse chronological order
650651
- Data from `/api/team` endpoint — members enriched with batched GraphQL GitHub data
651652
- Fetch-on-activation pattern (like Statistics), manual refresh button, no polling
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Review: Team Page — Show Issue/PR Details and Activity Feed
2+
3+
## Summary
4+
Expanded the team page to show individual issue/PR titles with clickable GitHub links (replacing count-only display) and added a combined activity feed showing recent merged PRs and closed issues across all members. Included a minimal backend fix to add `url` to the GraphQL query for recent activity items.
5+
6+
**Stats**: 6 files changed, 325 insertions, 21 deletions across 5 commits.
7+
8+
## Spec Compliance
9+
- [x] Member cards show individual issue titles with clickable GitHub links
10+
- [x] Member cards show individual PR titles with clickable GitHub links
11+
- [x] Combined activity feed renders below Messages section
12+
- [x] Activity feed entries sorted reverse chronologically with correct attribution
13+
- [x] Activity feed entries link to GitHub (entire row clickable)
14+
- [x] Empty states handled (`github_data: null` hides sections; empty arrays show text)
15+
- [x] Long titles truncated with CSS ellipsis
16+
- [x] Existing member card info preserved (name, role, GitHub handle)
17+
- [x] Relative dates: "just now" (<1h), "Xh ago", "Xd ago"
18+
- [x] All links open in new tab with `noopener noreferrer`
19+
20+
## Deviations from Plan
21+
- **Backend change added**: Original issue described this as "frontend-only," but all 3 spec consultants identified that `recentActivity` items lacked `url` fields. Added a minimal backend fix (GraphQL query + type updates) — 4 lines of query change.
22+
- **Tests added for dashboard logic**: Plan didn't originally include frontend unit tests. Codex reviewer requested them. Added `activityFeed.test.ts` with 8 tests covering `relativeDate` and `buildActivityFeed` pure functions.
23+
24+
## Lessons Learned
25+
26+
### What Went Well
27+
- 3-way consultation caught a real data gap (missing `url` on activity items) before implementation started — saved a rework cycle
28+
- Clean separation of pure functions (`relativeDate`, `buildActivityFeed`) from React components made testing straightforward
29+
- Existing `TeamMemberGitHubData` interface and `useTeam` hook required zero modifications to the data flow
30+
31+
### Challenges Encountered
32+
- **GraphQL URL gap**: The `_merged` and `_closed` query fragments omitted `url` even though the GitHub API supports it. Caught during spec consultation, not during code review — consultation was load-bearing here.
33+
- **Dashboard test config**: Dashboard tests run with a separate vitest config (`dashboard/vitest.config.ts`) with jsdom environment, excluded from the main test suite. Required running from the `dashboard/` subdirectory.
34+
35+
### What Would Be Done Differently
36+
- Check data completeness (all fields available) during spec writing rather than assuming "all data is already available"
37+
38+
## Technical Debt
39+
- No Playwright E2E tests for the new UI — existing team tab E2E tests only verify API contract and tab visibility, not rendered content
40+
41+
## Consultation Feedback
42+
43+
### Specify Phase (Round 1)
44+
45+
#### Gemini (REQUEST_CHANGES)
46+
- **Concern**: `recentActivity` items lack `url` — spec claims frontend-only but can't link activity items
47+
- **Addressed**: Updated spec to include minimal backend fix
48+
49+
#### Codex (REQUEST_CHANGES)
50+
- **Concern**: Relative date format under-specified; empty state for `github_data: null` unclear; CSS truncation needs bounds; testing should include Playwright
51+
- **Addressed**: Added relative date format spec, null vs empty distinction, CSS truncation requirement
52+
- **Rebutted**: Playwright coverage deferred as out of scope for ~250 LOC change
53+
54+
#### Claude (COMMENT)
55+
- **Concern**: Same URL gap; suggested truncation guidance and date formatting utility
56+
- **Addressed**: All points incorporated into spec revision
57+
58+
### Plan Phase (Round 1)
59+
60+
#### Gemini (APPROVE)
61+
- No concerns. Provided helpful CSS tip (block-level for ellipsis).
62+
63+
#### Codex (REQUEST_CHANGES)
64+
- **Concern**: Missing test tasks; "entire row clickable" not explicit; sub-1h date undefined
65+
- **Addressed**: Added test update task, explicit anchor requirement, "just now" fallback
66+
67+
#### Claude (APPROVE)
68+
- No concerns.
69+
70+
### Implement: backend-url-fix (Round 1)
71+
72+
#### Gemini (APPROVE), Claude (APPROVE)
73+
- No concerns.
74+
75+
#### Codex (REQUEST_CHANGES)
76+
- **Concern**: Missing explicit `url` assertions in tests
77+
- **Addressed**: Added `toEqual` assertions and query-level regex checks
78+
79+
### Implement: expanded-member-cards (Round 1)
80+
81+
#### All three (APPROVE)
82+
- No concerns raised.
83+
84+
### Implement: activity-feed (Round 1)
85+
86+
#### Gemini (APPROVE), Claude (APPROVE)
87+
- No concerns.
88+
89+
#### Codex (REQUEST_CHANGES)
90+
- **Concern**: No frontend test coverage for activity feed logic
91+
- **Addressed**: Added `activityFeed.test.ts` with 8 tests for pure functions
92+
93+
## Flaky Tests
94+
No flaky tests encountered.
95+
96+
## Architecture Updates
97+
Updated `codev/resources/arch.md` Team View section to reflect:
98+
- Member cards now show clickable issue/PR title lists (not just counts)
99+
- Added combined activity feed description
100+
101+
## Lessons Learned Updates
102+
No lessons learned updates needed — straightforward frontend enhancement with no novel insights beyond existing entries.
103+
104+
## Follow-up Items
105+
- Add Playwright E2E tests for team page rendered content (issue/PR links, activity feed ordering)
106+
- Consider item count cap if teams have many open issues/PRs (currently shows all)

0 commit comments

Comments
 (0)