Skip to content

feat(weekly-brief): AI Assistant card on committee overview#778

Draft
manishdixitlfx wants to merge 9 commits into
feat/wg-weekly-brief-angular-servicefrom
feat/wg-weekly-brief-ui-card
Draft

feat(weekly-brief): AI Assistant card on committee overview#778
manishdixitlfx wants to merge 9 commits into
feat/wg-weekly-brief-angular-servicefrom
feat/wg-weekly-brief-ui-card

Conversation

@manishdixitlfx
Copy link
Copy Markdown
Contributor

@manishdixitlfx manishdixitlfx commented May 24, 2026

Tracking: LFXV2-1984 (part of Epic LFXV2-1976)


Summary

Wires up the WG Weekly Brief end-to-end: AI Assistant card component on the Committee Overview page, with Playwright e2e coverage. Largest of the 8 PRs (component + template + styles + tests + several review-iteration fixes folded in).

What's new

  • apps/lfx-one/src/app/modules/committees/components/weekly-brief-card/ — component (TS + HTML + SCSS) covering all card states: empty, generating, generated, edited, approved, error, throttle-exceeded, edit-mode
  • apps/lfx-one/src/app/modules/committees/components/committee-overview/ — moves the AI Assistant card above pending actions
  • apps/lfx-one/src/app/shared/components/textarea/ — small enhancement for the edit-mode textarea
  • packages/shared/src/constants/weekly-brief.constants.tsWEEKLY_BRIEF_DEFAULT_THROTTLE
  • apps/lfx-one/e2e/weekly-brief-card.spec.ts — Playwright spec covering card state transitions
  • COMMITTEE_SERVICE_URL env override on the BFF: lets you point at a locally-running committee-service without retargeting LFX_V2_SERVICE globally (dev convenience)

Notes

  • refresh$ = new BehaviorSubject<void>(undefined) is a refresh trigger (legitimate RxJS pattern, not simple state)
  • All other state uses signal() (fetchLoading, generating, saving, editMode)
  • The earlier fix(review): ... commits in this branch addressed reviewer findings on prior iterations of this card — they're folded in here for a clean diff

Stack

PR 4/4 on lfx-self-serve. Base = PR #777 (angular-service).

Test plan

  • yarn lint / yarn build green (verified)
  • yarn e2e -- weekly-brief-card.spec.ts passes
  • All card states render correctly when stepping through mock data
  • Throttle 429 surfaces inline; 409 prompts reload

Copilot AI review requested due to automatic review settings May 24, 2026 18:56
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 24, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f8a540b7-ede1-4755-bfeb-97461eee2cbf

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/wg-weekly-brief-ui-card

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR titles must follow Conventional Commits. Love from, Your reviewers ❤️.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR wires up the WG Weekly Brief “AI Assistant” card end-to-end on the Committee Overview page, adds shared throttle defaults, and introduces Playwright e2e coverage for key card states and transitions.

Changes:

  • Added a new WeeklyBriefCardComponent (template + logic) and mounted it above “My Pending Actions” on committee overview behind an OpenFeature flag.
  • Centralized default throttle counters into a shared constant consumed by both the BFF and Angular fallback paths.
  • Added Playwright e2e tests for feature-flag gating, empty/generated states, generate-from-empty, and edit→save round-trip.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/shared/src/constants/weekly-brief.constants.ts Adds shared default weekly-brief throttle constants.
