Skip to content

RE1-T115 TTS changes and fixed issue with SystemAuth api breaking som…#358

Merged
ucswift merged 2 commits intomasterfrom
develop
May 2, 2026
Merged

RE1-T115 TTS changes and fixed issue with SystemAuth api breaking som…#358
ucswift merged 2 commits intomasterfrom
develop

Conversation

@ucswift
Copy link
Copy Markdown
Member

@ucswift ucswift commented May 2, 2026

…e api controllers

Summary by CodeRabbit

Release Notes

  • New Features

    • Expanded automated call and menu prompt library for IVR systems with additional verification and navigation options.
  • Changes

    • Updated text-to-speech default voice and speed settings for improved audio quality in automated system messages.
    • Modernized API authentication infrastructure to use OpenIddict validation as the primary authentication method.
  • Bug Fixes

    • Improved cloud storage service resilience when handling malformed response data.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 2, 2026

Warning

Rate limit exceeded

@ucswift has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 21 minutes and 15 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 80a34cb2-03ec-42de-a165-40a4895317be

📥 Commits

Reviewing files that changed from the base of the PR and between b52de41 and bbd10e3.

📒 Files selected for processing (2)
  • Tests/Resgrid.Tests/Web/Tts/S3StorageServiceTests.cs
  • Web/Resgrid.Web.Tts/Services/S3StorageService.cs
📝 Walkthrough

Walkthrough

This PR contains two independent changes: updates to TTS voice configuration (defaulting to klatt4 at speed 165 instead of klatt6 at 175), S3 storage error handling (treating malformed responses as success rather than falling back to presigned URLs), and a substantial authentication refactoring that removes legacy v3 token middleware and centralizes authorization at the base controller level.

Changes

TTS Voice Configuration & S3 Storage Refactoring

Layer / File(s) Summary
Configuration Defaults
Core/Resgrid.Config/TtsConfig.cs, Web/Resgrid.Web.Tts/Configuration/TtsOptions.cs
DefaultVoice changes from en-us+klatt6 to en-us+klatt4; DefaultSpeed changes from 175 to 165. PreGeneratedPrompts is refactored from a string literal into a string.Join(";", new[] { ... }) array and expanded with additional IVR prompt strings.
Service Logic
Web/Resgrid.Web.Tts/Services/TtsService.cs, Web/Resgrid.Web.Tts/Services/S3StorageService.cs
NormalizeVoice now treats en-us+klatt6 (case-insensitive) like the legacy en-us+f3, returning the configured default. ExistsAsync treats S3 metadata FormatException as "object exists"; HandleMalformedPutResponseAsync treats malformed PUT responses as immediate success (removing previous presigned PUT fallback and persistence verification).
Runtime & Deployment
Web/Resgrid.Web.Tts/Dockerfile, Web/Resgrid.Web.Tts/k8s/deployment.yaml
Dockerfile removes the klatt6 eSpeak NG voice data build step. ConfigMap updates both voice/speed defaults and replaces PreGeneratedPrompts with expanded IVR menu/response phrases.
Test Updates
Tests/Resgrid.Tests/Services/DepartmentSettingsServiceTtsLanguageTests.cs, Tests/Resgrid.Tests/Web/Tts/TtsServiceTests.cs, Tests/Resgrid.Tests/Web/Tts/TtsAdminControllerTests.cs, Tests/Resgrid.Tests/Web/Tts/S3StorageServiceTests.cs
Test fixtures and assertions are updated to expect klatt4/165. S3 storage tests are refactored to verify malformed PUT/metadata responses are treated as success; prior presigned-fallback test cases are removed. Legacy voice-normalization tests are consolidated.

Authentication Refactoring & Authorization Consolidation

