Skip to content

Conversation

@tassoevan
Copy link
Contributor

@tassoevan tassoevan commented Feb 6, 2026

Proposed changes (including videos or screenshots)

Some record types (i.e. types that represent database documents) are not properly declaring the presence of the _updatedAt field. This PR normalizes it and refines API methods to reflect it.

Issue(s)

ARCH-1931

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • Bug Fixes

    • Custom sound uploads and renames now broadcast the actual updated sound only when the update is confirmed, improving sync accuracy.
  • User Interface

    • Removed the "Updated at" timestamp from the instance details modal for a cleaner view.
  • Refactor

    • Standardized record shapes and event payloads across several features for more consistent behavior.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Feb 6, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Feb 6, 2026

⚠️ No Changeset found

Latest commit: bde31e7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 6, 2026

Walkthrough

Centralizes record identity/timestamps under IRocketChatRecord, removes _updatedAt from many input types, updates models to return full updated CustomSound documents, changes server broadcasts to use fetched/updated sound objects, removes IInquiry, and adjusts UI/stories that displayed _updatedAt.

Changes

Cohort / File(s) Summary
Core typings — central record schema
packages/core-typings/src/IRocketChatRecord.ts, packages/core-typings/src/ICustomSound.ts, packages/core-typings/src/ICustomUserStatus.ts, packages/core-typings/src/ILivechatBusinessHour.ts, packages/core-typings/src/ILivechatDepartment.ts, packages/core-typings/src/ICronHistoryItem.ts, packages/core-typings/src/ICredentialToken.ts, packages/core-typings/src/IEmailMessageHistory.ts, packages/core-typings/src/ISmarshHistory.ts, packages/core-typings/src/IRole.ts, packages/core-typings/src/IUpload.ts, packages/core-typings/src/ISession.ts, packages/core-typings/src/IStats.ts
Introduce IRocketChatRecordSchema/IRocketChatRecord and make many interfaces extend it; remove explicit _id/_updatedAt fields from those interfaces.
Core typings — removals & specific adjustments
packages/core-typings/src/IInquiry.ts, packages/core-typings/src/IInstanceStatus.ts, packages/core-typings/src/INps.ts, packages/core-typings/src/IUser.ts, packages/core-typings/src/IOAuthRefreshToken.ts, packages/core-typings/src/IOEmbedCache.ts
Remove IInquiry; adjust IInstanceStatus to declare _id explicitly; remove or relocate various _id/_updatedAt properties and add mixed field changes (some files add new properties).
Model typings & models — CustomSounds & BusinessHours
packages/model-typings/src/models/ICustomSoundsModel.ts, packages/models/src/models/CustomSounds.ts, packages/model-typings/src/models/ILivechatBusinessHoursModel.ts, packages/models/src/models/LivechatBusinessHours.ts
CustomSounds.setName now returns `Promise<ICustomSound
Server methods — custom sounds broadcasting
apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts, apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts
Handlers now use model-returned document and broadcast only when that document exists, sending the full sound object (soundData: sound) instead of raw constructed payloads.
File upload / UFS typing narrowings
apps/meteor/app/file-upload/server/lib/FileUpload.ts, apps/meteor/app/file-upload/ufs/*/server.ts, apps/meteor/server/ufs/ufs-filter.ts, apps/meteor/server/ufs/ufs-store.ts
Narrowed many IUpload parameter types to omit _updatedAt; adjusted store/getPath signatures and call-site casts accordingly.
Client types, contexts & providers
apps/meteor/client/lib/userStatuses.ts, apps/meteor/client/providers/CustomSoundProvider/..., packages/ui-contexts/src/CustomSoundContext.ts
Client types changed to use Omit<..., '_updatedAt'> / Serialized<...> where appropriate; explicit queryFn return types added; runtime behavior unchanged.
UI/stories — removed/adjusted _updatedAt display or sample data
apps/meteor/client/views/admin/workspace/.../InstancesModal.tsx, .../InstancesModal.stories.tsx, multiple stories and components under apps/meteor/client/views/... (RoomFiles, FileItem, PermissionsTable, UsersTable stories)
Removed _updatedAt display in InstancesModal and updated story/test data to add/remove _updatedAt fields to match new typings.
Livechat & roles — typings and minor logic changes
apps/meteor/app/livechat/server/business-hour/..., apps/meteor/ee/server/lib/roles/insertRole.ts, apps/meteor/ee/server/lib/roles/updateRole.ts
Narrowed business-hour and role-related parameter types to exclude _updatedAt; small signature reformatting only.
Core services events & rest typings
packages/core-services/src/events/Events.ts, packages/rest-typings/src/v1/omnichannel.ts
Removed IInquiry import and updated livechat-inquiry-queue-observer payload to use ILivechatInquiryRecord; REST response typing updated to omit _updatedAt for saved livechat tags.
Models & data insertions — add/update timestamps
packages/models/src/models/Roles.ts, packages/models/src/models/OEmbedCache.ts, packages/models/src/models/EmailMessageHistory.ts, apps/meteor/app/importer/server/..., apps/meteor/app/importer/..., apps/meteor/app/importer/...
Some model insert paths now explicitly set _updatedAt/createdAt when constructing documents; EmailMessageHistory create uses InsertionModel param type.
Credentials & tokens models changes
packages/model-typings/src/models/ICredentialTokensModel.ts, packages/models/src/models/CredentialTokens.ts
CredentialTokens.create now returns Promise<void> (no longer returns created token); implementation adjusted accordingly.
Misc tests/mocks & small edits
apps/meteor/tests/*, apps/meteor/tests/mocks/data.ts, packages/models/src/models/LivechatRooms.ts
Test/mock data updated to include _updatedAt in places; minor comment removal in LivechatRooms.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client as Client
  participant Server as CustomSounds Service
  participant DB as Database
  participant Notify as Notify/Broadcast

  Note over Client,Server: Upload or rename request initiated
  Client->>Server: upload sound / rename request
  Server->>DB: insert / findOneAndUpdate
  DB-->>Server: returns inserted/updated document (or null)
  alt document returned
    Server->>Notify: broadcast `updateCustomSound` with full sound object
    Notify->>Client: notify clients
  else no document
    Server-->>Client: no broadcast
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐇
I hopped through types and fields anew,
Gathered records tidy as dew,
Found the sound, then gave a ring,
Only when the doc exists I sing,
A cheerful hop — the changes true.

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and accurately describes the main objective: normalizing record types to properly declare the _updatedAt field.
Linked Issues check ✅ Passed The code changes fully address the stated objective in ARCH-1931: ensuring record types correctly declare _updatedAt field by updating core TypeScript typings.
Out of Scope Changes check ✅ Passed All changes are within scope: they update type declarations, model methods, and related signatures to properly reflect the _updatedAt field across database record representations.

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


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

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

@codecov
Copy link

codecov bot commented Feb 6, 2026

Codecov Report

❌ Patch coverage is 84.21053% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.38%. Comparing base (248e4fa) to head (bde31e7).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #38528      +/-   ##
===========================================
- Coverage    70.41%   70.38%   -0.04%     
===========================================
  Files         3162     3162              
  Lines       110663   110671       +8     
  Branches     19940    19869      -71     
===========================================
- Hits         77923    77892      -31     
- Misses       30711    30750      +39     
  Partials      2029     2029              
Flag Coverage Δ
e2e 60.39% <80.00%> (-0.02%) ⬇️
e2e-api 48.78% <ø> (-0.03%) ⬇️
unit 71.33% <85.71%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

📦 Docker Image Size Report

➡️ Changes

Service Current Baseline Change Percent
sum of all images 0B 0B 0B
account-service 0B 0B 0B
authorization-service 0B 0B 0B
ddp-streamer-service 0B 0B 0B
omnichannel-transcript-service 0B 0B 0B
presence-service 0B 0B 0B
queue-worker-service 0B 0B 0B
rocketchat 0B 0B 0B

📊 Historical Trend

---
config:
  theme: "dark"
  xyChart:
    width: 900
    height: 400
---
xychart
  title "Image Size Evolution by Service (Last 30 Days + This PR)"
  x-axis ["11/18 22:53", "11/19 23:02", "11/21 16:49", "11/24 17:34", "11/27 22:32", "11/28 19:05", "12/01 23:01", "12/02 21:57", "12/03 21:00", "12/04 18:17", "12/05 21:56", "12/08 20:15", "12/09 22:17", "12/10 23:26", "12/11 21:56", "12/12 22:45", "12/13 01:34", "12/15 22:31", "12/16 22:18", "12/17 21:04", "12/18 23:12", "12/19 23:27", "12/20 21:03", "12/22 18:54", "12/23 16:16", "12/24 19:38", "12/25 17:51", "12/26 13:18", "12/29 19:01", "12/30 20:52", "02/10 14:49 (PR)"]
  y-axis "Size (GB)" 0 --> 0.5
  line "account-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.00]
  line "authorization-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.00]
  line "ddp-streamer-service" [0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.00]
  line "omnichannel-transcript-service" [0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.00]
  line "presence-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.00]
  line "queue-worker-service" [0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.00]
  line "rocketchat" [0.35, 0.35, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.00]
Loading

Statistics (last 30 days):

  • 📊 Average: 1.5GiB
  • ⬇️ Minimum: 1.4GiB
  • ⬆️ Maximum: 1.6GiB
  • 🎯 Current PR: 0B
ℹ️ About this report

This report compares Docker image sizes from this build against the develop baseline.

  • Tag: pr-38528
  • Baseline: develop
  • Timestamp: 2026-02-10 14:49:59 UTC
  • Historical data points: 30

Updated: Tue, 10 Feb 2026 14:50:00 GMT

@tassoevan tassoevan added this to the 8.2.0 milestone Feb 6, 2026
@tassoevan tassoevan marked this pull request as ready for review February 6, 2026 17:32
@tassoevan tassoevan requested review from a team as code owners February 6, 2026 17:32
Copy link
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: 1

🤖 Fix all issues with AI agents
In `@apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts`:
- Around line 32-40: The ws.on('end') handler uses an async setTimeout with a
fixed 500ms delay which is a race condition and creates unhandled promise
rejections; change this to avoid the magic timeout and to handle errors: either
(preferred) perform an atomic read-after-write (e.g., use the same insert/update
operation or a findOneAndUpdate on CustomSounds to get the final document and
broadcast immediately from that promise), or (minimal) replace the async
setTimeout with a proper promise chain that awaits CustomSounds.findOneById and
calls api.broadcast inside a try/catch so rejections are handled before calling
resolve; remove the fire-and-forget async callback to eliminate unhandled
promise rejections and reference ws.on('end'), setTimeout,
CustomSounds.findOneById and api.broadcast when making the change.
🧹 Nitpick comments (1)
apps/meteor/tests/data/livechat/department.ts (1)

200-205: delete department._updatedAt is now contradictory with the parameter type.

The parameter is typed as Omit<ILivechatDepartment, '_updatedAt'>, signaling _updatedAt shouldn't be present, yet line 202 still deletes it. This only compiles because ILivechatDepartment has an index signature ([k: string]: any). Consider removing the delete statement since the type contract already guarantees the field isn't there, or keep the original ILivechatDepartment type if the intent is to defensively strip it at runtime.

Option A: Remove the dead delete (trust the type)
 export const disableDepartment = async (department: Omit<ILivechatDepartment, '_updatedAt'>): Promise<void> => {
 	department.enabled = false;
-	delete department._updatedAt;
 	const updatedDepartment = await updateDepartment(department._id, department);
 	expect(updatedDepartment.enabled).to.be.false;
 };
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ac9065f and 50d8933.

📒 Files selected for processing (22)
  • apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts
  • apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts
  • apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts
  • apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts
  • apps/meteor/client/lib/userStatuses.ts
  • apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx
  • apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts
  • apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.stories.tsx
  • apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.tsx
  • apps/meteor/tests/data/livechat/department.ts
  • packages/core-services/src/events/Events.ts
  • packages/core-typings/src/ICustomSound.ts
  • packages/core-typings/src/ICustomUserStatus.ts
  • packages/core-typings/src/IInquiry.ts
  • packages/core-typings/src/IInstanceStatus.ts
  • packages/core-typings/src/ILivechatBusinessHour.ts
  • packages/core-typings/src/ILivechatDepartment.ts
  • packages/model-typings/src/models/ICustomSoundsModel.ts
  • packages/model-typings/src/models/ILivechatBusinessHoursModel.ts
  • packages/models/src/models/CustomSounds.ts
  • packages/models/src/models/LivechatBusinessHours.ts
  • packages/ui-contexts/src/CustomSoundContext.ts
💤 Files with no reviewable changes (3)
  • apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.stories.tsx
  • packages/core-typings/src/IInquiry.ts
  • apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • packages/core-services/src/events/Events.ts
  • apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts
  • apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts
  • packages/core-typings/src/ILivechatBusinessHour.ts
  • packages/core-typings/src/IInstanceStatus.ts
  • apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts
  • packages/core-typings/src/ICustomUserStatus.ts
  • apps/meteor/tests/data/livechat/department.ts
  • packages/model-typings/src/models/ILivechatBusinessHoursModel.ts
  • packages/model-typings/src/models/ICustomSoundsModel.ts
  • packages/models/src/models/LivechatBusinessHours.ts
  • packages/core-typings/src/ILivechatDepartment.ts
  • apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx
  • apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts
  • packages/core-typings/src/ICustomSound.ts
  • packages/models/src/models/CustomSounds.ts
  • packages/ui-contexts/src/CustomSoundContext.ts
  • apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts
  • apps/meteor/client/lib/userStatuses.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts
  • apps/meteor/tests/data/livechat/department.ts
  • packages/models/src/models/LivechatBusinessHours.ts
  • apps/meteor/client/lib/userStatuses.ts
📚 Learning: 2025-09-15T21:34:39.812Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 36717
File: packages/ui-voip/src/providers/useCallSounds.ts:6-21
Timestamp: 2025-09-15T21:34:39.812Z
Learning: The voipSounds methods (playDialer, playRinger, playCallEnded) from useCustomSound return proper offCallbackHandler cleanup functions, not void as some type definitions might suggest.

Applied to files:

  • apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts
📚 Learning: 2025-11-19T18:20:37.116Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37419
File: apps/meteor/server/services/media-call/service.ts:141-141
Timestamp: 2025-11-19T18:20:37.116Z
Learning: In apps/meteor/server/services/media-call/service.ts, the sendHistoryMessage method should use call.caller.id or call.createdBy?.id as the message author, not call.transferredBy?.id. Even for transferred calls, the message should appear in the DM between the two users who are calling each other, not sent by the person who transferred the call.

Applied to files:

  • apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts
🧬 Code graph analysis (14)
packages/core-services/src/events/Events.ts (1)
packages/core-typings/src/IInquiry.ts (1)
  • ILivechatInquiryRecord (29-55)
apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts (1)
packages/core-typings/src/ILivechatBusinessHour.ts (1)
  • ILivechatBusinessHour (33-41)
apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts (1)
packages/core-typings/src/ILivechatBusinessHour.ts (1)
  • ILivechatBusinessHour (33-41)
apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts (2)
packages/models/src/index.ts (1)
  • CustomSounds (144-144)
packages/core-services/src/index.ts (1)
  • api (55-55)
apps/meteor/tests/data/livechat/department.ts (1)
packages/core-typings/src/ILivechatDepartment.ts (1)
  • ILivechatDepartment (3-24)
packages/model-typings/src/models/ILivechatBusinessHoursModel.ts (1)
packages/core-typings/src/ILivechatBusinessHour.ts (1)
  • ILivechatBusinessHour (33-41)
packages/model-typings/src/models/ICustomSoundsModel.ts (2)
packages/core-typings/src/ICustomSound.ts (1)
  • ICustomSound (3-8)
packages/ui-contexts/src/index.ts (1)
  • FindOptions (110-110)
packages/models/src/models/LivechatBusinessHours.ts (1)
packages/core-typings/src/ILivechatBusinessHour.ts (1)
  • ILivechatBusinessHour (33-41)
apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx (1)
packages/core-typings/src/ICustomSound.ts (1)
  • ICustomSound (3-8)
apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts (1)
packages/core-typings/src/ICustomSound.ts (1)
  • ICustomSound (3-8)
packages/models/src/models/CustomSounds.ts (1)
packages/core-typings/src/ICustomSound.ts (1)
  • ICustomSound (3-8)
packages/ui-contexts/src/CustomSoundContext.ts (1)
packages/core-typings/src/ICustomSound.ts (1)
  • ICustomSound (3-8)
apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts (2)
packages/models/src/index.ts (1)
  • CustomSounds (144-144)
packages/core-services/src/index.ts (1)
  • api (55-55)
apps/meteor/client/lib/userStatuses.ts (1)
packages/core-typings/src/ICustomUserStatus.ts (1)
  • ICustomUserStatus (4-4)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
🔇 Additional comments (18)
packages/core-services/src/events/Events.ts (1)

26-26: LGTM — consistent replacement of IInquiry with ILivechatInquiryRecord.

The import and event signature change on line 74 now aligns with the existing usage on line 242 (watch.inquiries), and ILivechatInquiryRecord properly extends IRocketChatRecord (which carries _updatedAt), matching the PR objective.

Also applies to: 74-74

packages/core-typings/src/ICustomSound.ts (1)

1-8: LGTM!

Clean refactor: extending IRocketChatRecord correctly provides _id and _updatedAt for this DB document type, and the remaining fields are unchanged. Consumers that don't need _updatedAt properly use Omit<ICustomSound, '_updatedAt'> elsewhere in the PR.

packages/ui-contexts/src/CustomSoundContext.ts (1)

39-39: LGTM!

Using Omit<ICustomSound, '_updatedAt'> for the client-side list is the right approach since the UI context doesn't carry the DB timestamp.

packages/core-typings/src/IInstanceStatus.ts (1)

1-23: Correct: intentionally detaching from IRocketChatRecord since the instance-status model doesn't support _updatedAt.

This is the mirror case of the other changes in this PR — the type now accurately reflects that instance-status documents don't have an _updatedAt field.

packages/core-typings/src/ILivechatDepartment.ts (1)

1-3: LGTM!

Consistent with the PR pattern — ILivechatDepartment now correctly inherits _id and _updatedAt from IRocketChatRecord as a proper DB document type. The separate LivechatDepartmentDTO remains unchanged, which is correct.

packages/core-typings/src/ILivechatBusinessHour.ts (1)

2-2: LGTM!

Same consistent pattern — ILivechatBusinessHour now properly inherits _id and _updatedAt via IRocketChatRecord.

Also applies to: 33-33

packages/model-typings/src/models/ILivechatBusinessHoursModel.ts (1)

26-26: LGTM!

Correctly excludes _updatedAt from the insertOne input, matching the pattern used in ICustomSoundsModel.create — the DB layer auto-sets this field.

packages/model-typings/src/models/ICustomSoundsModel.ts (1)

9-10: Signatures match the implementation perfectly.

setName correctly uses findOneAndUpdate with returnDocument: 'after' to return the updated document or null. create correctly uses insertOne and returns InsertOneResult<WithId<ICustomSound>>. The type omissions for _id and _updatedAt in create's input accurately reflect DB auto-population behavior.

apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts (1)

6-6: LGTM — return type correctly reflects the constructed object shape.

The object literal provides _id but not _updatedAt, so Omit<ILivechatBusinessHour, '_updatedAt'> is an accurate representation.

packages/models/src/models/LivechatBusinessHours.ts (1)

75-80: LGTM — parameter type correctly excludes _updatedAt.

The base layer (BaseRaw.insertOne) handles _id generation and _updatedAt stamping, so excluding both from the input type is correct.

apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts (1)

4-6: LGTM — parameter type widening is correct and consistent with callers.

All fields accessed in the body (active, workHours, _id, type) remain available in Omit<ILivechatBusinessHour, '_updatedAt'>, and this aligns with createDefaultBusinessHourRow's updated return type.

packages/models/src/models/CustomSounds.ts (2)

35-43: Good refactor — setName now returns the updated document.

Switching from updateOne to findOneAndUpdate with returnDocument: 'after' is a clean approach that eliminates the need for a separate fetch when the caller needs the updated document (as in insertOrUpdateSound.ts).


46-48: LGTM — create parameter type correctly excludes _updatedAt.

apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts (1)

90-96: LGTM — properly handles nullable return and broadcasts full document.

The null guard on updatedSound correctly handles the case where the document wasn't found, and broadcasting the full updated document ensures payload consistency with the actual DB state.

apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts (1)

7-9: No changes needed. The code does not pass defaultSounds elements to getCustomSoundURL. Instead, it passes items from customSoundsList (which are full ICustomSound objects from the server method listCustomSounds(): ICustomSound[]) to the function, matching its parameter type exactly. The defaultSounds array is concatenated separately after the mapping operation, so no type mismatch occurs.

Likely an incorrect or invalid review comment.

apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx (1)

26-26: LGTM — explicit return type aligns queryFn with the updated ICustomSound shape.

The annotation correctly reflects that neither sdk.call('listCustomSounds') nor defaultSounds include _updatedAt, keeping the type consistent with the broader refactor.

apps/meteor/client/lib/userStatuses.ts (1)

36-47: LGTM — parameter type correctly narrowed to exclude _updatedAt.

The method only uses name, _id, and statusType, so Omit<ICustomUserStatus, '_updatedAt'> accurately describes the required shape. Structural subtyping ensures existing callers (lines 68, 74) remain compatible.

packages/core-typings/src/ICustomUserStatus.ts (1)

1-4: Clean consolidation — _updatedAt properly handled by InsertionModel.

By extending IRocketChatRecord, ICustomUserStatus gains a consolidated _updatedAt field. Although _updatedAt is required in the IRocketChatRecord interface, the InsertionModel<ICustomUserStatus> type utility already makes _updatedAt optional during object construction (_updatedAt?: Date), so no call site changes are needed. Existing code that inserts custom user statuses without explicitly providing _updatedAt (e.g., apps/meteor/app/user-status/server/methods/insertOrUpdateUserStatus.ts) continues to work correctly.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 22 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts">

<violation number="1" location="apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts:32">
P1: The async callback passed to `setTimeout` lacks error handling. If `CustomSounds.findOneById` rejects (e.g., due to a database error), it will result in an UnhandledPromiseRejection, which can crash the Node.js process or leave the application in an unstable state. Wrap the asynchronous operation in a `try/catch` block.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@tassoevan tassoevan force-pushed the refactor/optional-updated-at-field branch from 50d8933 to 3912614 Compare February 6, 2026 17:59
Copy link
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: 0

Caution

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

⚠️ Outside diff range comments (1)
apps/meteor/client/lib/userStatuses.ts (1)

61-70: ⚠️ Potential issue | 🔴 Critical

Type mismatch in sync() method: sdk.call('listCustomUserStatus') returns ICustomUserStatus[] but createFromCustom() expects Omit<ICustomUserStatus, '_updatedAt'>.

The listCustomUserStatus() method returns full ICustomUserStatus objects (which include _updatedAt from IRocketChatRecord), but createFromCustom() at line 36 requires Omit<ICustomUserStatus, '_updatedAt'>. Passing the full type to a function expecting the omitted type is incompatible.

The stream event at line 74 correctly provides Omit<ICustomUserStatus, '_updatedAt'> and is compatible. The sync() method should either strip _updatedAt before passing to createFromCustom(), or the method signature should accept the full ICustomUserStatus type.

🧹 Nitpick comments (1)
apps/meteor/tests/data/livechat/department.ts (1)

200-205: The Omit is effectively a no-op due to the index signature on ILivechatDepartment.

Since ILivechatDepartment declares [k: string]: any, Omit<ILivechatDepartment, '_updatedAt'> still allows _updatedAt to be accessed (as any) through the index signature. The type narrowing has no practical enforcement here—callers can still pass objects with _updatedAt, and line 202 still compiles without issue via the index signature.

This isn't a problem introduced by this PR (the index signature is pre-existing), but it's worth noting that the Omit doesn't provide the type-safety it suggests. If the index signature on ILivechatDepartment is ever tightened, this will need revisiting.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 50d8933 and 3912614.

📒 Files selected for processing (23)
  • apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts
  • apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts
  • apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts
  • apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts
  • apps/meteor/client/lib/userStatuses.ts
  • apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx
  • apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts
  • apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.stories.tsx
  • apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.tsx
  • apps/meteor/tests/data/livechat/department.ts
  • packages/core-services/src/events/Events.ts
  • packages/core-typings/src/ICronHistoryItem.ts
  • packages/core-typings/src/ICustomSound.ts
  • packages/core-typings/src/ICustomUserStatus.ts
  • packages/core-typings/src/IInquiry.ts
  • packages/core-typings/src/IInstanceStatus.ts
  • packages/core-typings/src/ILivechatBusinessHour.ts
  • packages/core-typings/src/ILivechatDepartment.ts
  • packages/model-typings/src/models/ICustomSoundsModel.ts
  • packages/model-typings/src/models/ILivechatBusinessHoursModel.ts
  • packages/models/src/models/CustomSounds.ts
  • packages/models/src/models/LivechatBusinessHours.ts
  • packages/ui-contexts/src/CustomSoundContext.ts
💤 Files with no reviewable changes (3)
  • apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.stories.tsx
  • packages/core-typings/src/IInquiry.ts
  • apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.tsx
🚧 Files skipped from review as they are similar to previous changes (8)
  • apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts
  • packages/models/src/models/LivechatBusinessHours.ts
  • apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts
  • packages/model-typings/src/models/ICustomSoundsModel.ts
  • packages/core-typings/src/ILivechatBusinessHour.ts
  • packages/models/src/models/CustomSounds.ts
  • apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx
  • packages/core-services/src/events/Events.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts
  • packages/core-typings/src/ILivechatDepartment.ts
  • packages/ui-contexts/src/CustomSoundContext.ts
  • packages/core-typings/src/ICustomSound.ts
  • packages/core-typings/src/IInstanceStatus.ts
  • packages/core-typings/src/ICronHistoryItem.ts
  • apps/meteor/client/lib/userStatuses.ts
  • apps/meteor/tests/data/livechat/department.ts
  • packages/model-typings/src/models/ILivechatBusinessHoursModel.ts
  • packages/core-typings/src/ICustomUserStatus.ts
  • apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts
  • apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts
  • packages/core-typings/src/ICronHistoryItem.ts
  • apps/meteor/client/lib/userStatuses.ts
  • apps/meteor/tests/data/livechat/department.ts
🧬 Code graph analysis (6)
apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts (1)
packages/core-typings/src/ILivechatBusinessHour.ts (1)
  • ILivechatBusinessHour (33-41)
packages/ui-contexts/src/CustomSoundContext.ts (1)
packages/core-typings/src/ICustomSound.ts (1)
  • ICustomSound (3-8)
apps/meteor/client/lib/userStatuses.ts (1)
packages/core-typings/src/ICustomUserStatus.ts (1)
  • ICustomUserStatus (4-4)
apps/meteor/tests/data/livechat/department.ts (1)
packages/core-typings/src/ILivechatDepartment.ts (1)
  • ILivechatDepartment (3-24)
packages/model-typings/src/models/ILivechatBusinessHoursModel.ts (1)
packages/core-typings/src/ILivechatBusinessHour.ts (1)
  • ILivechatBusinessHour (33-41)
apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts (1)
packages/core-typings/src/ICustomSound.ts (1)
  • ICustomSound (3-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (11)
apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts (1)

6-6: LGTM — return type correctly narrowed.

The function never sets _updatedAt (it's a seed row for DB insertion), so Omit<ILivechatBusinessHour, '_updatedAt'> accurately reflects the runtime shape. Clean alignment with the broader IRocketChatRecord type tightening.

packages/core-typings/src/ICustomUserStatus.ts (1)

1-4: LGTM — clean centralization of _updatedAt via IRocketChatRecord.

This correctly removes the locally declared optional _updatedAt in favor of inheriting the required one from IRocketChatRecord, aligning with the PR's goal of normalizing record types.

apps/meteor/client/lib/userStatuses.ts (1)

36-47: Sound type narrowing — method doesn't use _updatedAt.

The Omit<ICustomUserStatus, '_updatedAt'> correctly reflects that this method never reads _updatedAt, and it keeps callers compatible now that ICustomUserStatus inherits a required _updatedAt from IRocketChatRecord. Objects that do carry _updatedAt remain assignable, so existing call sites at lines 68 and 74 are unaffected.

packages/core-typings/src/IInstanceStatus.ts (1)

1-2: Consistent removal of IRocketChatRecord for a type without _updatedAt.

Since _updatedAt is now required on IRocketChatRecord, disconnecting IInstanceStatus and declaring _id explicitly is the correct approach for documents that don't carry an _updatedAt field.

packages/core-typings/src/ICronHistoryItem.ts (1)

1-3: LGTM!

Clean migration to IRocketChatRecord_id and _updatedAt are now inherited from the base record type, consistent with the PR's normalization goal.

packages/model-typings/src/models/ILivechatBusinessHoursModel.ts (1)

26-26: LGTM!

Omitting _updatedAt from the insertOne parameter is correct — it's auto-managed by the persistence layer, just like _id.

packages/core-typings/src/ICustomSound.ts (1)

1-7: LGTM!

Promoting _updatedAt from optional to required (via IRocketChatRecord) correctly reflects the database document shape. Downstream code that constructs objects without _updatedAt (e.g., default sounds) appropriately uses Omit<ICustomSound, '_updatedAt'>.

apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts (1)

90-95: Good improvement: broadcast now sends the actual updated document.

Broadcasting the full updatedSound returned by setName instead of a hand-assembled partial object ensures field consistency with the ICustomSound type. The guard on line 91 is also an improvement — previously the broadcast would fire even if the update was a no-op.

One minor note: if setName returns falsy (e.g., document not found), the method still returns soundData._id on line 98 as if it succeeded. Consider whether this silent no-op should surface an error to the caller.

apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts (1)

28-28: LGTM!

Omit<ICustomSound, '_updatedAt'> correctly models static default sounds that aren't database documents and don't carry _updatedAt.

packages/ui-contexts/src/CustomSoundContext.ts (1)

39-39: LGTM!

The list type is correctly widened to Omit<ICustomSound, '_updatedAt'>[] since it merges default sounds (no _updatedAt) with DB-fetched sounds — the lowest common denominator type is appropriate here.

packages/core-typings/src/ILivechatDepartment.ts (1)

1-3: Clean adoption of IRocketChatRecord as the base type.

This correctly centralizes _id and _updatedAt into the shared base record, aligning with the PR's goal of making _updatedAt a required field on document types. The DTO type below appropriately remains separate since it represents input data, not a stored document.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@tassoevan tassoevan force-pushed the refactor/optional-updated-at-field branch from 3912614 to 052278b Compare February 6, 2026 19:04
@tassoevan tassoevan marked this pull request as draft February 6, 2026 19:27
@tassoevan tassoevan force-pushed the refactor/optional-updated-at-field branch 9 times, most recently from 2cf5fba to b92bc2c Compare February 10, 2026 13:51
…ken` to extend `IRocketChatRecord` and update `create` method to return void
@tassoevan tassoevan force-pushed the refactor/optional-updated-at-field branch from 5062555 to bde31e7 Compare February 10, 2026 14:31
@tassoevan tassoevan marked this pull request as ready for review February 10, 2026 16:14
@tassoevan tassoevan requested a review from a team as a code owner February 10, 2026 16:14
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 91 files

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed.

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="packages/core-typings/src/IInstanceStatus.ts">

