Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 164 additions & 0 deletions codev/plans/650-team-page-show-issue-pr-detail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# Plan: Team Page — Show Issue/PR Details and Activity Feed

## Metadata
- **ID**: plan-2026-04-01-team-page-detail
- **Status**: draft
- **Specification**: codev/specs/650-team-page-show-issue-pr-detail.md
- **Created**: 2026-04-01

## Executive Summary
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`.

## Success Metrics
- [ ] Member cards show issue/PR titles with clickable GitHub links
- [ ] Combined activity feed below Messages section
- [ ] Activity feed sorted reverse chronologically with correct attribution
- [ ] Empty states handled (`github_data: null` hides sections; empty arrays show text)
- [ ] Long titles truncated with ellipsis
- [ ] Build passes, no regressions

## Phases (Machine Readable)

```json
{
"phases": [
{"id": "backend-url-fix", "title": "Add URL to recent activity data"},
{"id": "expanded-member-cards", "title": "Expand member cards with issue/PR lists"},
{"id": "activity-feed", "title": "Add combined activity feed"}
]
}
```

## Phase Breakdown

### Phase 1: Add URL to recent activity data
**Dependencies**: None

#### Objectives
- Add `url` field to merged PRs and closed issues in the GraphQL query and types

#### Deliverables
- [ ] Updated GraphQL query fragments in `team-github.ts`
- [ ] Updated TypeScript types in `team-github.ts` and `api.ts`
- [ ] Updated response parsing to include `url`

#### Implementation Details

**File: `packages/codev/src/lib/team-github.ts`**
- `TeamMemberGitHubData.recentActivity.mergedPRs`: add `url: string` to type (line 26)
- `TeamMemberGitHubData.recentActivity.closedIssues`: add `url: string` to type (line 27)
- GraphQL query `_merged` fragment (line 94): add `url` → `nodes { ... on PullRequest { number title url mergedAt } }`
- GraphQL query `_closed` fragment (line 97): add `url` → `nodes { ... on Issue { number title url closedAt } }`
- `parseTeamGraphQLResponse` (lines 123-124): update type casts and map to include `url`

**File: `packages/codev/dashboard/src/lib/api.ts`**
- `TeamMemberGitHubData.recentActivity.mergedPRs`: add `url: string` (line 60)
- `TeamMemberGitHubData.recentActivity.closedIssues`: add `url: string` (line 61)

#### Acceptance Criteria
- [ ] `url` field present on all recent activity items
- [ ] Update existing unit test mocks in `team-github.test.ts` to include `url` field
- [ ] Existing unit tests still pass
- [ ] Build succeeds

---

### Phase 2: Expand member cards with issue/PR lists
**Dependencies**: Phase 1

#### Objectives
- Replace count-only display with individual issue/PR title lists in `MemberCard`

#### Deliverables
- [ ] Updated `MemberCard` component showing issue/PR titles
- [ ] CSS styles for issue/PR lists
- [ ] Empty state handling

#### Implementation Details

**File: `packages/codev/dashboard/src/components/TeamView.tsx`**
- Replace the `team-member-stats` div (lines 29-32) with two sections:
- "Working on" section: render `gh.assignedIssues` as a list of `<a>` tags with `#{number} {title}`
- "Open PRs" section: render `gh.openPRs` as a list of `<a>` tags with `#{number} {title}`
- When `github_data` is `null`: hide both sections entirely
- When arrays are empty: show "No assigned issues" / "No open PRs" text
- Keep existing recent activity summary (merged/closed counts with "last 7d")

**File: `packages/codev/dashboard/src/index.css`**
- Add styles for `.team-member-issues` and `.team-member-prs` list containers
- Style `.team-item-link`: `display: block`, `text-overflow: ellipsis`, `overflow: hidden`, `white-space: nowrap` (block-level with constrained width for ellipsis to work)
- Style section labels (small, muted headers for "Working on" / "Open PRs")

