feat(meetings): enforce YouTube title 100-char limit (LFXV2-2534)#1040
feat(meetings): enforce YouTube title 100-char limit (LFXV2-2534)#1040andrest50 wants to merge 8 commits into
Conversation
When YouTube uploads are enabled the upload handler appends " - DD/MM/YYYY" (13 chars) to the meeting title, so the title itself must be ≤ 87 chars to stay within the YouTube API's 100-char video title limit. - Add YOUTUBE_MAX_TITLE_LENGTH, YOUTUBE_TITLE_DATE_SUFFIX_LENGTH, and YOUTUBE_MAX_MEETING_TITLE_LENGTH constants - Dynamically add/remove Validators.maxLength(87) on the title control whenever youtube_upload_enabled changes - Show conditional char counter under title in Meeting Details step (color-coded amber at 90 % and red past the limit) - Show inline error on title field when maxlength is exceeded - Add warning banner on Platform & Features step when YouTube is on but the title is already too long, with a button to navigate back to Meeting Details; forward navigation is also blocked until fixed Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
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 (2)
WalkthroughAdds shared YouTube title-length constants, conditionally applies a maxlength validator to the meeting title field when YouTube uploads are enabled, and shows YouTube-specific limit messaging in the meeting details and platform-features steps. ChangesYouTube Title Length Validation
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Comment |
There was a problem hiding this comment.
Pull request overview
Adds YouTube-specific meeting-title length enforcement to prevent upload failures caused by the YouTube 100-character title cap (accounting for an auto-appended date suffix).
Changes:
- Introduces shared constants for the YouTube title cap, date suffix length, and effective max meeting title length.
- Dynamically enforces a max-length validator on the meeting
titlefield whenyoutube_upload_enabledis enabled. - Adds UI feedback: a character counter + inline error in Meeting Details, and a warning banner in Platform & Features with navigation back to fix the title.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/shared/src/constants/meeting.constants.ts | Adds derived constants defining the effective YouTube-safe meeting title length. |
| apps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.ts | Subscribes to youtube_upload_enabled changes to add/remove a max-length validator on title. |
| apps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.html | Wires a new child output to navigate back to Meeting Details from the warning banner. |
| apps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.ts | Exposes YouTube title limit + emits navigation event for “fix title” action. |
| apps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.html | Displays warning banner when YouTube uploads are enabled and the title exceeds the max length. |
| apps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.ts | Exposes YouTube title limit for template display. |
| apps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.html | Shows conditional character counter + maxlength validation message for YouTube-enabled meetings. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/modules/meetings/components/meeting-details/meeting-details.component.html`:
- Around line 47-50: The YouTube max-length validator is being recreated instead
of reused, so removeValidators in the meeting details form cannot clear the
earlier one. Update the validation logic in the meeting details component so the
same maxLength validator instance is cached and reused for both adding and
removing, or rebuild the validators list when the YouTube toggle changes. Use
the relevant form setup and toggle-handling code in MeetingDetailsComponent to
ensure the title control’s validator reference stays stable.
In
`@apps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.ts`:
- Around line 186-199: The validator handling in meeting-manage.component.ts is
using a fresh Validators.maxLength(...) reference for removal, so the previously
added max-length rule on the title control will not be cleared. Update the
youtube_upload_enabled subscription logic to reuse the same validator instance
for both addValidators and removeValidators, or manage the title control’s
validators as a full set. Use the existing title control inside the subscription
and keep the reusable validator tied to the MeetingManageComponent logic.
🪄 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: e4efa8c2-bc2f-40a8-b91c-df772ac2dfb1
📒 Files selected for processing (7)
apps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.tsapps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.htmlapps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.tspackages/shared/src/constants/meeting.constants.ts
🚀 Deployment StatusYour branch has been deployed to: https://ui-pr-1040.dev.v2.cluster.linuxfound.info Deployment Details:
The deployment will be automatically removed when this PR is closed. |
Validators.maxLength() returns a new function instance on every call, so removeValidators(Validators.maxLength(...)) was silently failing — Angular compares validators by reference. Storing the instance as a class property ensures add and remove operate on the same reference. Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
audigregorie
left a comment
There was a problem hiding this comment.
Code Review Summary
Solid, well-targeted fix. The validator wiring (single Validators.maxLength instance, add/remove on youtube_upload_enabled valueChanges, paired updateValueAndValidity) and the updateCanProceed look-ahead change correctly block Next/Create Meeting when a previous step becomes invalid. Main feedback is around extracting the repeated title.length expression to a computed() per the project's init*() convention, a few minor naming/wording polish items, and dropping a couple of "what" comments per global-rules.mdc.
What's done well
- Validator instance reused (
private readonly youtubeMaxLengthValidator = Validators.maxLength(...)) so add/remove reference the same object. - Constants derived from the YouTube API limit and the appended date suffix (single source of truth).
updateCanProceednow validates prior steps viacanNavigateToStep(next)— correctly handles cross-step invalidity (the actual reason behind therefresh canProceed on youtube togglecommit).- Modern Angular surface area:
input.required,output(),takeUntilDestroyed(destroyRef),@if, signals throughout.
Rating: 4/5
MRashad26
left a comment
There was a problem hiding this comment.
Code Review — PR #1040 feat(meetings): enforce YouTube title 100-char limit (LFXV2-2534)
Overview
Adds end-to-end enforcement of YouTube's 100-char video title limit. Three new shared constants (YOUTUBE_MAX_TITLE_LENGTH = 100, YOUTUBE_TITLE_DATE_SUFFIX_LENGTH = 13, YOUTUBE_MAX_MEETING_TITLE_LENGTH = 87) drive a dynamic Validators.maxLength(87) added/removed via valueChanges on youtube_upload_enabled. Meeting Details step gains a color-coded character counter and an inline validation error; Platform & Features step gains a warning banner with a "Go back" button that emits a new goToDetailsStep output. updateCanProceed is fixed to check forward-navigation validity rather than current-step validity so the Next button correctly blocks when the title exceeds the limit.
Secrets / critical-constants check ✅
No secrets or hardcoded credentials introduced. The YouTube API limit and date-suffix length are functional constants, correctly placed in @lfx-one/shared/constants.
Code-standards audit
| # | Severity | Finding |
|---|---|---|
| 1 | 🔵 Info | [ngClass] in meeting-details evaluates form().get('title')?.value?.length 4× per CD cycle — not reactive in zoneless mode |
Code quality notes
YOUTUBE_MAX_MEETING_TITLE_LENGTH = YOUTUBE_MAX_TITLE_LENGTH - YOUTUBE_TITLE_DATE_SUFFIX_LENGTHis the right derivation pattern — the limit self-documents and stays in sync if the suffix ever changes. ✅valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(...)withaddValidators/removeValidators+updateValueAndValidity()is the correct reactive-forms pattern (noeffect()). ✅private readonly youtubeMaxLengthValidator = Validators.maxLength(...)— storing the validator instance is required forremoveValidatorsidentity comparison; this is correct. ✅output<number>()forgoToDetailsStep+(goToDetailsStep)="goToStep($event)"— clean Angular 20 output pattern. ✅updateCanProceedfix: checkingcanNavigateToStep(currentStep + 1)rather thanisStepValid(currentStep)ensures the maxlength validator blocks forward navigation correctly. ✅
Verdict: PASS ✅ (1 info)
All standards pass. The info item below is a performance + reactivity improvement — not blocking.
- Add MEETING_DETAILS_STEP constant to shared meeting.constants.ts - Add titleLength computed signal and youtubeAmberThreshold to MeetingDetailsComponent - Add titleLength computed signal and meetingDetailsStep property to MeetingPlatformFeaturesComponent - Rename goToDetailsStep output to goToStep for consistency with meeting-resources-summary - Replace five inline form().get(title).value.length expressions with titleLength() - Tighten hint text: remove YouTube API 100-char detail, use full word characters - Trim warning banner: drop redundant third paragraph, keep sentence + action button - Replace hardcoded step 2 with MEETING_DETAILS_STEP constant - Remove what comments per global-rules.mdc - Add ordering guarantee comment on youtube_upload_enabled subscription Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/modules/meetings/components/meeting-details/meeting-details.component.ts`:
- Line 74: The titleLength signal is currently derived from plain Reactive Forms
state in MeetingDetailsComponent, so it won’t stay in sync as the user types.
Update the MeetingDetailsComponent logic to derive titleLength from the title
control’s valueChanges using toSignal, or otherwise bind the title control value
directly so the counter updates live; use the existing title control in the
form() lookup as the source of truth.
In
`@apps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.ts`:
- Line 30: The title character count is currently derived with computed() from
the form object only, so it will not update when the FormControl value changes.
Update MeetingPlatformFeaturesComponent’s titleLength to derive from the title
control stream by using the title control’s valueChanges (preferably converted
to a signal) so the count stays in sync after edits.
🪄 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: 0dd04049-e59e-45ab-a00e-9272f2df062b
📒 Files selected for processing (7)
apps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.tsapps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.htmlapps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.tspackages/shared/src/constants/meeting.constants.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.html
- apps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.html
- apps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.ts
computed() depends only on the form input signal (the FormGroup reference), so it returns stale character counts when the user types. toSignal() + toObservable(form) + switchMap(ctrl.valueChanges) subscribes to the RxJS valueChanges stream, making the counter and ngClass colours update reactively on every keystroke in both zone and zoneless mode. Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
Summary
YOUTUBE_MAX_TITLE_LENGTH,YOUTUBE_TITLE_DATE_SUFFIX_LENGTH, andYOUTUBE_MAX_MEETING_TITLE_LENGTHconstants tomeeting.constants.tsValidators.maxLength(87)on thetitleform control wheneveryoutube_upload_enabledchangesBackground
The YouTube Data API enforces a 100-character video title limit. The upload handler in
itx-service-zoomautomatically appends- DD/MM/YYYY(13 chars) to the meeting title when uploading, leaving an effective limit of 87 characters for the meeting title itself. Titles exceeding this cause aninvalidTitleAPI rejection and get stuck inin_progressupload state (see PCC-1315 for the incident that surfaced this).Screenshots
This shows what the validation error looks like when you set the meeting title too long when the youtube upload is already enabled.

This shows what the text looks like when the meeting title is within its character limit for a meeting that has youtube upload enabled.

This shows the warning the user gets when they try to enable youtube uploads for a meeting that has too long of a title.

Ticket
LFXV2-2534
Test plan
🤖 Generated with Claude Code