<violation number="1" location="packages/core-typings/src/IInstanceStatus.ts:1">
P2: IInstanceStatus is a record type but no longer requires `_updatedAt` after removing the IRocketChatRecord base. This makes the type inconsistent with the standard record shape and allows records without `_updatedAt`. Consider adding `_updatedAt` explicitly (or re-extending IRocketChatRecord) to keep the record contract intact.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
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 (3)
apps/meteor/app/importer/server/classes/converters/RecordConverter.ts (1)

155-172: ⚠️ Potential issue | 🟠 Major

addObjectToMemory is missing _updatedAt, inconsistent with addObjectToDatabase.

addObjectToDatabase now sets _updatedAt: new Date() (Line 161), but the sibling addObjectToMemory (Lines 165–172) does not. The as R cast on Line 171 silently suppresses the type error, so if IImportRecord now requires _updatedAt (as intended by this PR), in-memory records will be missing it at runtime.

Proposed fix
 public addObjectToMemory(data: R['data'], options: R['options'] = {}): void {
   this._records.push({
     _id: Random.id(),
     data,
     dataType: this.getDataType(),
     options,
+    _updatedAt: new Date(),
   } as R);
 }
apps/meteor/server/ufs/ufs-filter.ts (1)

10-10: ⚠️ Potential issue | 🟡 Minor