Layer / File(s) Summary
Legacy Middleware Removal
Web/Resgrid.Web.Services/Middleware/AuthTokenMiddleware.cs, Web/Resgrid.Web.Services/Middleware/TokenAuthHandler.cs, Web/Resgrid.Web.Services/Middleware/MiddlewareExtensions.cs
Removed v3 token-based authentication middleware (including AuthTokenMiddleware, V3AuthToken, ResgridPrincipleV3 classes and ResgridTokenAuthHandler authentication handler). Deleted the UseV3AuthTokenMiddleware extension method.
Startup & Base Controller Authorization
Web/Resgrid.Web.Services/Startup.cs, Web/Resgrid.Web.Services/Controllers/v4/V4AuthenticatedApiControllerbaseSystemAuth.cs
Default authentication scheme changed from BasicAuthentication to OpenIddict.Validation.AspNetCore. BasicAuthentication scheme registration removed; SystemApiKey scheme retained. Base controller class now includes explicit [Authorize(AuthenticationSchemes = "...OpenIddict...,SystemApiKey")] attribute to centralize auth enforcement.
Controller Authorization Cleanup
Web/Resgrid.Web.Services/Controllers/v4/CallFilesController.cs, Web/Resgrid.Web.Services/Controllers/v4/CallsController.cs, Web/Resgrid.Web.Services/Controllers/v4/DepartmentsController.cs, Web/Resgrid.Web.Services/Controllers/v4/GroupsController.cs, Web/Resgrid.Web.Services/Controllers/v4/RolesController.cs, Web/Resgrid.Web.Services/Controllers/v4/UnitsController.cs
Removed class-level [Authorize(AuthenticationSchemes = "BasicAuthentication,SystemApiKey")] attribute from each controller; authorization now inherited from base controller and method-level attributes.
Documentation
Web/Resgrid.Web.Services/Resgrid.Web.Services.xml
Whitespace/formatting adjustments to V4AuthenticatedApiControllerbaseSystemAuth summary (no content changes).

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

  • RE1-T115 Updating TTS and Twilio outbound voice flow #357: Modifies TTS defaults and voice-normalization logic in the same files (TtsConfig/TtsOptions and TtsService.NormalizeVoice), changing how legacy voice variants are mapped.
  • RE1-T116 Updating API to support SMTP Relay #351: Related authentication refactoring — modifies v4 controller authorization attributes, V4AuthenticatedApiControllerbaseSystemAuth, and Startup authentication scheme registrations.
  • RE1-T115 S3 fix #354: Modifies S3StorageService behavior around malformed S3 metadata/FormatException (ExistsAsync and upload handling) and updates related S3StorageServiceTests.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title references TTS changes and SystemAuth API fixes, which align with major changes across config/test/service files, but is truncated and lacks complete specificity. Expand the truncated title to clearly describe both the TTS configuration update and the SystemAuth API controller authorization consolidation changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Tip

💬 Introducing Slack Agent: Turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get your free trial and get 200 agent minutes per Slack user (a $50 value).


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 21 minutes and 15 seconds.

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Web/Resgrid.Web.Services/Controllers/v4/V4AuthenticatedApiControllerbaseSystemAuth.cs (1)

21-79: ⚠️ Potential issue | 🟠 Major

Some inheritors correctly use GetEffectiveDepartmentId(), but others cannot support cross-department SystemApiKey requests.

Endpoints that accept departmentId parameters (e.g., GetCall, GetUnitByName) are correctly using GetEffectiveDepartmentId(). However, endpoints that don't accept departmentId parameters cannot support cross-department access in SystemApiKey mode:

  • GetCallExtraData, GetActiveCalls, GetAllUnits, GetAllRoles: These lock to the token's DepartmentId claim and will fail or return incorrect results if the relay's token department doesn't match the requested entity's department.
  • GetCallExtraData specifically validates call.DepartmentId != DepartmentId without guarding for SystemApiKey mode, guaranteeing failure for out-of-department calls.