packages/shared/src/constants/index.ts Re-exports weekly-brief constants from the shared constants barrel.
apps/lfx-one/src/server/services/weekly-brief.service.ts Uses shared throttle defaults and adds COMMITTEE_SERVICE_URL override routing for live calls.
apps/lfx-one/src/server/controllers/weekly-brief.controller.ts Updates route comments to reflect /api/... paths.
apps/lfx-one/src/app/shared/services/weekly-brief.service.ts Uses shared throttle defaults for empty-envelope fallback and updates logging.
apps/lfx-one/src/app/shared/components/textarea/textarea.component.ts Adds dataTestId input for data-testid support.
apps/lfx-one/src/app/shared/components/textarea/textarea.component.html Binds data-testid attribute from the new dataTestId input.
apps/lfx-one/src/app/modules/committees/components/weekly-brief-card/weekly-brief-card.component.ts Introduces the AI Assistant card component behavior (fetch, generate, edit/save, copy).
apps/lfx-one/src/app/modules/committees/components/weekly-brief-card/weekly-brief-card.component.html Implements card UI for loading/empty/generated/edit states and throttling display.
apps/lfx-one/src/app/modules/committees/components/weekly-brief-card/weekly-brief-card.component.scss Adds stylesheet placeholder (license header).
apps/lfx-one/src/app/modules/committees/components/committee-overview/committee-overview.component.ts Adds feature-flag signal and imports the weekly brief card component.
apps/lfx-one/src/app/modules/committees/components/committee-overview/committee-overview.component.html Conditionally renders the weekly brief card based on flag + edit permissions.
apps/lfx-one/e2e/weekly-brief-card.spec.ts Adds Playwright e2e coverage for weekly brief card gating and key flows.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/lfx-one/src/server/services/weekly-brief.service.ts
Comment thread apps/lfx-one/src/server/services/weekly-brief.service.ts Outdated
Comment thread apps/lfx-one/e2e/weekly-brief-card.spec.ts Outdated
Comment thread apps/lfx-one/src/server/services/weekly-brief.service.ts
Copilot AI review requested due to automatic review settings May 24, 2026 19:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 9 comments.

Comment thread apps/lfx-one/src/server/services/weekly-brief.service.ts Outdated
Comment thread wg-weekly-brief-rebuild-prompts.md Outdated
Comment thread wg-weekly-brief-implementation-status.md Outdated
Comment thread wg-weekly-brief-implementation-status.md Outdated
Comment thread apps/lfx-one/src/server/services/weekly-brief.service.ts Outdated
Comment thread apps/lfx-one/e2e/weekly-brief-card.spec.ts Outdated
Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>
@manishdixitlfx manishdixitlfx force-pushed the feat/wg-weekly-brief-angular-service branch from 8952067 to 6baa70b Compare May 24, 2026 21:06
…w integration

Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>
- Reorder class members per component-organization.md (injections before inputs;
  refresh$ in helpers band)
- Replace raw textarea + (input) handler with ReactiveForms FormControl
- Approved badge: green -> emerald (brand success scale)
- Add data-testid attributes on 8 interactive elements + empty state
- Guard onGenerate against re-entrant clicks while generating
- Log clipboard write failure via console.warn for DataDog RUM

Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>
Covers: feature-flag gating, empty state, generated state, edit/save
round-trip, and generate-from-empty happy path. Closes learnings-reviewer
finding on missing empty-state e2e coverage.

Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>
Position the AI Assistant card between the meetings section and pending
actions for better discoverability. Visible to all users with writer access.

Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>
Allow COMMITTEE_SERVICE_URL env var to bypass LFX_V2_SERVICE gateway
when testing against a locally-running committee-service instance.
Falls back to LFX_V2_SERVICE proxy when not set.

Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>
…vice override

Address post-commit code-reviewer findings on 4b4069cf:
- Use req.bearerToken (matches MicroserviceProxyService) instead of the
  raw Authorization header, so OIDC / impersonation / refreshed tokens
  flow correctly into the local-dev override path.
- Throw MicroserviceError.fromMicroserviceResponse so upstream 429/409
  status codes propagate through apiErrorHandler instead of collapsing
  to a generic 500.
- Guard empty / 204 No Content responses before JSON.parse to avoid
  SyntaxError on success paths.
- Widen method union to match proxyRequest's accepted methods.
- Add logger.debug to document the dispatch decision.
- Document that the direct-fetch bypass is deliberate for the local-dev
  override (vs MicroserviceProxyService) so reviewers don't re-flag it.

Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>
Consolidated post-commit + full-branch sweep findings:
- Throw MicroserviceError on 204/empty body instead of returning
  undefined-cast-as-T (fixes generic-return-type-lies Critical).