#### Acceptance Criteria
- [ ] Each issue/PR title displayed as clickable link
- [ ] Links open in new tab with `noopener noreferrer`
- [ ] Long titles truncated with ellipsis
- [ ] `github_data: null` hides sections
- [ ] Empty arrays show placeholder text

---

### Phase 3: Add combined activity feed
**Dependencies**: Phase 1, Phase 2

#### Objectives
- Add a unified activity timeline below the Messages section

#### Deliverables
- [ ] New `ActivityFeed` component
- [ ] CSS styles for activity feed
- [ ] Relative date formatting helper

#### Implementation Details

**File: `packages/codev/dashboard/src/components/TeamView.tsx`**
- Add `ActivityFeed` component that:
1. Aggregates `recentActivity.mergedPRs` and `recentActivity.closedIssues` across all members
2. Tags each item with the member's `name` and `github` handle
3. Sorts by timestamp (mergedAt/closedAt) in reverse chronological order
4. Renders each entry as: `{relativeDate} @{github} {merged|closed} #{number} {title}`
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
- Add inline `relativeDate(isoString: string)` helper: returns "just now" (<1h), "Xh ago" (1-23h), "Xd ago" (1d+)
- Add the feed as a third section in `TeamView` after Messages
- Show "No recent activity" when feed is empty

**File: `packages/codev/dashboard/src/index.css`**
- Style `.team-activity-feed` container
- Style `.team-activity-entry`: row layout, muted date, action text
- Style `.team-activity-author`: `@handle` display

#### Acceptance Criteria
- [ ] Activity feed shows entries from all members
- [ ] Entries sorted reverse chronologically
- [ ] Relative dates display correctly
- [ ] Links open in new tab
- [ ] Empty state shows "No recent activity"

## Dependency Map
```
Phase 1 (backend-url-fix) ──→ Phase 2 (expanded-member-cards) ──→ Phase 3 (activity-feed)
```

## Risk Analysis
| Risk | Probability | Impact | Mitigation |
|------|------------|--------|------------|
| GraphQL url field not available | Very Low | Medium | Verified: GitHub API exposes `url` on Issue and PullRequest |
| CSS layout breakage on narrow widths | Low | Low | Existing `minmax(200px, 1fr)` grid handles this; add `text-overflow: ellipsis` |

## Validation Checkpoints
1. **After Phase 1**: `npm run build` passes, types are consistent
2. **After Phase 2**: Member cards render titles in dashboard
3. **After Phase 3**: Full feature complete, activity feed renders correctly

## Expert Review
**Date**: 2026-04-01
**Models Consulted**: Gemini, Codex, Claude
**Key changes from consultation**:
- Added explicit unit test update task for Phase 1 (Gemini, Codex)
- Specified "entire row clickable" as single `<a>` anchor for activity feed (Codex)
- Added "just now" fallback for sub-1h relative dates (Codex)
- Clarified CSS ellipsis requires block-level display (Gemini)

## Approval
- [ ] Technical Lead Review
- [x] Expert AI Consultation Complete
3 changes: 2 additions & 1 deletion codev/resources/arch.md
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,8 @@ packages/codev/dashboard/
**Team View** (Spec 587):
- Conditional tab — only appears when `codev/team/people/` has 2+ valid member files
- `teamEnabled` boolean in `DashboardState` controls tab visibility (set by `hasTeam()` in `/api/state`)
- Member cards: name, role badge, GitHub handle link, assigned issues, open PRs, recent activity (last 7 days)
- Member cards: name, role badge, GitHub handle link, clickable issue/PR title lists, recent activity counts (last 7 days)
- Combined activity feed: unified reverse-chronological timeline of merged PRs and closed issues across all members
- Message log from `codev/team/messages.md` displayed in reverse chronological order
- Data from `/api/team` endpoint — members enriched with batched GraphQL GitHub data
- Fetch-on-activation pattern (like Statistics), manual refresh button, no polling
Expand Down
106 changes: 106 additions & 0 deletions codev/reviews/650-team-page-show-issue-pr-detail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Review: Team Page — Show Issue/PR Details and Activity Feed