Either add optional departmentId query parameters to these endpoints and use GetEffectiveDepartmentId(), or restrict SystemApiKey access to single-department operation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Web/Resgrid.Web.Services/Controllers/v4/V4AuthenticatedApiControllerbaseSystemAuth.cs`
around lines 21 - 79, Several controller actions (GetCallExtraData,
GetActiveCalls, GetAllUnits, GetAllRoles) incorrectly always use the token's
DepartmentId (protected DepartmentId /
ClaimsAuthorizationHelper.GetDepartmentId()) causing cross-department
SystemApiKey requests to fail; update these actions to accept an optional
departmentId query parameter (string or int?) and replace uses of DepartmentId
with GetEffectiveDepartmentId(requestDepartmentId) so SystemApiKey callers can
pass the intended department, and specifically modify GetCallExtraData's
validation (the call.DepartmentId != DepartmentId check) to use
GetEffectiveDepartmentId(...) or skip the mismatch failure when
IsSystemApiKeyRequest and a valid request department is supplied. Ensure method
signatures and all internal references use the new requestDepartmentId variable
and preserve existing behavior when no requestDepartmentId is provided.
🧹 Nitpick comments (1)
Web/Resgrid.Web.Tts/Services/S3StorageService.cs (1)

98-141: Remove unreachable dead code methods.

The following methods are unreachable after removing the presigned fallback logic:

  • WasUploadPersistedAsync (lines 98-141)
  • UploadWithPresignedUrlAsync (lines 156-207)
  • CreatePresignedHeadUrl (lines 209-219)
  • ExistsWithPresignedHeadAsync (lines 221-271)

The public UploadAsync method no longer invokes these methods; HandleMalformedPutResponseAsync simply logs and returns without attempting a fallback. Removing them reduces maintenance burden and improves code clarity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Web/Resgrid.Web.Tts/Services/S3StorageService.cs` around lines 98 - 141, The
four methods WasUploadPersistedAsync, UploadWithPresignedUrlAsync,
CreatePresignedHeadUrl, and ExistsWithPresignedHeadAsync are now dead code
because UploadAsync/HandleMalformedPutResponseAsync no longer call the
presigned-fallback path; remove these private methods from S3StorageService.cs
and also delete any helper members or using directives that only supported them
(e.g., presigned-request builders or HttpClient fields) to avoid unused
warnings, then run a compile to ensure no remaining references or tests depend
on those symbols.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Web/Resgrid.Web.Tts/Services/S3StorageService.cs`:
- Around line 83-96: HandleMalformedPutResponseAsync currently ignores payload,
contentType, and cancellationToken and assumes a FormatException means the
upload succeeded; either remove the unused parameters from the method signature
(and update all callers such as CacheService.StoreAsync to match) or add
verification logic that checks S3 for the object (e.g., a HEAD/GetObject check
using the objectKey) before returning success; update the log to reflect
verification outcome and ensure cancellationToken is honored if you perform the
verification.
- Around line 55-63: Update the exception handling in S3StorageService (the
catch blocks around metadata parsing in the method that checks object existence,
e.g., ExistsAsync) to catch AmazonUnmarshallingException and inspect its
InnerException for a FormatException (use a when filter like "when
(ex.InnerException is FormatException)") instead of catching FormatException
directly; log the outer AmazonUnmarshallingException and the inner
FormatException details, and either perform an explicit secondary verification
(e.g., a safe HEAD/get attempt) before returning true or add a clear comment
documenting the assumption that a parsing failure implies the object likely
exists so callers (like CacheService) understand the risk.

---

Outside diff comments:
In
`@Web/Resgrid.Web.Services/Controllers/v4/V4AuthenticatedApiControllerbaseSystemAuth.cs`:
- Around line 21-79: Several controller actions (GetCallExtraData,
GetActiveCalls, GetAllUnits, GetAllRoles) incorrectly always use the token's
DepartmentId (protected DepartmentId /
ClaimsAuthorizationHelper.GetDepartmentId()) causing cross-department
SystemApiKey requests to fail; update these actions to accept an optional
departmentId query parameter (string or int?) and replace uses of DepartmentId
with GetEffectiveDepartmentId(requestDepartmentId) so SystemApiKey callers can
pass the intended department, and specifically modify GetCallExtraData's
validation (the call.DepartmentId != DepartmentId check) to use
GetEffectiveDepartmentId(...) or skip the mismatch failure when
IsSystemApiKeyRequest and a valid request department is supplied. Ensure method
signatures and all internal references use the new requestDepartmentId variable
and preserve existing behavior when no requestDepartmentId is provided.

---

Nitpick comments:
In `@Web/Resgrid.Web.Tts/Services/S3StorageService.cs`:
- Around line 98-141: The four methods WasUploadPersistedAsync,
UploadWithPresignedUrlAsync, CreatePresignedHeadUrl, and
ExistsWithPresignedHeadAsync are now dead code because
UploadAsync/HandleMalformedPutResponseAsync no longer call the
presigned-fallback path; remove these private methods from S3StorageService.cs
and also delete any helper members or using directives that only supported them
(e.g., presigned-request builders or HttpClient fields) to avoid unused
warnings, then run a compile to ensure no remaining references or tests depend
on those symbols.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 023da492-20ea-44f4-bed3-9ad102ce6158

📥 Commits

Reviewing files that changed from the base of the PR and between 68625b6 and b52de41.

📒 Files selected for processing (22)
  • Core/Resgrid.Config/TtsConfig.cs
  • Tests/Resgrid.Tests/Services/DepartmentSettingsServiceTtsLanguageTests.cs
  • Tests/Resgrid.Tests/Web/Tts/S3StorageServiceTests.cs
  • Tests/Resgrid.Tests/Web/Tts/TtsAdminControllerTests.cs
  • Tests/Resgrid.Tests/Web/Tts/TtsServiceTests.cs
  • Web/Resgrid.Web.Services/Controllers/v4/CallFilesController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/CallsController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/DepartmentsController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/GroupsController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/RolesController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/UnitsController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/V4AuthenticatedApiControllerbaseSystemAuth.cs
  • Web/Resgrid.Web.Services/Middleware/AuthTokenMiddleware.cs
  • Web/Resgrid.Web.Services/Middleware/MiddlewareExtensions.cs
  • Web/Resgrid.Web.Services/Middleware/TokenAuthHandler.cs
  • Web/Resgrid.Web.Services/Resgrid.Web.Services.xml
  • Web/Resgrid.Web.Services/Startup.cs
  • Web/Resgrid.Web.Tts/Configuration/TtsOptions.cs
  • Web/Resgrid.Web.Tts/Dockerfile
  • Web/Resgrid.Web.Tts/Services/S3StorageService.cs
  • Web/Resgrid.Web.Tts/Services/TtsService.cs
  • Web/Resgrid.Web.Tts/k8s/deployment.yaml
💤 Files with no reviewable changes (10)
  • Web/Resgrid.Web.Tts/Dockerfile
  • Web/Resgrid.Web.Services/Controllers/v4/DepartmentsController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/CallsController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/RolesController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/CallFilesController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/UnitsController.cs
  • Web/Resgrid.Web.Services/Controllers/v4/GroupsController.cs
  • Web/Resgrid.Web.Services/Middleware/TokenAuthHandler.cs
  • Web/Resgrid.Web.Services/Middleware/MiddlewareExtensions.cs
  • Web/Resgrid.Web.Services/Middleware/AuthTokenMiddleware.cs

Comment thread Web/Resgrid.Web.Tts/Services/S3StorageService.cs Outdated
Comment thread Web/Resgrid.Web.Tts/Services/S3StorageService.cs Outdated
@ucswift
Copy link
Copy Markdown
Member Author

ucswift commented May 2, 2026

Approve

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.

This PR is approved.

@ucswift ucswift merged commit a89099c into master May 2, 2026
18 of 19 checks passed
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.

1 participant