Type mismatch between IFilterOptions.onCheck and the Filter method signatures.

IFilterOptions.onCheck (Line 10) still accepts IUpload, but Filter.check and Filter.onCheck (Lines 62, 140) now use Omit<OptionalId<IUpload>, '_updatedAt'>. A user-provided onCheck callback would expect _updatedAt on the file parameter, but it won't be guaranteed at runtime.

Consider aligning the IFilterOptions type:

Proposed fix
 type IFilterOptions = {
 	contentTypes?: string[];
 	extensions?: string[];
 	minSize?: number;
 	maxSize?: number;
-	onCheck?: (file: IUpload, content?: Buffer | string) => Promise<boolean>;
+	onCheck?: (file: Omit<OptionalId<IUpload>, '_updatedAt'>, content?: Buffer | string) => Promise<boolean>;
 	invalidFileError?: () => Meteor.Error;

Also applies to: 62-62, 140-140

packages/models/src/models/Roles.ts (1)

249-256: ⚠️ Potential issue | 🟡 Minor

Return value has a divergent _updatedAt timestamp from what's stored in the database.

BaseRaw.insertOne sets _updatedAt: new Date() inside the method before storing the document (line 293 of BaseRaw.ts). The return statement in createWithRandomId creates a second new Date() call, resulting in a microsecond-divergent timestamp being returned to the caller versus what's actually persisted.

This pattern is used throughout the codebase (e.g., Rooms.createWithFullRoomData, TeamMember), and OEmbedCache.ts:21 even documents this with a TODO comment. Consider either:

  • Returning the result of insertOne directly if the object is available
  • Or having BaseRaw.insertOne return the full inserted document (including _updatedAt)

Also remove the inline TODO comment on line 253 to comply with the coding guideline to avoid code comments in implementation.

🤖 Fix all issues with AI agents
In `@apps/meteor/client/startup/roles.ts`:
- Line 14: The stream handler stores incoming roles without converting the JSON
`_updatedAt` string to a Date, causing type inconsistency with IRole; update the
stream-handling code that calls Roles.state.replaceAll (the counterpart to the
REST path that already does roles.map(... _updatedAt: new Date(...))) to
similarly map over incoming roles and set `_updatedAt: new
Date(role._updatedAt)` before calling Roles.state.replaceAll so Roles.state
always contains Date objects.

In `@apps/meteor/server/services/import/service.ts`:
- Line 144: The roles merge uses the Set constructor incorrectly by spreading
two iterables as separate arguments; update the roles assignment where
data.roles and defaultRoles are combined (the expression referencing data.roles,
defaultRoles and Set) to pass a single iterable that concatenates data.roles and
defaultRoles into new Set and then spread that Set into an array so duplicates
are removed (i.e., combine data.roles and defaultRoles into one array, build a
Set from that array, and spread the Set back into the roles array).
🧹 Nitpick comments (6)
packages/models/src/models/OEmbedCache.ts (1)

16-25: TODO comment should be removed or resolved; timestamps could drift.

Two observations on this change:

  1. The TODO comment on line 21 violates the coding guideline to avoid code comments in implementation files. If BaseRaw.insertOne reliably sets _updatedAt, remove the manual assignment entirely. If it doesn't, remove the comment and keep the assignment as intentional.

  2. updatedAt (line 20) and _updatedAt (line 21) are created from separate new Date() calls, which could yield slightly different timestamps under load. Consider capturing the date once:

Suggested fix
 async createWithIdAndData(_id: string, data: any): Promise<IOEmbedCache> {
+  const now = new Date();
   const record = {
     _id,
     data,
-    updatedAt: new Date(),
-    _updatedAt: new Date(), // TODO: insertOne inserts the field `_updatedAt` synchronously but it's not guaranteed
+    updatedAt: now,
+    _updatedAt: now,
   };
   record._id = (await this.insertOne(record)).insertedId;
   return record;
 }

As per coding guidelines, implementation files matching **/*.{ts,tsx,js} should "Avoid code comments in the implementation".

apps/meteor/tests/data/livechat/department.ts (1)

200-205: delete department._updatedAt is now redundant given the Omit type.

Since the parameter type is Omit<ILivechatDepartment, '_updatedAt'>, callers should never pass _updatedAt. The delete on line 202 is dead code from a typing perspective. Note that the index signature ([k: string]: any) on ILivechatDepartment undermines the Omit — TypeScript still allows _updatedAt to be accessed as any through the index signature, so the Omit only provides documentation-level intent, not enforcement.

Consider removing the redundant delete to keep the code consistent with the type declaration, or add a brief comment explaining why it's retained as a defensive measure.

♻️ Optional cleanup
 export const disableDepartment = async (department: Omit<ILivechatDepartment, '_updatedAt'>): Promise<void> => {
 	department.enabled = false;
-	delete department._updatedAt;
 	const updatedDepartment = await updateDepartment(department._id, department);
 	expect(updatedDepartment.enabled).to.be.false;
 };
packages/core-typings/src/IOEmbedCache.ts (1)

1-5: updatedAt and _updatedAt coexist — potential confusion.

After extending IRocketChatRecord, this interface now has both _updatedAt (inherited) and updatedAt (local, line 5). The TODO correctly flags this, but it's worth tracking as a follow-up to avoid consumers updating the wrong field. Consider opening an issue to unify these.

The TODO comment on line 5 also conflicts with the coding guideline to avoid code comments. As per coding guidelines, **/*.{ts,tsx,js}: "Avoid code comments in the implementation."

Would you like me to open a new issue to track the updatedAt / _updatedAt unification for IOEmbedCache?

packages/core-typings/src/federation/v1/FederationKey.ts (1)

4-8: Redundant _id re-declaration.

IRocketChatRecord already provides _id. Other interfaces in this PR (e.g., ISmarshHistory, IOAuthRefreshToken, IImportRecord) drop their explicit _id when switching to IRocketChatRecord inheritance. Keeping it here is harmless but inconsistent.

Suggested diff
 export interface FederationKey extends IRocketChatRecord {
-	_id: string;
 	type: 'private' | 'public';
 	key: string;
 }
apps/meteor/app/file-upload/ufs/GoogleStorage/server.ts (1)

80-83: Consider a shared type alias for Omit<IUpload, '_updatedAt'> across storage adapters.

The same Omit<IUpload, '_updatedAt'> type and as cast pattern is repeated in GoogleStorage, AmazonS3, and Webdav adapters. A shared type alias (e.g., type UploadFileInput = Omit<IUpload, '_updatedAt'>) would reduce repetition and make future changes easier.

apps/meteor/app/file-upload/server/lib/FileUpload.ts (1)

810-863: Consistent omission of _updatedAt from insert-path types.

The Omit<OptionalId<IUpload>, '_updatedAt'> pattern across _validateFile, _doInsert, and insert correctly reflects that _updatedAt is server-managed and shouldn't be part of the caller-supplied data.

Note that uploadImageThumbnail (Line 358) still includes _updatedAt: new Date() in the details object passed to store.insert. While TypeScript won't flag this (excess property checks don't apply to variables), it's semantically inconsistent with the new Omit contract. Consider removing it if the DB layer sets _updatedAt automatically.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 052278b and bde31e7.

📒 Files selected for processing (91)
  • apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts
  • apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts
  • apps/meteor/app/file-upload/server/lib/FileUpload.ts
  • apps/meteor/app/file-upload/ufs/AmazonS3/server.ts
  • apps/meteor/app/file-upload/ufs/GoogleStorage/server.ts
  • apps/meteor/app/file-upload/ufs/Webdav/server.ts
  • apps/meteor/app/importer/server/classes/converters/RecordConverter.ts
  • apps/meteor/app/livechat/imports/server/rest/sms.ts
  • apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts
  • apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts
  • apps/meteor/client/components/ImageGallery/ImageGallery.tsx
  • apps/meteor/client/hooks/useWorkspaceInfo.ts
  • apps/meteor/client/lib/userStatuses.ts
  • apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx
  • apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts
  • apps/meteor/client/startup/roles.ts
  • apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsx
  • apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.stories.tsx
  • apps/meteor/client/views/admin/users/AdminUserForm.tsx
  • apps/meteor/client/views/admin/users/AdminUserFormWithData.tsx
  • apps/meteor/client/views/admin/users/UsersTable/UsersTable.tsx
  • apps/meteor/client/views/admin/users/UsersTable/UsersTableFilters.tsx
  • apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.stories.tsx
  • apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.tsx
  • apps/meteor/client/views/omnichannel/tags/TagEdit.tsx
  • apps/meteor/client/views/omnichannel/tags/TagEditWithDepartmentData.tsx
  • apps/meteor/client/views/room/ImageGallery/hooks/useImagesList.ts
  • apps/meteor/client/views/room/contextualBar/RoomFiles/RoomFiles.stories.tsx
  • apps/meteor/client/views/room/contextualBar/RoomFiles/components/FileItem.stories.tsx
  • apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts
  • apps/meteor/ee/server/lib/roles/insertRole.ts
  • apps/meteor/ee/server/lib/roles/updateRole.ts
  • apps/meteor/ee/server/models/raw/LivechatTag.ts
  • apps/meteor/server/services/import/service.ts
  • apps/meteor/server/ufs/ufs-filter.ts
  • apps/meteor/server/ufs/ufs-store.ts
  • apps/meteor/tests/data/livechat/department.ts
  • apps/meteor/tests/mocks/data.ts
  • packages/core-services/src/events/Events.ts
  • packages/core-typings/src/IBanner.ts
  • packages/core-typings/src/ICredentialToken.ts
  • packages/core-typings/src/ICronHistoryItem.ts
  • packages/core-typings/src/ICustomSound.ts
  • packages/core-typings/src/ICustomUserStatus.ts
  • packages/core-typings/src/IEmailInbox.ts
  • packages/core-typings/src/IEmailMessageHistory.ts
  • packages/core-typings/src/IInquiry.ts
  • packages/core-typings/src/IInstanceStatus.ts
  • packages/core-typings/src/IIntegrationHistory.ts
  • packages/core-typings/src/ILivechatBusinessHour.ts
  • packages/core-typings/src/ILivechatDepartment.ts
  • packages/core-typings/src/ILivechatDepartmentRecord.ts
  • packages/core-typings/src/ILivechatTag.ts
  • packages/core-typings/src/ILivechatTagRecord.ts
  • packages/core-typings/src/INotification.ts
  • packages/core-typings/src/INps.ts
  • packages/core-typings/src/IOAuthAccessToken.ts
  • packages/core-typings/src/IOAuthApps.ts
  • packages/core-typings/src/IOAuthAuthCode.ts
  • packages/core-typings/src/IOAuthRefreshToken.ts
  • packages/core-typings/src/IOEmbedCache.ts
  • packages/core-typings/src/IOmnichannelBusinessUnit.ts
  • packages/core-typings/src/IPermission.ts
  • packages/core-typings/src/IReadReceipt.ts
  • packages/core-typings/src/IRocketChatRecord.ts
  • packages/core-typings/src/IRole.ts
  • packages/core-typings/src/IServerEvent.ts
  • packages/core-typings/src/ISession.ts
  • packages/core-typings/src/ISmarshHistory.ts
  • packages/core-typings/src/IStats.ts
  • packages/core-typings/src/IUpload.ts
  • packages/core-typings/src/IUser.ts
  • packages/core-typings/src/MessageReads.ts
  • packages/core-typings/src/ee/IWorkspaceCredentials.ts
  • packages/core-typings/src/federation/v1/FederationKey.ts
  • packages/core-typings/src/import/IImportRecord.ts
  • packages/core-typings/src/migrations/IControl.ts
  • packages/model-typings/src/models/ICredentialTokensModel.ts
  • packages/model-typings/src/models/ICustomSoundsModel.ts
  • packages/model-typings/src/models/IEmailMessageHistoryModel.ts
  • packages/model-typings/src/models/ILivechatBusinessHoursModel.ts
  • packages/model-typings/src/models/ILivechatTagModel.ts
  • packages/models/src/models/CredentialTokens.ts
  • packages/models/src/models/CustomSounds.ts
  • packages/models/src/models/EmailMessageHistory.ts
  • packages/models/src/models/LivechatBusinessHours.ts
  • packages/models/src/models/LivechatRooms.ts
  • packages/models/src/models/OEmbedCache.ts
  • packages/models/src/models/Roles.ts
  • packages/rest-typings/src/v1/omnichannel.ts
  • packages/ui-contexts/src/CustomSoundContext.ts