- Tighten getCurrentBrief catch to instanceof MicroserviceError;
  drop dead error?.status === 404 defensiveness.
- Add /api prefix to weekly-brief controller JSDoc (matches mounted
  path in server.ts).
- Promote throttle defaults to WEEKLY_BRIEF_DEFAULT_THROTTLE shared
  constant; consume from BFF and Angular client so future policy
  changes propagate (fixes hardcoded-list-duplicates-config).
- Guard onSave against empty/whitespace brief text.
- Pipe onGenerate/onSave subscriptions through take(1) per frontend
  checklist §6 (no bare .subscribe).
- Replace raw <textarea> with lfx-textarea wrapper per checklist §2.
- Log via console.warn when client catchError swallows an HTTP error
  so real upstream failures aren't silenced (combined with the BFF's
  404-to-empty-envelope normalization).

Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>
manishdixitlfx added a commit that referenced this pull request May 24, 2026
Address copilot-pull-request-reviewer comments:

- apps/lfx-one/src/server/services/weekly-brief.service.ts
  (proxyToCommitteeService):
  * URL: use `new URL(path, overrideUrl)` so trailing-slash variants on
    COMMITTEE_SERVICE_URL don't produce `//path` or drop the path.
  * Defaults: append DEFAULT_QUERY_PARAMS (`v=1`) on the override path so
    behaviour matches MicroserviceProxyService.proxyRequest.
  * Timeout: 15s AbortSignal.timeout(...) — a hung local committee-
    service no longer wedges the BFF request.
  * Body parse: read response.text() first, then JSON.parse with a
    catch — empty/non-JSON 2xx bodies now surface as 502 BAD_GATEWAY
    via MicroserviceError instead of a raw SyntaxError 500.
  * 204 / empty body: map to 502 (the weekly-brief endpoints always
    return a payload on success) instead of leaking the raw 204 status
    through MicroserviceError.

- apps/lfx-one/src/app/modules/committees/components/weekly-brief-card/
  weekly-brief-card.component.ts (weekLabel + onGenerate):
  * weekLabel: format window_start / window_end with `timeZone: 'UTC'`
    so users in negative offsets don't see the start shift to the
    prior day (window_start/end are documented as UTC Sun→Sat
    boundaries).
  * onGenerate: explicit branch for 409 (edited-brief guard) — prompt
    reload and refresh$.next() instead of swallowing as "Failed to
    generate brief". Distinct from 429 (throttle exhausted).

- apps/lfx-one/src/app/modules/committees/components/weekly-brief-card/
  weekly-brief-card.component.html:
  * Generating branch now fires on `generating() || brief()?.state ===
    'generating'` — backend-side persisted-generating state no longer
    falls through to the normal brief UI.
  * Added explicit `brief()?.state === 'error'` branch with a Try
    again button (uses canGenerate gating).

- apps/lfx-one/e2e/weekly-brief-card.spec.ts (mockCurrentBrief):
  * Helper is now async and awaits page.route() — no more race with
    page.goto() that could let real-network requests leak through.
  * All four call sites updated to await the helper.

Resolves 14 review threads (the 3 doc-related threads — about
wg-weekly-brief-rebuild-prompts.md / -implementation-status.md — are
addressed by the rebase that dropped those commits; the files no
longer exist in this branch).

Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>
@manishdixitlfx manishdixitlfx force-pushed the feat/wg-weekly-brief-ui-card branch from 3a094fc to 6504343 Compare May 24, 2026 21:10
@manishdixitlfx
Copy link
Copy Markdown
Contributor Author

Review Feedback Addressed

Commit: 6504343

