feat(profile): add about me bio field to profile edit and panel - #1285
Conversation
Persist a free-text "About Me" bio in Auth0 user_metadata under the `bio` key (matches the auth-service contract). Adds the shared type, a 2000-char server-side length guard, an autoresizing textarea in the edit drawer, and the panel display binding that was previously unwired. LFXV2-2933 Signed-off-by: Fayaz G <5818912+fayazg@users.noreply.github.com>
PR SummaryMedium Risk Overview The profile edit drawer gains an About Me Shared types add Note: Persistence through NATS depends on the upstream auth-service bio contract being deployed. Reviewed by Cursor Bugbot for commit f11fe93. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughThe profile edit drawer now supports a 2,000-character About Me bio. The bio is validated, saved in user metadata, restored during profile authorization, and displayed in the profile panel. An end-to-end test covers the update flow. ChangesProfile About Me support
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Pull request overview
Adds an Auth0-backed About Me bio to profile editing and display.
Changes:
- Adds shared bio/profile types and 2,000-character validation.
- Integrates bio editing, persistence, Flow C replay, and panel display.
- Adds E2E coverage for saving and optimistic rendering.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
packages/shared/src/interfaces/user-profile.interface.ts |
Adds Auth0 bio metadata type. |
packages/shared/src/interfaces/profile.interface.ts |
Adds panel About Me data. |
apps/lfx-one/src/server/services/user.service.ts |
Validates bio length. |
apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.ts |
Wires bio into editing and saving. |
apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.html |
Adds the bio textarea. |
apps/lfx-one/src/app/layouts/profile-layout/profile-layout.component.ts |
Maps bio to panel and Flow C. |
apps/lfx-one/src/app/layouts/profile-layout/profile-layout.component.html |
Binds About Me to the panel. |
apps/lfx-one/e2e/profile-edit-drawer.spec.ts |
Tests bio save and optimistic display. |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
apps/lfx-one/src/server/services/user.service.ts (2)
256-259: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winUse one shared constant for the bio length limit.
The server check repeats
2000, which is also hard-coded in the client validator and textarea. Add a runtimePROFILE_BIO_MAX_LENGTHconstant underpackages/shared/src/constants/, export it, and use it in all three layers. Use the constant in the error message.As per coding guidelines, “Keep shared types, constants, enums, and validators in
packages/shared/(@lfx-one/shared) when they define contracts shared across the application and BFF.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/lfx-one/src/server/services/user.service.ts` around lines 256 - 259, Add and export a shared PROFILE_BIO_MAX_LENGTH constant under packages/shared/src/constants, then replace the hard-coded bio limit in the server validation, client validator, and bio textarea configuration with that constant. Update the server error message in the user service validation to interpolate the shared value, and import it through the existing `@lfx-one/shared` exports.Source: Coding guidelines
257-258: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winCentralize the bio length contract.
The server validator, form validator, and textarea repeat the same
2000literal. A future change can make the client and server accept different limits.
apps/lfx-one/src/server/services/user.service.ts#L257-L258: use an exported sharedPROFILE_BIO_MAX_LENGTHconstant in the comparison and error message.apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.ts#L60-L60: use the shared constant inValidators.maxLength.apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.html#L40-L40: bind[maxlength]to the component value backed by the shared constant.As per coding guidelines, “Keep shared types, constants, enums, and validators in
packages/shared/(@lfx-one/shared) when they define contracts shared across the application and BFF.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/lfx-one/src/server/services/user.service.ts` around lines 257 - 258, Centralize the shared bio-length contract in `@lfx-one/shared` by exporting PROFILE_BIO_MAX_LENGTH. In apps/lfx-one/src/server/services/user.service.ts:257-258, use it for validation and the error message; in apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.ts:60, use it with Validators.maxLength; and in apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.html:40, bind maxlength to a component value backed by the shared constant.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@apps/lfx-one/src/server/services/user.service.ts`:
- Around line 256-259: Add and export a shared PROFILE_BIO_MAX_LENGTH constant
under packages/shared/src/constants, then replace the hard-coded bio limit in
the server validation, client validator, and bio textarea configuration with
that constant. Update the server error message in the user service validation to
interpolate the shared value, and import it through the existing `@lfx-one/shared`
exports.
- Around line 257-258: Centralize the shared bio-length contract in
`@lfx-one/shared` by exporting PROFILE_BIO_MAX_LENGTH. In
apps/lfx-one/src/server/services/user.service.ts:257-258, use it for validation
and the error message; in
apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.ts:60,
use it with Validators.maxLength; and in
apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.html:40,
bind maxlength to a component value backed by the shared constant.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8042561e-2a84-403c-8bf7-2d019277fb87
📒 Files selected for processing (8)
apps/lfx-one/e2e/profile-edit-drawer.spec.tsapps/lfx-one/src/app/layouts/profile-layout/profile-layout.component.htmlapps/lfx-one/src/app/layouts/profile-layout/profile-layout.component.tsapps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.htmlapps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.tsapps/lfx-one/src/server/services/user.service.tspackages/shared/src/interfaces/profile.interface.tspackages/shared/src/interfaces/user-profile.interface.ts
Drop autoResize and add a scoped override so the bio field renders as a fixed-height box with a vertical resize handle (field-sizing: fixed, min-height 80px, resize: vertical), matching the v2 prototype instead of collapsing to a single line. LFXV2-2933 Signed-off-by: Fayaz G <5818912+fayazg@users.noreply.github.com>
|
Commit Adjusted the About Me (bio) field in the profile edit drawer to match the v2 prototype:
The shared |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 844ac13. Configure here.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.scss (1)
4-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winScope the deep selector to the drawer.
Line [7] removes Angular style encapsulation for the selector that follows. Any matching
.about-me-textarea.p-textareaelement can receive these styles. Prefix the selector with:host.Based on learnings, scope component-specific deep selectors to minimize their blast radius.
Proposed fix
-::ng-deep .about-me-textarea.p-textarea { +:host ::ng-deep .about-me-textarea.p-textarea {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.scss` around lines 4 - 11, Scope the deep selector in the profile edit drawer stylesheet by prefixing `.about-me-textarea.p-textarea` with `:host`, while preserving the existing field-sizing, minimum-height, and vertical-resize declarations.Source: Learnings
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In
`@apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.scss`:
- Around line 4-11: Scope the deep selector in the profile edit drawer
stylesheet by prefixing `.about-me-textarea.p-textarea` with `:host`, while
preserving the existing field-sizing, minimum-height, and vertical-resize
declarations.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 06bdb70e-d96a-4218-aced-7abe4c7feebc
📒 Files selected for processing (3)
apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.htmlapps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.scssapps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.html
- apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.ts
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.ts:219
- Converting an empty bio to
undefinedmakes JSON omit the key. The PATCH therefore leaves an existing bio unchanged, andapplyOptimisticProfileUpdatedeliberately drops undefined values, so users cannot clear About Me once it has been set. Preserve the empty string so both persistence and the panel are cleared.
bio: formValue.bio || undefined,
apps/lfx-one/src/app/layouts/profile-layout/profile-layout.component.ts:254
- The Flow C replay path also converts an empty bio to
undefined, so clearing About Me still fails whenever the save requires management-token authorization. Preserve the empty string here as in the normal drawer save path.
bio: formData.bio || undefined,
| postal_code?: string; | ||
| phone_number?: string; | ||
| t_shirt_size?: string; | ||
| bio?: string; |
There was a problem hiding this comment.
Correct that bio isn't in lfx-v2-auth-service main yet — that's the intended landing order. The upstream contract change is in auth-service PR linuxfoundation/lfx-v2-auth-service#65 (feat(user-metadata): add bio (About Me) field), currently open. This self-serve PR is second in the sequence and should merge/deploy after #65; until then the NATS round-trip drops bio as you describe. Added an External References note to the PR description and leaving this thread open as the gating dependency.
- profile-panel: add whitespace-pre-line so a multi-line About Me keeps its line breaks in the panel (per cursor) - profile-edit-drawer.scss: scope the deep selector with :host to limit its blast radius (per coderabbitai) - shared: add PROFILE_BIO_MAX_LENGTH and use it in the server validator, form validator, and textarea maxlength instead of the repeated 2000 literal (per coderabbitai) LFXV2-2933 Signed-off-by: Fayaz G <5818912+fayazg@users.noreply.github.com>
Review Feedback AddressedCommit: Changes Made
No Change Needed (repo-wide pattern, responded on-thread)
Still Open
Threads Resolved4 of 5 unresolved threads resolved; 1 intentionally left open (upstream dependency). |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/shared/src/constants/profile.constants.ts (1)
20-20: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd an explicit type annotation to the exported constant.
Declare the type of
PROFILE_BIO_MAX_LENGTHexplicitly because it is part of the shared public contract.Proposed fix
-export const PROFILE_BIO_MAX_LENGTH = 2000; +export const PROFILE_BIO_MAX_LENGTH: number = 2000;As per coding guidelines, TypeScript files must use type annotations.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/shared/src/constants/profile.constants.ts` at line 20, Update the exported PROFILE_BIO_MAX_LENGTH constant with an explicit number type annotation, preserving its current value and public contract.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@apps/lfx-one/src/app/layouts/profile-layout/profile-panel/profile-panel.component.html`:
- Line 71: Update the bio container rendering aboutMe() to apply break-words or
an equivalent overflow-wrap style, preserving the existing whitespace-pre-line
styling while ensuring long unbroken text cannot overflow the profile rail.
---
Nitpick comments:
In `@packages/shared/src/constants/profile.constants.ts`:
- Line 20: Update the exported PROFILE_BIO_MAX_LENGTH constant with an explicit
number type annotation, preserving its current value and public contract.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9056649c-2b46-41cf-b95a-2f31dbda61c4
📒 Files selected for processing (6)
apps/lfx-one/src/app/layouts/profile-layout/profile-panel/profile-panel.component.htmlapps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.htmlapps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.scssapps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.tsapps/lfx-one/src/server/services/user.service.tspackages/shared/src/constants/profile.constants.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.html
- apps/lfx-one/src/server/services/user.service.ts
- apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.ts
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Suppressed comments (3)
apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.ts:222
- An existing bio cannot be cleared: converting the form's empty string to
undefinedmakes Angular omitbiofrom the JSON body, so the backend leaves the previous Auth0 value unchanged. Send an empty string so deleting the text is persisted.
bio: formValue.bio || undefined,
apps/lfx-one/src/app/layouts/profile-layout/profile-layout.component.ts:254
- The Flow C retry also drops an intentionally cleared bio by converting
''toundefined; after authorization, the PATCH therefore preserves the old value. Keep the empty string in this retry payload just as in the direct-save path.
bio: formData.bio || undefined,
apps/lfx-one/src/server/services/user.service.ts:260
- This runtime guard assumes
biois a string, but the controller casts untrusted JSON directly toProfileUpdateRequest. Values such as an object, number, or short array pass this check and are forwarded over NATS despite violating the auth-service string contract. Validate the type before applying the length limit.
if (metadata?.bio && metadata.bio.length > PROFILE_BIO_MAX_LENGTH) {
throw new Error(`Bio is too long (max ${PROFILE_BIO_MAX_LENGTH} characters)`);
Add break-words to the panel's About Me block so a long unbroken token or URL can't overflow the profile rail; whitespace-pre-line alone only wraps normal whitespace. Matches the email field's existing wrapping. LFXV2-2933 Signed-off-by: Fayaz G <5818912+fayazg@users.noreply.github.com>
Review Feedback AddressedCommit: Changes Made
Threads Resolved1 of 2 unresolved threads addressed this iteration. Still Open
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Suppressed comments (1)
apps/lfx-one/src/server/services/user.service.ts:259
- The length check uses JavaScript UTF-16 code units, but the upstream auth-service contract in PR #65 defines the 2,000-character limit with Go runes and explicitly tests multibyte input. This rejects valid bios containing characters outside the BMP—for example, 1,001 emoji have 1,001 runes but a JavaScript
.lengthof 2,002. The AngularValidators.maxLengthand nativemaxlengthadded in this PR have the same mismatch. Use a code-point-aware count on both server and client (and replace the native maxlength constraint with equivalent code-point-aware enforcement) so the BFF and UI match the upstream contract.
if (metadata?.bio && metadata.bio.length > PROFILE_BIO_MAX_LENGTH) {
throw new Error(`Bio is too long (max ${PROFILE_BIO_MAX_LENGTH} characters)`);
audigregorie
left a comment
There was a problem hiding this comment.
Code Review Summary
Clean, well-wired full-stack change. The shared PROFILE_BIO_MAX_LENGTH constant driving both client and server validation is the right pattern, the optimistic-update path is extended consistently across all three save paths, and the E2E stub avoids mutating the real test profile. No line-level defects found — the findings below are all meta / outside-the-diff.
Major — outside the diff
Stale doc comment in profile-panel.component.ts:20-21 — The class docstring still says "About me and LinkedIn are stubbed for now (no source yet) and therefore stay hidden until wired in a follow-up." This PR wires aboutMe from user_metadata.bio (the layout [aboutMe] binding + mapToHeaderData), so the "About me" half of that comment is now inaccurate. The PR touches profile-panel.component.html but not the .ts; update the docstring in the same change so it doesn't mislead future readers.
PR shape — commit subjects missing the (LFXV2-2933) ticket suffix — Per the repo commit rules (global-rules.mdc / .claude/rules/commit-workflow.md), every commit subject must end with the ticket reference derived from the branch (feat/LFXV2-2933 → (LFXV2-2933)). None of the 5 commits carry the suffix. The branch also contains a merge commit (Merge branch 'main' into feat/LFXV2-2933); /lfx-self-serve-pr-readiness will flag this — rebase before opening the PR.
Upstream sequencing risk (acknowledged but worth guarding) — The PR description notes bio is not yet in lfx-v2-auth-service main (PR #65), so the NATS round-trip drops the value until #65 ships. UX impact: the user types a bio, Save closes the drawer, the optimistic update shows it — but a refetch loses it. The author already states this should merge/deploy after #65; flagging so the merge order is enforced at PR time (block merge until #65 is deployed).
Minor — outside the diff
- No server-side unit test for the bio length guard.
validateUserMetadatanow rejectsbio.length > PROFILE_BIO_MAX_LENGTH, but there's no unit test covering the new branch. The E2E covers the happy path only. A one-line assertion in the user.service spec would lock in the contract. - E2E doesn't exercise the
maxlengthboundary. S4 fills a short bio and asserts the envelope. It doesn't verify the 2000-char cap is enforced client-side (Validators.maxLength+ textarea[maxlength]). A test pasting 2001 chars and asserting Save stays disabled would close the loop.
What's done well
- Single shared
PROFILE_BIO_MAX_LENGTHconstant drives the BFF validator, the reactive-form validator, and the textarea[maxlength]— one contract across client and server. whitespace-pre-line break-wordson the panel preserves multi-line bios and prevents overflow in the 300px rail.- The optimistic-update path (
onSubmit,populateForm, Flow ChandleProfileAuthReturn,mapToHeaderData) is extended consistently — no half-wired field. - E2E stubs PATCH
/api/profileso the real test profile is never mutated, and asserts theuser_metadata.bioenvelope shape.
Rating: 4/5 — solid implementation; the blockers are merge-ordering and PR-shape hygiene, not code defects.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Suppressed comments (2)
apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.ts:222
- The optimistic value can differ from what is persisted because auth-service trims
biobefore storing it, but this path emits the raw form value. Leading/trailing whitespace—or a whitespace-only bio—appears in the panel and on drawer reopen until a reload, after which it changes or disappears. Normalize withtrim()before buildinguserMetadata, and apply the same normalization in the Flow C replay atprofile-layout.component.ts:254.
bio: formValue.bio || undefined,
apps/lfx-one/src/app/modules/profile/components/profile-edit-drawer/profile-edit-drawer.component.ts:64
- The 2,000-character limit does not match the upstream contract for non-BMP text. Angular's
maxLength, the nativemaxlength, and the BFF'sstring.lengthcount UTF-16 code units, while auth-service PR #65 deliberately capsbioat 2,000 Go runes. A bio containing emoji is therefore rejected at roughly half the upstream allowance (for example, 1,001 emoji). Please enforce the shared limit by Unicode code-point count on both client and server and avoid nativemaxlength, which cannot express that metric.
This issue also appears on line 222 of the same file.
bio: ['', [Validators.maxLength(PROFILE_BIO_MAX_LENGTH)]],

Summary
bio) field to the LFX One profile, persisted in Auth0user_metadataunder thebiokey (matches thelfx-v2-auth-servicecontract).bio?onUserMetadata,aboutMe?onProfileHeaderData.validateUserMetadata()and client-sideValidators.maxLength(...)on the drawer control, both driven by a sharedPROFILE_BIO_MAX_LENGTHconstant.lfx-textarea(fixed-height, vertically resizable per the v2 prototype), placed as the first field in Personal Information; wired throughonSubmit,populateForm, and the Flow C management-token redirect path.[aboutMe]input (renders withwhitespace-pre-lineso multi-line bios keep their line breaks).user_metadata.bioenvelope assertion.External References
linuxfoundation/lfx-v2-auth-service#65—feat(user-metadata): add bio (About Me) field.biois not yet in auth-servicemain, so the NATS round-trip drops the value until refactor(ui): comprehensive meeting registrants cleanup and optimization #65 ships. This PR should merge/deploy after refactor(ui): comprehensive meeting registrants cleanup and optimization #65.Fixes LFXV2-2933