💤 Files with no reviewable changes (11)
  • packages/core-typings/src/IUser.ts
  • packages/core-typings/src/IInquiry.ts
  • packages/core-typings/src/IOmnichannelBusinessUnit.ts
  • packages/core-typings/src/ILivechatTagRecord.ts
  • packages/models/src/models/LivechatRooms.ts
  • packages/core-typings/src/ILivechatDepartmentRecord.ts
  • apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.tsx
  • packages/core-typings/src/ee/IWorkspaceCredentials.ts
  • packages/core-typings/src/IIntegrationHistory.ts
  • packages/core-typings/src/INps.ts
  • apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.stories.tsx
🚧 Files skipped from review as they are similar to previous changes (13)
  • packages/core-services/src/events/Events.ts
  • apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts
  • packages/model-typings/src/models/ICustomSoundsModel.ts
  • apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts
  • apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts
  • packages/core-typings/src/IInstanceStatus.ts
  • packages/models/src/models/LivechatBusinessHours.ts
  • packages/models/src/models/CustomSounds.ts
  • packages/core-typings/src/ICustomSound.ts
  • packages/core-typings/src/ICredentialToken.ts
  • packages/model-typings/src/models/ICredentialTokensModel.ts
  • apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts
  • packages/models/src/models/CredentialTokens.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/client/views/omnichannel/tags/TagEdit.tsx
  • apps/meteor/ee/server/lib/roles/insertRole.ts
  • apps/meteor/tests/mocks/data.ts
  • apps/meteor/client/views/omnichannel/tags/TagEditWithDepartmentData.tsx
  • packages/ui-contexts/src/CustomSoundContext.ts
  • apps/meteor/server/services/import/service.ts
  • packages/core-typings/src/IRole.ts
  • apps/meteor/ee/server/models/raw/LivechatTag.ts
  • apps/meteor/client/views/admin/users/AdminUserFormWithData.tsx
  • apps/meteor/client/views/room/contextualBar/RoomFiles/components/FileItem.stories.tsx
  • apps/meteor/client/views/admin/users/UsersTable/UsersTable.tsx
  • packages/core-typings/src/ILivechatTag.ts
  • apps/meteor/client/lib/userStatuses.ts
  • apps/meteor/server/ufs/ufs-store.ts
  • apps/meteor/client/views/room/ImageGallery/hooks/useImagesList.ts
  • packages/core-typings/src/ISmarshHistory.ts
  • packages/models/src/models/EmailMessageHistory.ts
  • packages/models/src/models/OEmbedCache.ts
  • apps/meteor/app/file-upload/ufs/GoogleStorage/server.ts
  • apps/meteor/client/views/admin/users/AdminUserForm.tsx
  • apps/meteor/app/file-upload/ufs/Webdav/server.ts
  • apps/meteor/app/file-upload/ufs/AmazonS3/server.ts
  • packages/core-typings/src/ISession.ts
  • packages/core-typings/src/MessageReads.ts
  • packages/core-typings/src/IOAuthAuthCode.ts
  • apps/meteor/client/startup/roles.ts
  • apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx
  • packages/core-typings/src/ICronHistoryItem.ts
  • packages/models/src/models/Roles.ts
  • apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts
  • apps/meteor/tests/data/livechat/department.ts
  • packages/rest-typings/src/v1/omnichannel.ts
  • packages/core-typings/src/IOAuthAccessToken.ts
  • packages/core-typings/src/INotification.ts
  • packages/core-typings/src/federation/v1/FederationKey.ts
  • apps/meteor/client/views/admin/users/UsersTable/UsersTableFilters.tsx
  • packages/core-typings/src/import/IImportRecord.ts
  • packages/model-typings/src/models/IEmailMessageHistoryModel.ts
  • apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts
  • packages/model-typings/src/models/ILivechatTagModel.ts
  • apps/meteor/app/importer/server/classes/converters/RecordConverter.ts
  • packages/core-typings/src/migrations/IControl.ts
  • apps/meteor/app/livechat/imports/server/rest/sms.ts
  • packages/core-typings/src/ILivechatDepartment.ts
  • apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsx
  • packages/core-typings/src/IRocketChatRecord.ts
  • packages/core-typings/src/IOAuthRefreshToken.ts
  • packages/core-typings/src/IUpload.ts
  • apps/meteor/client/components/ImageGallery/ImageGallery.tsx
  • apps/meteor/client/views/room/contextualBar/RoomFiles/RoomFiles.stories.tsx
  • packages/core-typings/src/IOEmbedCache.ts
  • packages/core-typings/src/ILivechatBusinessHour.ts
  • packages/core-typings/src/IEmailMessageHistory.ts
  • apps/meteor/client/hooks/useWorkspaceInfo.ts
  • apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.stories.tsx
  • packages/core-typings/src/IReadReceipt.ts
  • packages/core-typings/src/IPermission.ts
  • packages/model-typings/src/models/ILivechatBusinessHoursModel.ts
  • packages/core-typings/src/ICustomUserStatus.ts
  • packages/core-typings/src/IBanner.ts
  • packages/core-typings/src/IServerEvent.ts
  • apps/meteor/app/file-upload/server/lib/FileUpload.ts
  • packages/core-typings/src/IOAuthApps.ts
  • packages/core-typings/src/IStats.ts
  • apps/meteor/server/ufs/ufs-filter.ts
  • packages/core-typings/src/IEmailInbox.ts
  • apps/meteor/ee/server/lib/roles/updateRole.ts
🧠 Learnings (11)
📓 Common learnings
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/ee/server/lib/roles/insertRole.ts
  • apps/meteor/tests/mocks/data.ts
  • apps/meteor/client/views/omnichannel/tags/TagEditWithDepartmentData.tsx
  • apps/meteor/server/services/import/service.ts
  • apps/meteor/ee/server/models/raw/LivechatTag.ts
  • apps/meteor/client/views/admin/users/AdminUserFormWithData.tsx
  • apps/meteor/client/views/room/contextualBar/RoomFiles/components/FileItem.stories.tsx
  • apps/meteor/client/lib/userStatuses.ts
  • apps/meteor/server/ufs/ufs-store.ts
  • packages/core-typings/src/ISmarshHistory.ts
  • apps/meteor/client/views/admin/users/AdminUserForm.tsx
  • apps/meteor/client/startup/roles.ts
  • packages/core-typings/src/ICronHistoryItem.ts
  • apps/meteor/tests/data/livechat/department.ts
  • packages/core-typings/src/migrations/IControl.ts
  • apps/meteor/app/livechat/imports/server/rest/sms.ts
  • apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsx
  • packages/core-typings/src/IRocketChatRecord.ts
  • packages/core-typings/src/IOAuthRefreshToken.ts
  • apps/meteor/client/views/room/contextualBar/RoomFiles/RoomFiles.stories.tsx
  • packages/core-typings/src/IOEmbedCache.ts
  • packages/core-typings/src/IEmailMessageHistory.ts
  • apps/meteor/client/hooks/useWorkspaceInfo.ts
  • packages/core-typings/src/IBanner.ts
  • packages/core-typings/src/IOAuthApps.ts
  • packages/core-typings/src/IEmailInbox.ts
  • apps/meteor/ee/server/lib/roles/updateRole.ts
📚 Learning: 2025-10-06T20:30:45.540Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37152
File: packages/apps-engine/tests/test-data/storage/storage.ts:101-122
Timestamp: 2025-10-06T20:30:45.540Z
Learning: In `packages/apps-engine/tests/test-data/storage/storage.ts`, the stub methods (updatePartialAndReturnDocument, updateStatus, updateSetting, updateAppInfo, updateMarketplaceInfo) intentionally throw "Method not implemented." Tests using these methods must stub them using `SpyOn` from the test library rather than relying on actual implementations.

Applied to files:

  • apps/meteor/tests/mocks/data.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • apps/meteor/tests/mocks/data.ts
  • apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (`test`, `page`, `expect`) for consistency in test files

Applied to files:

  • apps/meteor/tests/mocks/data.ts
  • apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsx
📚 Learning: 2026-01-15T22:03:35.587Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 38071
File: apps/meteor/app/apps/server/bridges/listeners.ts:257-271
Timestamp: 2026-01-15T22:03:35.587Z
Learning: In the file upload pipeline (apps/meteor/app/apps/server/bridges/listeners.ts), temporary files are created by the server in the same filesystem, so symlinks between temp files are safe and don't require cross-filesystem fallbacks.

Applied to files:

  • apps/meteor/app/file-upload/ufs/GoogleStorage/server.ts
  • apps/meteor/app/file-upload/ufs/Webdav/server.ts
  • apps/meteor/app/file-upload/ufs/AmazonS3/server.ts
  • apps/meteor/app/file-upload/server/lib/FileUpload.ts
  • apps/meteor/server/ufs/ufs-filter.ts
📚 Learning: 2025-10-16T21:09:51.816Z
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36942
File: apps/meteor/client/lib/e2ee/keychain.ts:148-156
Timestamp: 2025-10-16T21:09:51.816Z
Learning: In the RocketChat/Rocket.Chat repository, only platforms with native crypto.randomUUID() support are targeted, so fallback implementations for crypto.randomUUID() are not required in E2EE or cryptographic code.

Applied to files:

  • apps/meteor/app/file-upload/ufs/AmazonS3/server.ts
📚 Learning: 2025-09-15T21:34:39.812Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 36717
File: packages/ui-voip/src/providers/useCallSounds.ts:6-21
Timestamp: 2025-09-15T21:34:39.812Z
Learning: The voipSounds methods (playDialer, playRinger, playCallEnded) from useCustomSound return proper offCallbackHandler cleanup functions, not void as some type definitions might suggest.

Applied to files:

  • apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx
📚 Learning: 2025-11-17T14:30:36.271Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 37491
File: packages/desktop-api/src/index.ts:17-27
Timestamp: 2025-11-17T14:30:36.271Z
Learning: In the Rocket.Chat desktop API (`packages/desktop-api/src/index.ts`), the `CustomNotificationOptions` type has an optional `id` field by design. Custom notifications dispatched without an ID cannot be closed programmatically using `closeCustomNotification`, and this is intentional.

Applied to files:

  • packages/core-typings/src/INotification.ts
📚 Learning: 2025-09-19T15:15:04.642Z
Learnt from: rodrigok
Repo: RocketChat/Rocket.Chat PR: 36991
File: apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts:219-221
Timestamp: 2025-09-19T15:15:04.642Z
Learning: The Federation_Matrix_homeserver_domain setting in apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts is part of the old federation system and is being deprecated/removed, so configuration issues with this setting should not be flagged for improvement.

Applied to files:

  • packages/core-typings/src/federation/v1/FederationKey.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `expect` matchers for assertions (`toEqual`, `toContain`, `toBeTruthy`, `toHaveLength`, etc.) instead of `assert` statements in Playwright tests

Applied to files:

  • apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsx
🧬 Code graph analysis (46)
apps/meteor/client/views/omnichannel/tags/TagEdit.tsx (2)
packages/core-typings/src/utils.ts (1)
  • Serialized (61-74)
packages/core-typings/src/ILivechatTag.ts (1)
  • ILivechatTag (3-8)
apps/meteor/ee/server/lib/roles/insertRole.ts (1)
packages/core-typings/src/IRole.ts (1)
  • IRole (3-9)
packages/ui-contexts/src/CustomSoundContext.ts (1)
packages/core-typings/src/ICustomSound.ts (1)
  • ICustomSound (3-8)
packages/core-typings/src/IRole.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
apps/meteor/ee/server/models/raw/LivechatTag.ts (1)
packages/core-typings/src/ILivechatTag.ts (1)
  • ILivechatTag (3-8)
apps/meteor/client/views/admin/users/AdminUserFormWithData.tsx (2)
packages/core-typings/src/utils.ts (1)
  • Serialized (61-74)
packages/core-typings/src/IRole.ts (1)
  • IRole (3-9)
packages/core-typings/src/ILivechatTag.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
apps/meteor/client/lib/userStatuses.ts (1)
packages/core-typings/src/ICustomUserStatus.ts (1)
  • ICustomUserStatus (4-4)
apps/meteor/server/ufs/ufs-store.ts (1)
packages/core-typings/src/IUpload.ts (1)
  • IUpload (5-67)
apps/meteor/app/file-upload/ufs/Webdav/server.ts (1)
packages/core-typings/src/IUpload.ts (1)
  • IUpload (5-67)
apps/meteor/app/file-upload/ufs/AmazonS3/server.ts (1)
packages/core-typings/src/IUpload.ts (1)
  • IUpload (5-67)
packages/core-typings/src/ISession.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
packages/core-typings/src/MessageReads.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
packages/core-typings/src/IOAuthAuthCode.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
apps/meteor/client/startup/roles.ts (1)
packages/models/src/index.ts (1)
  • Roles (191-191)
apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx (1)
packages/core-typings/src/ICustomSound.ts (1)
  • ICustomSound (3-8)
packages/core-typings/src/ICronHistoryItem.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts (1)
packages/core-typings/src/ILivechatBusinessHour.ts (1)
  • ILivechatBusinessHour (33-41)
apps/meteor/tests/data/livechat/department.ts (1)
packages/core-typings/src/ILivechatDepartment.ts (1)
  • ILivechatDepartment (3-24)
packages/rest-typings/src/v1/omnichannel.ts (1)
packages/core-typings/src/ILivechatTag.ts (1)
  • ILivechatTag (3-8)
packages/core-typings/src/IOAuthAccessToken.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
packages/core-typings/src/INotification.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
packages/core-typings/src/federation/v1/FederationKey.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
packages/core-typings/src/import/IImportRecord.ts (2)
packages/core-typings/src/import/IImportMessage.ts (1)
  • IImportMessage (22-51)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
packages/model-typings/src/models/IEmailMessageHistoryModel.ts (1)
packages/core-typings/src/IEmailMessageHistory.ts (1)
  • IEmailMessageHistory (3-6)
packages/model-typings/src/models/ILivechatTagModel.ts (1)
packages/core-typings/src/ILivechatTag.ts (1)
  • ILivechatTag (3-8)
packages/core-typings/src/migrations/IControl.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
apps/meteor/app/livechat/imports/server/rest/sms.ts (1)
packages/core-typings/src/IUpload.ts (1)
  • IUpload (5-67)
packages/core-typings/src/IRocketChatRecord.ts (1)
packages/core-typings/src/utils.ts (1)
  • TimestampSchema (76-79)
packages/core-typings/src/IOAuthRefreshToken.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
apps/meteor/client/components/ImageGallery/ImageGallery.tsx (1)
packages/core-typings/src/IUpload.ts (1)
  • IUpload (5-67)
packages/core-typings/src/IOEmbedCache.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
packages/core-typings/src/ILivechatBusinessHour.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
packages/core-typings/src/IEmailMessageHistory.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
apps/meteor/client/hooks/useWorkspaceInfo.ts (2)
packages/core-typings/src/utils.ts (1)
  • Serialized (61-74)
packages/core-typings/src/IStats.ts (1)
  • IStats (21-276)
packages/core-typings/src/IReadReceipt.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
packages/core-typings/src/IPermission.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
packages/model-typings/src/models/ILivechatBusinessHoursModel.ts (1)
packages/core-typings/src/ILivechatBusinessHour.ts (1)
  • ILivechatBusinessHour (33-41)
packages/core-typings/src/ICustomUserStatus.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
packages/core-typings/src/IBanner.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (2)
  • IRocketChatRecordSchema (6-9)
  • IRocketChatRecord (11-11)
apps/meteor/app/file-upload/server/lib/FileUpload.ts (1)
packages/core-typings/src/IUpload.ts (1)
  • IUpload (5-67)
packages/core-typings/src/IOAuthApps.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
packages/core-typings/src/IStats.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
apps/meteor/server/ufs/ufs-filter.ts (1)
packages/core-typings/src/IUpload.ts (1)
  • IUpload (5-67)
packages/core-typings/src/IEmailInbox.ts (1)
packages/core-typings/src/IRocketChatRecord.ts (1)
  • IRocketChatRecord (11-11)
apps/meteor/ee/server/lib/roles/updateRole.ts (1)
packages/core-typings/src/IRole.ts (1)
  • IRole (3-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🔇 Additional comments (60)
apps/meteor/client/views/room/contextualBar/RoomFiles/components/FileItem.stories.tsx (1)

26-26: LGTM!

Adding _updatedAt to the mock data correctly aligns with the updated record type that now inherits _updatedAt from IRocketChatRecord.

apps/meteor/client/views/room/contextualBar/RoomFiles/RoomFiles.stories.tsx (1)

30-31: LGTM!

Story mock data correctly updated to include the now-required _updatedAt field, keeping it consistent with the updated record typings.

Also applies to: 41-42

apps/meteor/client/views/room/ImageGallery/hooks/useImagesList.ts (1)

24-30: LGTM — unconditional new Date(file._updatedAt) is consistent with _updatedAt now being required.

The other date fields (uploadedAt, modifiedAt, expiresAt) remain optional and are conditionally constructed, while _updatedAt is correctly treated as always-present per the updated core typings.

apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts (1)

40-46: LGTM — unconditional new Date is consistent with _updatedAt now being required.

The other timestamp fields (uploadedAt, modifiedAt, expiresAt) remain conditionally converted because they're optional on IUpload, while _updatedAt is now guaranteed via IRocketChatRecord. The change aligns with the PR objective.

apps/meteor/tests/mocks/data.ts (1)

436-446: LGTM!

The addition of _updatedAt to createFakeTag is consistent with how other Serialized<…> fake creators in this file handle the field (e.g., createFakeAgent, createFakeBusinessUnit, createFakeDepartment), and it's correctly placed before the ...overrides spread.

packages/core-typings/src/ILivechatDepartment.ts (1)

1-3: LGTM — clean adoption of IRocketChatRecord.

Extending IRocketChatRecord centralizes _id and _updatedAt consistently, which aligns with the PR objective. The rest of the interface is unchanged.

apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx (1)

26-26: LGTM — explicit return type aligns with the context contract.

The Omit<ICustomSound, '_updatedAt'> annotation is consistent with the updated CustomSoundContext type and the defaultSounds array type, correctly narrowing the public surface to exclude the DB-level timestamp.

packages/ui-contexts/src/CustomSoundContext.ts (1)

39-39: LGTM — context type correctly reflects the provider's data shape.

The list type now matches the provider's queryFn return type and the updated defaultSounds type, keeping the public contract consistent across the custom sound system.

apps/meteor/server/services/import/service.ts (1)

147-147: LGTM — _updatedAt field aligns with the PR objective.

Adding _updatedAt: new Date() to the inserted import data documents ensures they conform to the updated record type requirements.

packages/core-typings/src/IStats.ts (1)

4-4: Clean alignment with the IRocketChatRecord base type pattern.

Extending IRocketChatRecord provides both _id and _updatedAt consistently, removing the need for a local _id declaration. This matches the broader PR refactor well.

Also applies to: 21-21

apps/meteor/client/hooks/useWorkspaceInfo.ts (1)

56-61: Correct deserialization of Date fields from the serialized response.

The select properly converts _updatedAt and lastMessageSentAt from their serialized string forms back to Date objects. The remaining createdAt field in IStats already accepts string, so the spread is type-safe without explicit conversion.

packages/model-typings/src/models/ILivechatTagModel.ts (1)

8-12: Return type accurately reflects the implementation.

createOrUpdateTag constructs a record manually and doesn't include _updatedAt, so Omit<ILivechatTag, '_updatedAt'> is the correct return type.

packages/core-typings/src/IEmailInbox.ts (1)

1-3: Consistent migration to IRocketChatRecord.

IEmailInbox correctly inherits _id and _updatedAt from IRocketChatRecord. The existing IEmailInboxPayload type on line 32 properly omits _updatedAt which now comes via inheritance.

packages/core-typings/src/IReadReceipt.ts (1)

2-2: Consistent migration to IRocketChatRecord.

IReadReceipt now inherits both _id and _updatedAt from IRocketChatRecord. Note that this adds a new required _updatedAt field to the type surface, which is the intended outcome of this PR.

Also applies to: 6-6

apps/meteor/ee/server/models/raw/LivechatTag.ts (1)

28-46: Return type correctly reflects the constructed object.

The method builds a plain record and appends _id, never including _updatedAt. The Omit<ILivechatTag, '_updatedAt'> return type accurately describes this. The type aligns with the model interface definition in ILivechatTagModel.ts.

packages/core-typings/src/IOAuthApps.ts (1)

1-3: Consistent migration to IRocketChatRecord.

IOAuthApps correctly inherits _id and _updatedAt from IRocketChatRecord, replacing the previously local declarations. Domain-specific fields like _createdAt and _createdBy remain appropriately in the interface.

packages/core-typings/src/IRocketChatRecord.ts (2)

6-11: Clean foundation for the record type normalization.

The zod schema approach with TimestampSchema is a good pattern for ensuring _updatedAt is consistently typed across all record types. The empty interface extending z.infer<> preserves a named type for consumers.


2-2: : The import import * as z from 'zod' is consistent with the project convention. All zod imports across the codebase use the namespace import style import * as z from 'zod', not alternative patterns like import { z } from 'zod/v4'.

Likely an incorrect or invalid review comment.

packages/core-typings/src/IOAuthAuthCode.ts (1)

1-9: LGTM — consistent migration to IRocketChatRecord.

Extending IRocketChatRecord correctly replaces the local _id declaration and adds the required _updatedAt field, aligning with the PR's normalization goal.

packages/core-typings/src/MessageReads.ts (1)

5-10: LGTM — type alias correctly migrated to interface.

The eslint-disable for naming convention is reasonable to preserve backward compatibility with the existing MessageReads name.

packages/model-typings/src/models/ILivechatBusinessHoursModel.ts (1)

26-26: LGTM — correctly excludes _updatedAt from insertion input.

Since _updatedAt is now part of ILivechatBusinessHour via IRocketChatRecord, omitting it from the insertOne parameter is correct — the database layer should set this field automatically.

packages/core-typings/src/IServerEvent.ts (1)

1-1: LGTM — consistent migration to IRocketChatRecord.

IServerEvent correctly inherits _id and _updatedAt from the base record type.

Also applies to: 18-18

packages/core-typings/src/migrations/IControl.ts (1)

1-9: Remove the concern about _updatedAt not being set in migration control documents. The BaseRaw.updateMany() method automatically adds _updatedAt via the setUpdatedAt() function, which detects MongoDB operators and injects the timestamp into the $set clause. Migration control documents are guaranteed to have this field, making the type cast in getControl() safe.

packages/core-typings/src/ILivechatBusinessHour.ts (1)

33-41: LGTM — consistent adoption of IRocketChatRecord.

The migration from locally declared _id/_updatedAt to extending IRocketChatRecord is clean and aligns with the PR objective. Downstream consumers already use Omit<ILivechatBusinessHour, '_updatedAt'> where the field isn't yet available.

packages/core-typings/src/IUpload.ts (1)

5-67: LGTM — IUpload now inherits identity fields from IRocketChatRecord.

apps/meteor/app/livechat/imports/server/rest/sms.ts (1)

30-30: LGTM — correctly excludes _updatedAt from the input shape.

Since IUpload now inherits a required _updatedAt from IRocketChatRecord, omitting it in the parameter type is the right call for a caller that constructs a plain details object before insertion.

packages/core-typings/src/ILivechatTag.ts (1)

1-8: LGTM — ILivechatTag properly migrated to IRocketChatRecord.

apps/meteor/client/views/omnichannel/tags/TagEditWithDepartmentData.tsx (1)

1-9: LGTM — correct use of Serialized<ILivechatTag> for API-sourced data.

Since ILivechatTag now includes _updatedAt: Date via IRocketChatRecord, wrapping in Serialized properly reflects the wire format where Date fields become strings.

apps/meteor/client/views/omnichannel/tags/TagEdit.tsx (1)

27-27: LGTM — prop type aligns with the parent component's Serialized<ILivechatTag>.

packages/core-typings/src/ICustomUserStatus.ts (1)

4-4: No issues found. The dual extension is valid: both IUserStatus and IRocketChatRecord declare _id: string (compatible), and _updatedAt is only in IRocketChatRecord. The change works cleanly with no type-level conflicts.

packages/rest-typings/src/v1/omnichannel.ts (1)

620-620: LGTM — type now matches the AJV schema shape.

The response schema doesn't include _updatedAt, so Omit<ILivechatTag, '_updatedAt'> correctly reflects what the validator actually accepts.

packages/core-typings/src/ISession.ts (1)

1-16: LGTM — ISession correctly extends IRocketChatRecord.

Centralizing _id and _updatedAt under IRocketChatRecord is consistent with the PR objective. Note that _updatedAt goes from optional to required here, which is the intended normalization.

apps/meteor/client/lib/userStatuses.ts (1)

36-47: LGTM — parameter type correctly narrowed.

The method body only accesses name, _id, and statusType, so omitting _updatedAt from the parameter type accurately reflects the actual data contract.

packages/core-typings/src/IOAuthAccessToken.ts (1)

1-10: LGTM — clean migration to IRocketChatRecord.

_id and _updatedAt are now inherited from the base type, consistent with the other record types in this PR.

packages/core-typings/src/IRole.ts (1)

1-9: LGTM — IRole now extends IRocketChatRecord.

This adds the previously missing _updatedAt field and centralizes _id under the shared base type, consistent with the PR's normalization goal.

apps/meteor/server/ufs/ufs-store.ts (1)

45-45: LGTM — input type correctly narrowed to exclude _updatedAt.

The Omit<OptionalId<IUpload>, '_updatedAt'> change aligns with the PR objective: callers constructing new upload records should not provide _updatedAt (it's a server-managed field). Existing usages like the copy path (Line 129) remain structurally compatible since TypeScript's structural subtyping permits extra properties on non-literal objects.

packages/core-typings/src/import/IImportRecord.ts (1)

5-10: LGTM — consistent adoption of IRocketChatRecord base.

Replacing the standalone _id declaration with IRocketChatRecord inheritance gives IImportRecord (and all its sub-interfaces) a properly typed _id and _updatedAt. Clean and consistent with the rest of the PR.

packages/core-typings/src/IOAuthRefreshToken.ts (1)

1-3: LGTM — IOAuthRefreshToken now correctly inherits from IRocketChatRecord.

Consistent with the PR-wide pattern. The interface gains _id and _updatedAt from the base type, matching the expected database document shape.

apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts (1)

4-6: LGTM — parameter type correctly narrowed.

The function only accesses active, workHours, _id, and type — none affected by omitting _updatedAt. The type change aligns with upstream callers that produce business hour objects without _updatedAt.

packages/core-typings/src/ISmarshHistory.ts (1)

1-3: LGTM — standard IRocketChatRecord adoption.

packages/core-typings/src/IEmailMessageHistory.ts (1)

1-3: LGTM — standard IRocketChatRecord adoption.

packages/model-typings/src/models/IEmailMessageHistoryModel.ts (1)

4-7: LGTM — correct use of InsertionModel for the create signature.

Using InsertionModel<IEmailMessageHistory> properly reflects that _updatedAt is managed by the persistence layer and _id is optional at insertion time.

packages/models/src/models/EmailMessageHistory.ts (1)

16-22: LGTM — implementation aligns with the updated model typing.

The createdAt is correctly set at insertion time, and _updatedAt is presumably managed by BaseRaw.insertOne.

packages/core-typings/src/ICronHistoryItem.ts (1)

1-10: LGTM — properly extends IRocketChatRecord for consistent identity fields.

apps/meteor/app/file-upload/ufs/GoogleStorage/server.ts (1)

21-25: LGTM — Omit<IUpload, '_updatedAt'> correctly narrows the type for path resolution.

Since _updatedAt isn't available at file creation time, this accurately models the data flow through the storage adapter.

packages/core-typings/src/INotification.ts (1)

41-50: LGTM — INotification correctly extends IRocketChatRecord.

packages/core-typings/src/IBanner.ts (1)

13-35: LGTM — schema and interface properly unified under IRocketChatRecordSchema/IRocketChatRecord.

The dual extension on IBanner (line 35) is slightly redundant since IBannerSchema already extends IRocketChatRecordSchema, but it makes the relationship explicit and ensures structural compatibility. Fine as-is.

apps/meteor/app/file-upload/ufs/Webdav/server.ts (1)

21-25: LGTM — consistent with the same type narrowing applied across all storage adapters.

packages/core-typings/src/IPermission.ts (1)

1-3: Clean consolidation onto IRocketChatRecord.

Extending IRocketChatRecord properly inherits _id and _updatedAt, removing duplication. Consistent with the PR-wide pattern.

apps/meteor/app/file-upload/server/lib/FileUpload.ts (1)

287-287: Good narrowing of parameter types to minimal required fields.

Using Pick<IUpload, '_id'> and Pick<IUpload, '_id' | 'identify'> properly limits these methods to only the fields they actually use, which is a clean approach.

Also applies to: 305-305

apps/meteor/app/file-upload/ufs/AmazonS3/server.ts (1)

27-31: Type narrowing for getPath is consistent across storage backends.

The Omit<IUpload, '_updatedAt'> parameter type correctly reflects that path resolution never depends on _updatedAt. The cast on Line 104 is necessary since the file parameter in create has a broader type from the store base class.

Also applies to: 104-104

apps/meteor/client/components/ImageGallery/ImageGallery.tsx (1)

101-109: Props correctly narrowed to only the fields consumed by the component.

The Pick<IUpload, '_id' | 'path' | 'url'> matches the destructured fields on Line 203 (_id, path, url). This reduces coupling to the full IUpload shape.

apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.stories.tsx (1)

20-84: Mock data correctly updated to include required _updatedAt field.

The IRole objects now satisfy the IRocketChatRecord contract. Consistent with the parallel update in the spec file.

apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsx (1)

38-54: Test data aligned with updated IRole type.

Both role entries now include _updatedAt, matching the story data and satisfying the IRocketChatRecord requirement.

apps/meteor/ee/server/lib/roles/insertRole.ts (1)

12-12: Input type correctly excludes _updatedAt.

Since _updatedAt is server-managed (set by Roles.createWithRandomId), excluding it from the input prevents callers from providing a potentially stale timestamp. The return type Promise<IRole> still includes _updatedAt from the DB response, which is correct.

apps/meteor/client/views/admin/users/AdminUserForm.tsx (1)

53-53: LGTM — type change to Serialized<IRole>[] is consistent and correct.

The component only destructures _id, name, and description from role objects (line 135), all of which are strings unaffected by serialization. This aligns with the same change applied across AdminUserFormWithData, UsersTable, and UsersTableFilters.

apps/meteor/client/views/admin/users/UsersTable/UsersTable.tsx (1)

27-27: LGTM — consistent type update.

The roleData prop type aligns with both upstream (AdminUsersPage) and downstream (UsersTableFilters) components.

apps/meteor/client/views/admin/users/UsersTable/UsersTableFilters.tsx (1)

1-1: LGTM — import and type update are consistent with the rest of the chain.

Also applies to: 14-14

apps/meteor/ee/server/lib/roles/updateRole.ts (1)

12-16: LGTM — correctly excludes _updatedAt from the input parameter.

The _updatedAt field is managed by the database layer, so excluding it from roleData prevents callers from accidentally supplying a stale or incorrect timestamp. The re-fetch at lines 56–61 ensures the returned IRole has the correct server-set _updatedAt.

apps/meteor/client/views/admin/users/AdminUserFormWithData.tsx (1)

1-1: LGTM — consistent type propagation to AdminUserForm.

Also applies to: 15-15

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@@ -144,6 +144,7 @@ export class ImportService extends ServiceClassInternal implements IImportServic
roles: data.roles ? [...new Set(...data.roles, ...defaultRoles)] : defaultRoles,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, locate and examine the file
file_path="apps/meteor/server/services/import/service.ts"
if [ -f "$file_path" ]; then
  echo "=== File content around line 144 ==="
  sed -n '140,150p' "$file_path"
else
  echo "File not found, searching for it..."
  find . -name "service.ts" -path "*/import/*" 2>/dev/null
fi

Repository: RocketChat/Rocket.Chat

Length of output: 350


🏁 Script executed:

# Verify Set constructor behavior with JavaScript
node <<'EOF'
console.log("=== Testing Set constructor behavior ===\n");

// Test 1: Set with multiple arguments
console.log("Test 1: new Set('admin', 'user')");
const set1 = new Set('admin', 'user');
console.log("Result:", set1);
console.log("Array:", [...set1]);

// Test 2: Set with array of strings
console.log("\nTest 2: new Set(['admin', 'user'])");
const set2 = new Set(['admin', 'user']);
console.log("Result:", set2);
console.log("Array:", [...set2]);

// Test 3: Spreading arrays as separate arguments
console.log("\nTest 3: new Set(...['admin'], ...['user'])");
const data = { roles: ['admin'] };
const defaultRoles = ['user'];
try {
  const set3 = new Set(...data.roles, ...defaultRoles);
  console.log("Result:", set3);
} catch(e) {
  console.log("Error:", e.message);
}

// Test 4: Correct approach with merged array
console.log("\nTest 4: new Set([...['admin'], ...['user']])");
const set4 = new Set([...data.roles, ...defaultRoles]);
console.log("Result:", set4);
console.log("Array:", [...set4]);

// Test 5: The actual pattern from the code
console.log("\nTest 5: Actual pattern simulation");
const testData = { roles: ['admin'] };
const testDefaultRoles = ['user'];
const buggyResult = [...new Set(...testData.roles, ...testDefaultRoles)];
console.log("Buggy pattern result:", buggyResult);
const fixedResult = [...new Set([...testData.roles, ...testDefaultRoles])];
console.log("Fixed pattern result:", fixedResult);
EOF

Repository: RocketChat/Rocket.Chat

Length of output: 638


🏁 Script executed:

# Search for similar patterns in the codebase
echo "=== Searching for similar Set patterns ==="
rg -nP 'new Set\(\.\.\.' --type=ts --type=js -C 2

Repository: RocketChat/Rocket.Chat

Length of output: 499


Fix bug in Set constructor usage: spreading multiple arrays as separate arguments only uses the first element

The Set constructor accepts a single iterable. new Set(...data.roles, ...defaultRoles) passes only the first spread expression as an argument; if it's a string (e.g., 'admin'), Set iterates its characters, yielding Set {'a', 'd', 'm', 'i', 'n'} instead of merging role arrays.

Replace with new Set([...data.roles, ...defaultRoles]) to merge both arrays before passing to Set.

🐛 Proposed fix
-				roles: data.roles ? [...new Set(...data.roles, ...defaultRoles)] : defaultRoles,
+				roles: data.roles ? [...new Set([...data.roles, ...defaultRoles])] : defaultRoles,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
roles: data.roles ? [...new Set(...data.roles, ...defaultRoles)] : defaultRoles,
roles: data.roles ? [...new Set([...data.roles, ...defaultRoles])] : defaultRoles,
🤖 Prompt for AI Agents
In `@apps/meteor/server/services/import/service.ts` at line 144, The roles merge
uses the Set constructor incorrectly by spreading two iterables as separate
arguments; update the roles assignment where data.roles and defaultRoles are
combined (the expression referencing data.roles, defaultRoles and Set) to pass a
single iterable that concatenates data.roles and defaultRoles into new Set and
then spread that Set into an array so duplicates are removed (i.e., combine
data.roles and defaultRoles into one array, build a Set from that array, and
spread the Set back into the roles array).

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