## Summary
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.

**Stats**: 6 files changed, 325 insertions, 21 deletions across 5 commits.

## Spec Compliance
- [x] Member cards show individual issue titles with clickable GitHub links
- [x] Member cards show individual PR titles with clickable GitHub links
- [x] Combined activity feed renders below Messages section
- [x] Activity feed entries sorted reverse chronologically with correct attribution
- [x] Activity feed entries link to GitHub (entire row clickable)
- [x] Empty states handled (`github_data: null` hides sections; empty arrays show text)
- [x] Long titles truncated with CSS ellipsis
- [x] Existing member card info preserved (name, role, GitHub handle)
- [x] Relative dates: "just now" (<1h), "Xh ago", "Xd ago"
- [x] All links open in new tab with `noopener noreferrer`

## Deviations from Plan
- **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.
- **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.

## Lessons Learned

### What Went Well
- 3-way consultation caught a real data gap (missing `url` on activity items) before implementation started — saved a rework cycle
- Clean separation of pure functions (`relativeDate`, `buildActivityFeed`) from React components made testing straightforward
- Existing `TeamMemberGitHubData` interface and `useTeam` hook required zero modifications to the data flow

### Challenges Encountered
- **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.
- **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.

### What Would Be Done Differently
- Check data completeness (all fields available) during spec writing rather than assuming "all data is already available"

## Technical Debt
- No Playwright E2E tests for the new UI — existing team tab E2E tests only verify API contract and tab visibility, not rendered content

## Consultation Feedback

### Specify Phase (Round 1)

#### Gemini (REQUEST_CHANGES)
- **Concern**: `recentActivity` items lack `url` — spec claims frontend-only but can't link activity items
- **Addressed**: Updated spec to include minimal backend fix

#### Codex (REQUEST_CHANGES)
- **Concern**: Relative date format under-specified; empty state for `github_data: null` unclear; CSS truncation needs bounds; testing should include Playwright
- **Addressed**: Added relative date format spec, null vs empty distinction, CSS truncation requirement
- **Rebutted**: Playwright coverage deferred as out of scope for ~250 LOC change

#### Claude (COMMENT)
- **Concern**: Same URL gap; suggested truncation guidance and date formatting utility
- **Addressed**: All points incorporated into spec revision

### Plan Phase (Round 1)

#### Gemini (APPROVE)
- No concerns. Provided helpful CSS tip (block-level for ellipsis).

#### Codex (REQUEST_CHANGES)
- **Concern**: Missing test tasks; "entire row clickable" not explicit; sub-1h date undefined
- **Addressed**: Added test update task, explicit anchor requirement, "just now" fallback

#### Claude (APPROVE)
- No concerns.

### Implement: backend-url-fix (Round 1)

#### Gemini (APPROVE), Claude (APPROVE)
- No concerns.

#### Codex (REQUEST_CHANGES)
- **Concern**: Missing explicit `url` assertions in tests
- **Addressed**: Added `toEqual` assertions and query-level regex checks

### Implement: expanded-member-cards (Round 1)

#### All three (APPROVE)
- No concerns raised.

### Implement: activity-feed (Round 1)

#### Gemini (APPROVE), Claude (APPROVE)
- No concerns.

#### Codex (REQUEST_CHANGES)
- **Concern**: No frontend test coverage for activity feed logic
- **Addressed**: Added `activityFeed.test.ts` with 8 tests for pure functions

## Flaky Tests
No flaky tests encountered.

## Architecture Updates
Updated `codev/resources/arch.md` Team View section to reflect:
- Member cards now show clickable issue/PR title lists (not just counts)
- Added combined activity feed description

## Lessons Learned Updates
No lessons learned updates needed — straightforward frontend enhancement with no novel insights beyond existing entries.

## Follow-up Items
- Add Playwright E2E tests for team page rendered content (issue/PR links, activity feed ordering)
- Consider item count cap if teams have many open issues/PRs (currently shows all)
Loading
Loading