Changes Made (per copilot-pull-request-reviewer)

  • apps/lfx-one/src/server/services/weekly-brief.service.ts (proxyToCommitteeService):
    • URL: now uses new URL(path, overrideUrl) with trailing-slash guard
    • Defaults: appends DEFAULT_QUERY_PARAMS (v=1), matching MicroserviceProxyService
    • Timeout: 15s AbortSignal.timeout
    • Body parsing: text() + try/catch JSON.parse; empty/non-JSON 2xx → 502 BAD_GATEWAY
    • 204 / empty body → 502 (the endpoints always return a payload on success)
  • apps/lfx-one/src/app/modules/committees/components/weekly-brief-card/weekly-brief-card.component.ts:
    • weekLabel formats with timeZone: 'UTC' for both window boundaries
    • onGenerate handles 409 explicitly — prompts reload + refresh$.next() (distinct from 429)
  • apps/lfx-one/src/app/modules/committees/components/weekly-brief-card/weekly-brief-card.component.html:
    • Generating branch fires on local generating() OR backend state === 'generating'
    • New state === 'error' branch with a Try again button
  • apps/lfx-one/e2e/weekly-brief-card.spec.ts:
    • mockCurrentBrief is async and awaits page.route(); all 4 call sites updated

Scope cleanup

The two planning docs (wg-weekly-brief-rebuild-prompts.md and wg-weekly-brief-implementation-status.md) that contained PII / duplicate content have been dropped from this branch via rebase — they were scope-creep on a UI-card PR.

Threads Resolved

14 of 14 unresolved threads addressed in this iteration.

Address copilot-pull-request-reviewer comments:

- apps/lfx-one/src/server/services/weekly-brief.service.ts
  (proxyToCommitteeService):
  * URL: use `new URL(path, overrideUrl)` so trailing-slash variants on
    COMMITTEE_SERVICE_URL don't produce `//path` or drop the path.
  * Defaults: append DEFAULT_QUERY_PARAMS (`v=1`) on the override path so
    behaviour matches MicroserviceProxyService.proxyRequest.
  * Timeout: 15s AbortSignal.timeout(...) — a hung local committee-
    service no longer wedges the BFF request.
  * Body parse: read response.text() first, then JSON.parse with a
    catch — empty/non-JSON 2xx bodies now surface as 502 BAD_GATEWAY
    via MicroserviceError instead of a raw SyntaxError 500.
  * 204 / empty body: map to 502 (the weekly-brief endpoints always
    return a payload on success) instead of leaking the raw 204 status
    through MicroserviceError.

- apps/lfx-one/src/app/modules/committees/components/weekly-brief-card/
  weekly-brief-card.component.ts (weekLabel + onGenerate):
  * weekLabel: format window_start / window_end with `timeZone: 'UTC'`
    so users in negative offsets don't see the start shift to the
    prior day (window_start/end are documented as UTC Sun→Sat
    boundaries).
  * onGenerate: explicit branch for 409 (edited-brief guard) — prompt
    reload and refresh$.next() instead of swallowing as "Failed to
    generate brief". Distinct from 429 (throttle exhausted).

- apps/lfx-one/src/app/modules/committees/components/weekly-brief-card/
  weekly-brief-card.component.html:
  * Generating branch now fires on `generating() || brief()?.state ===
    'generating'` — backend-side persisted-generating state no longer
    falls through to the normal brief UI.
  * Added explicit `brief()?.state === 'error'` branch with a Try
    again button (uses canGenerate gating).

- apps/lfx-one/e2e/weekly-brief-card.spec.ts (mockCurrentBrief):
  * Helper is now async and awaits page.route() — no more race with
    page.goto() that could let real-network requests leak through.
  * All four call sites updated to await the helper.

Resolves 14 review threads (the 3 doc-related threads — about
wg-weekly-brief-rebuild-prompts.md / -implementation-status.md — are
addressed by the rebase that dropped those commits; the files no
longer exist in this branch).

Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>

Refs: LFXV2-1984
Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>
@manishdixitlfx manishdixitlfx force-pushed the feat/wg-weekly-brief-angular-service branch from 6baa70b to 192bb9b Compare May 24, 2026 22:43
@manishdixitlfx manishdixitlfx force-pushed the feat/wg-weekly-brief-ui-card branch from 6504343 to d18610e Compare May 24, 2026 22:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants