-
Notifications
You must be signed in to change notification settings - Fork 13.1k
refactor(core-typings): Record types missing a required _updatedAt field
#38528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
|
Looks like this PR is not ready to merge, because of the following issues:
Please fix the issues and try again If you have any trouble, please check the PR guidelines |
|
WalkthroughCentralizes record identity/timestamps under IRocketChatRecord, removes Changes
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ 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. Comment |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ 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
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
There was a problem hiding this 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._updatedAtis now contradictory with the parameter type.The parameter is typed as
Omit<ILivechatDepartment, '_updatedAt'>, signaling_updatedAtshouldn't be present, yet line 202 still deletes it. This only compiles becauseILivechatDepartmenthas an index signature ([k: string]: any). Consider removing thedeletestatement since the type contract already guarantees the field isn't there, or keep the originalILivechatDepartmenttype 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
📒 Files selected for processing (22)
apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.tsapps/meteor/app/custom-sounds/server/methods/uploadCustomSound.tsapps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.tsapps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.tsapps/meteor/client/lib/userStatuses.tsapps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsxapps/meteor/client/providers/CustomSoundProvider/lib/helpers.tsapps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.stories.tsxapps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.tsxapps/meteor/tests/data/livechat/department.tspackages/core-services/src/events/Events.tspackages/core-typings/src/ICustomSound.tspackages/core-typings/src/ICustomUserStatus.tspackages/core-typings/src/IInquiry.tspackages/core-typings/src/IInstanceStatus.tspackages/core-typings/src/ILivechatBusinessHour.tspackages/core-typings/src/ILivechatDepartment.tspackages/model-typings/src/models/ICustomSoundsModel.tspackages/model-typings/src/models/ILivechatBusinessHoursModel.tspackages/models/src/models/CustomSounds.tspackages/models/src/models/LivechatBusinessHours.tspackages/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.tsapps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.tsapps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.tspackages/core-typings/src/ILivechatBusinessHour.tspackages/core-typings/src/IInstanceStatus.tsapps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.tspackages/core-typings/src/ICustomUserStatus.tsapps/meteor/tests/data/livechat/department.tspackages/model-typings/src/models/ILivechatBusinessHoursModel.tspackages/model-typings/src/models/ICustomSoundsModel.tspackages/models/src/models/LivechatBusinessHours.tspackages/core-typings/src/ILivechatDepartment.tsapps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsxapps/meteor/client/providers/CustomSoundProvider/lib/helpers.tspackages/core-typings/src/ICustomSound.tspackages/models/src/models/CustomSounds.tspackages/ui-contexts/src/CustomSoundContext.tsapps/meteor/app/custom-sounds/server/methods/uploadCustomSound.tsapps/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.tsapps/meteor/tests/data/livechat/department.tspackages/models/src/models/LivechatBusinessHours.tsapps/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 ofIInquirywithILivechatInquiryRecord.The import and event signature change on line 74 now aligns with the existing usage on line 242 (
watch.inquiries), andILivechatInquiryRecordproperly extendsIRocketChatRecord(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
IRocketChatRecordcorrectly provides_idand_updatedAtfor this DB document type, and the remaining fields are unchanged. Consumers that don't need_updatedAtproperly useOmit<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 fromIRocketChatRecordsince 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
_updatedAtfield.packages/core-typings/src/ILivechatDepartment.ts (1)
1-3: LGTM!Consistent with the PR pattern —
ILivechatDepartmentnow correctly inherits_idand_updatedAtfromIRocketChatRecordas a proper DB document type. The separateLivechatDepartmentDTOremains unchanged, which is correct.packages/core-typings/src/ILivechatBusinessHour.ts (1)
2-2: LGTM!Same consistent pattern —
ILivechatBusinessHournow properly inherits_idand_updatedAtviaIRocketChatRecord.Also applies to: 33-33
packages/model-typings/src/models/ILivechatBusinessHoursModel.ts (1)
26-26: LGTM!Correctly excludes
_updatedAtfrom theinsertOneinput, matching the pattern used inICustomSoundsModel.create— the DB layer auto-sets this field.packages/model-typings/src/models/ICustomSoundsModel.ts (1)
9-10: Signatures match the implementation perfectly.
setNamecorrectly usesfindOneAndUpdatewithreturnDocument: 'after'to return the updated document or null.createcorrectly usesinsertOneand returnsInsertOneResult<WithId<ICustomSound>>. The type omissions for_idand_updatedAtincreate'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
_idbut not_updatedAt, soOmit<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_idgeneration and_updatedAtstamping, 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 inOmit<ILivechatBusinessHour, '_updatedAt'>, and this aligns withcreateDefaultBusinessHourRow's updated return type.packages/models/src/models/CustomSounds.ts (2)
35-43: Good refactor —setNamenow returns the updated document.Switching from
updateOnetofindOneAndUpdatewithreturnDocument: 'after'is a clean approach that eliminates the need for a separate fetch when the caller needs the updated document (as ininsertOrUpdateSound.ts).
46-48: LGTM —createparameter 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
updatedSoundcorrectly 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 passdefaultSoundselements togetCustomSoundURL. Instead, it passes items fromcustomSoundsList(which are fullICustomSoundobjects from the server methodlistCustomSounds(): ICustomSound[]) to the function, matching its parameter type exactly. ThedefaultSoundsarray 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 updatedICustomSoundshape.The annotation correctly reflects that neither
sdk.call('listCustomSounds')nordefaultSoundsinclude_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, andstatusType, soOmit<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,ICustomUserStatusgains a consolidated_updatedAtfield. Although_updatedAtis required in theIRocketChatRecordinterface, theInsertionModel<ICustomUserStatus>type utility already makes_updatedAtoptional 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.
There was a problem hiding this 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.
50d8933 to
3912614
Compare
There was a problem hiding this 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 | 🔴 CriticalType mismatch in
sync()method:sdk.call('listCustomUserStatus')returnsICustomUserStatus[]butcreateFromCustom()expectsOmit<ICustomUserStatus, '_updatedAt'>.The
listCustomUserStatus()method returns fullICustomUserStatusobjects (which include_updatedAtfromIRocketChatRecord), butcreateFromCustom()at line 36 requiresOmit<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. Thesync()method should either strip_updatedAtbefore passing tocreateFromCustom(), or the method signature should accept the fullICustomUserStatustype.
🧹 Nitpick comments (1)
apps/meteor/tests/data/livechat/department.ts (1)
200-205: TheOmitis effectively a no-op due to the index signature onILivechatDepartment.Since
ILivechatDepartmentdeclares[k: string]: any,Omit<ILivechatDepartment, '_updatedAt'>still allows_updatedAtto be accessed (asany) 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
Omitdoesn't provide the type-safety it suggests. If the index signature onILivechatDepartmentis ever tightened, this will need revisiting.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (23)
apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.tsapps/meteor/app/custom-sounds/server/methods/uploadCustomSound.tsapps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.tsapps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.tsapps/meteor/client/lib/userStatuses.tsapps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsxapps/meteor/client/providers/CustomSoundProvider/lib/helpers.tsapps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.stories.tsxapps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.tsxapps/meteor/tests/data/livechat/department.tspackages/core-services/src/events/Events.tspackages/core-typings/src/ICronHistoryItem.tspackages/core-typings/src/ICustomSound.tspackages/core-typings/src/ICustomUserStatus.tspackages/core-typings/src/IInquiry.tspackages/core-typings/src/IInstanceStatus.tspackages/core-typings/src/ILivechatBusinessHour.tspackages/core-typings/src/ILivechatDepartment.tspackages/model-typings/src/models/ICustomSoundsModel.tspackages/model-typings/src/models/ILivechatBusinessHoursModel.tspackages/models/src/models/CustomSounds.tspackages/models/src/models/LivechatBusinessHours.tspackages/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.tspackages/core-typings/src/ILivechatDepartment.tspackages/ui-contexts/src/CustomSoundContext.tspackages/core-typings/src/ICustomSound.tspackages/core-typings/src/IInstanceStatus.tspackages/core-typings/src/ICronHistoryItem.tsapps/meteor/client/lib/userStatuses.tsapps/meteor/tests/data/livechat/department.tspackages/model-typings/src/models/ILivechatBusinessHoursModel.tspackages/core-typings/src/ICustomUserStatus.tsapps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.tsapps/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.tspackages/core-typings/src/ICronHistoryItem.tsapps/meteor/client/lib/userStatuses.tsapps/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), soOmit<ILivechatBusinessHour, '_updatedAt'>accurately reflects the runtime shape. Clean alignment with the broaderIRocketChatRecordtype tightening.packages/core-typings/src/ICustomUserStatus.ts (1)
1-4: LGTM — clean centralization of_updatedAtviaIRocketChatRecord.This correctly removes the locally declared optional
_updatedAtin favor of inheriting the required one fromIRocketChatRecord, 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 thatICustomUserStatusinherits a required_updatedAtfromIRocketChatRecord. Objects that do carry_updatedAtremain 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
_updatedAtis now required onIRocketChatRecord, disconnectingIInstanceStatusand declaring_idexplicitly is the correct approach for documents that don't carry an_updatedAtfield.packages/core-typings/src/ICronHistoryItem.ts (1)
1-3: LGTM!Clean migration to
IRocketChatRecord—_idand_updatedAtare 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
_updatedAtfrom theinsertOneparameter is correct — it's auto-managed by the persistence layer, just like_id.packages/core-typings/src/ICustomSound.ts (1)
1-7: LGTM!Promoting
_updatedAtfrom optional to required (viaIRocketChatRecord) correctly reflects the database document shape. Downstream code that constructs objects without_updatedAt(e.g., default sounds) appropriately usesOmit<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
updatedSoundreturned bysetNameinstead of a hand-assembled partial object ensures field consistency with theICustomSoundtype. 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
setNamereturns falsy (e.g., document not found), the method still returnssoundData._idon 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
listtype is correctly widened toOmit<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 ofIRocketChatRecordas the base type.This correctly centralizes
_idand_updatedAtinto the shared base record, aligning with the PR's goal of making_updatedAta 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.
3912614 to
052278b
Compare
2cf5fba to
b92bc2c
Compare
The related model is prevented from setting the `_updatedAt` field.
…ken` to extend `IRocketChatRecord` and update `create` method to return void
…d `IRocketChatRecord`
…xtend schema definitions
5062555 to
bde31e7
Compare
There was a problem hiding this 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.
There was a problem hiding this 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
addObjectToMemoryis missing_updatedAt, inconsistent withaddObjectToDatabase.
addObjectToDatabasenow sets_updatedAt: new Date()(Line 161), but the siblingaddObjectToMemory(Lines 165–172) does not. Theas Rcast on Line 171 silently suppresses the type error, so ifIImportRecordnow 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 | 🟡 MinorType mismatch between
IFilterOptions.onCheckand theFiltermethod signatures.
IFilterOptions.onCheck(Line 10) still acceptsIUpload, butFilter.checkandFilter.onCheck(Lines 62, 140) now useOmit<OptionalId<IUpload>, '_updatedAt'>. A user-providedonCheckcallback would expect_updatedAton the file parameter, but it won't be guaranteed at runtime.Consider aligning the
IFilterOptionstype: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 | 🟡 MinorReturn value has a divergent
_updatedAttimestamp from what's stored in the database.
BaseRaw.insertOnesets_updatedAt: new Date()inside the method before storing the document (line 293 of BaseRaw.ts). The return statement increateWithRandomIdcreates a secondnew 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), andOEmbedCache.ts:21even documents this with a TODO comment. Consider either:
- Returning the result of
insertOnedirectly if the object is available- Or having
BaseRaw.insertOnereturn 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:
The TODO comment on line 21 violates the coding guideline to avoid code comments in implementation files. If
BaseRaw.insertOnereliably sets_updatedAt, remove the manual assignment entirely. If it doesn't, remove the comment and keep the assignment as intentional.
updatedAt(line 20) and_updatedAt(line 21) are created from separatenew 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._updatedAtis now redundant given theOmittype.Since the parameter type is
Omit<ILivechatDepartment, '_updatedAt'>, callers should never pass_updatedAt. Thedeleteon line 202 is dead code from a typing perspective. Note that the index signature ([k: string]: any) onILivechatDepartmentundermines theOmit— TypeScript still allows_updatedAtto be accessed asanythrough the index signature, so theOmitonly provides documentation-level intent, not enforcement.Consider removing the redundant
deleteto 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:updatedAtand_updatedAtcoexist — potential confusion.After extending
IRocketChatRecord, this interface now has both_updatedAt(inherited) andupdatedAt(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/_updatedAtunification forIOEmbedCache?packages/core-typings/src/federation/v1/FederationKey.ts (1)
4-8: Redundant_idre-declaration.
IRocketChatRecordalready provides_id. Other interfaces in this PR (e.g.,ISmarshHistory,IOAuthRefreshToken,IImportRecord) drop their explicit_idwhen switching toIRocketChatRecordinheritance. 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 forOmit<IUpload, '_updatedAt'>across storage adapters.The same
Omit<IUpload, '_updatedAt'>type andascast 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_updatedAtfrom insert-path types.The
Omit<OptionalId<IUpload>, '_updatedAt'>pattern across_validateFile,_doInsert, andinsertcorrectly reflects that_updatedAtis 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 tostore.insert. While TypeScript won't flag this (excess property checks don't apply to variables), it's semantically inconsistent with the newOmitcontract. Consider removing it if the DB layer sets_updatedAtautomatically.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (91)
apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.tsapps/meteor/app/custom-sounds/server/methods/uploadCustomSound.tsapps/meteor/app/file-upload/server/lib/FileUpload.tsapps/meteor/app/file-upload/ufs/AmazonS3/server.tsapps/meteor/app/file-upload/ufs/GoogleStorage/server.tsapps/meteor/app/file-upload/ufs/Webdav/server.tsapps/meteor/app/importer/server/classes/converters/RecordConverter.tsapps/meteor/app/livechat/imports/server/rest/sms.tsapps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.tsapps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.tsapps/meteor/client/components/ImageGallery/ImageGallery.tsxapps/meteor/client/hooks/useWorkspaceInfo.tsapps/meteor/client/lib/userStatuses.tsapps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsxapps/meteor/client/providers/CustomSoundProvider/lib/helpers.tsapps/meteor/client/startup/roles.tsapps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsxapps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.stories.tsxapps/meteor/client/views/admin/users/AdminUserForm.tsxapps/meteor/client/views/admin/users/AdminUserFormWithData.tsxapps/meteor/client/views/admin/users/UsersTable/UsersTable.tsxapps/meteor/client/views/admin/users/UsersTable/UsersTableFilters.tsxapps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.stories.tsxapps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.tsxapps/meteor/client/views/omnichannel/tags/TagEdit.tsxapps/meteor/client/views/omnichannel/tags/TagEditWithDepartmentData.tsxapps/meteor/client/views/room/ImageGallery/hooks/useImagesList.tsapps/meteor/client/views/room/contextualBar/RoomFiles/RoomFiles.stories.tsxapps/meteor/client/views/room/contextualBar/RoomFiles/components/FileItem.stories.tsxapps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.tsapps/meteor/ee/server/lib/roles/insertRole.tsapps/meteor/ee/server/lib/roles/updateRole.tsapps/meteor/ee/server/models/raw/LivechatTag.tsapps/meteor/server/services/import/service.tsapps/meteor/server/ufs/ufs-filter.tsapps/meteor/server/ufs/ufs-store.tsapps/meteor/tests/data/livechat/department.tsapps/meteor/tests/mocks/data.tspackages/core-services/src/events/Events.tspackages/core-typings/src/IBanner.tspackages/core-typings/src/ICredentialToken.tspackages/core-typings/src/ICronHistoryItem.tspackages/core-typings/src/ICustomSound.tspackages/core-typings/src/ICustomUserStatus.tspackages/core-typings/src/IEmailInbox.tspackages/core-typings/src/IEmailMessageHistory.tspackages/core-typings/src/IInquiry.tspackages/core-typings/src/IInstanceStatus.tspackages/core-typings/src/IIntegrationHistory.tspackages/core-typings/src/ILivechatBusinessHour.tspackages/core-typings/src/ILivechatDepartment.tspackages/core-typings/src/ILivechatDepartmentRecord.tspackages/core-typings/src/ILivechatTag.tspackages/core-typings/src/ILivechatTagRecord.tspackages/core-typings/src/INotification.tspackages/core-typings/src/INps.tspackages/core-typings/src/IOAuthAccessToken.tspackages/core-typings/src/IOAuthApps.tspackages/core-typings/src/IOAuthAuthCode.tspackages/core-typings/src/IOAuthRefreshToken.tspackages/core-typings/src/IOEmbedCache.tspackages/core-typings/src/IOmnichannelBusinessUnit.tspackages/core-typings/src/IPermission.tspackages/core-typings/src/IReadReceipt.tspackages/core-typings/src/IRocketChatRecord.tspackages/core-typings/src/IRole.tspackages/core-typings/src/IServerEvent.tspackages/core-typings/src/ISession.tspackages/core-typings/src/ISmarshHistory.tspackages/core-typings/src/IStats.tspackages/core-typings/src/IUpload.tspackages/core-typings/src/IUser.tspackages/core-typings/src/MessageReads.tspackages/core-typings/src/ee/IWorkspaceCredentials.tspackages/core-typings/src/federation/v1/FederationKey.tspackages/core-typings/src/import/IImportRecord.tspackages/core-typings/src/migrations/IControl.tspackages/model-typings/src/models/ICredentialTokensModel.tspackages/model-typings/src/models/ICustomSoundsModel.tspackages/model-typings/src/models/IEmailMessageHistoryModel.tspackages/model-typings/src/models/ILivechatBusinessHoursModel.tspackages/model-typings/src/models/ILivechatTagModel.tspackages/models/src/models/CredentialTokens.tspackages/models/src/models/CustomSounds.tspackages/models/src/models/EmailMessageHistory.tspackages/models/src/models/LivechatBusinessHours.tspackages/models/src/models/LivechatRooms.tspackages/models/src/models/OEmbedCache.tspackages/models/src/models/Roles.tspackages/rest-typings/src/v1/omnichannel.tspackages/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.tsxapps/meteor/ee/server/lib/roles/insertRole.tsapps/meteor/tests/mocks/data.tsapps/meteor/client/views/omnichannel/tags/TagEditWithDepartmentData.tsxpackages/ui-contexts/src/CustomSoundContext.tsapps/meteor/server/services/import/service.tspackages/core-typings/src/IRole.tsapps/meteor/ee/server/models/raw/LivechatTag.tsapps/meteor/client/views/admin/users/AdminUserFormWithData.tsxapps/meteor/client/views/room/contextualBar/RoomFiles/components/FileItem.stories.tsxapps/meteor/client/views/admin/users/UsersTable/UsersTable.tsxpackages/core-typings/src/ILivechatTag.tsapps/meteor/client/lib/userStatuses.tsapps/meteor/server/ufs/ufs-store.tsapps/meteor/client/views/room/ImageGallery/hooks/useImagesList.tspackages/core-typings/src/ISmarshHistory.tspackages/models/src/models/EmailMessageHistory.tspackages/models/src/models/OEmbedCache.tsapps/meteor/app/file-upload/ufs/GoogleStorage/server.tsapps/meteor/client/views/admin/users/AdminUserForm.tsxapps/meteor/app/file-upload/ufs/Webdav/server.tsapps/meteor/app/file-upload/ufs/AmazonS3/server.tspackages/core-typings/src/ISession.tspackages/core-typings/src/MessageReads.tspackages/core-typings/src/IOAuthAuthCode.tsapps/meteor/client/startup/roles.tsapps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsxpackages/core-typings/src/ICronHistoryItem.tspackages/models/src/models/Roles.tsapps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.tsapps/meteor/tests/data/livechat/department.tspackages/rest-typings/src/v1/omnichannel.tspackages/core-typings/src/IOAuthAccessToken.tspackages/core-typings/src/INotification.tspackages/core-typings/src/federation/v1/FederationKey.tsapps/meteor/client/views/admin/users/UsersTable/UsersTableFilters.tsxpackages/core-typings/src/import/IImportRecord.tspackages/model-typings/src/models/IEmailMessageHistoryModel.tsapps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.tspackages/model-typings/src/models/ILivechatTagModel.tsapps/meteor/app/importer/server/classes/converters/RecordConverter.tspackages/core-typings/src/migrations/IControl.tsapps/meteor/app/livechat/imports/server/rest/sms.tspackages/core-typings/src/ILivechatDepartment.tsapps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsxpackages/core-typings/src/IRocketChatRecord.tspackages/core-typings/src/IOAuthRefreshToken.tspackages/core-typings/src/IUpload.tsapps/meteor/client/components/ImageGallery/ImageGallery.tsxapps/meteor/client/views/room/contextualBar/RoomFiles/RoomFiles.stories.tsxpackages/core-typings/src/IOEmbedCache.tspackages/core-typings/src/ILivechatBusinessHour.tspackages/core-typings/src/IEmailMessageHistory.tsapps/meteor/client/hooks/useWorkspaceInfo.tsapps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.stories.tsxpackages/core-typings/src/IReadReceipt.tspackages/core-typings/src/IPermission.tspackages/model-typings/src/models/ILivechatBusinessHoursModel.tspackages/core-typings/src/ICustomUserStatus.tspackages/core-typings/src/IBanner.tspackages/core-typings/src/IServerEvent.tsapps/meteor/app/file-upload/server/lib/FileUpload.tspackages/core-typings/src/IOAuthApps.tspackages/core-typings/src/IStats.tsapps/meteor/server/ufs/ufs-filter.tspackages/core-typings/src/IEmailInbox.tsapps/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.tsapps/meteor/tests/mocks/data.tsapps/meteor/client/views/omnichannel/tags/TagEditWithDepartmentData.tsxapps/meteor/server/services/import/service.tsapps/meteor/ee/server/models/raw/LivechatTag.tsapps/meteor/client/views/admin/users/AdminUserFormWithData.tsxapps/meteor/client/views/room/contextualBar/RoomFiles/components/FileItem.stories.tsxapps/meteor/client/lib/userStatuses.tsapps/meteor/server/ufs/ufs-store.tspackages/core-typings/src/ISmarshHistory.tsapps/meteor/client/views/admin/users/AdminUserForm.tsxapps/meteor/client/startup/roles.tspackages/core-typings/src/ICronHistoryItem.tsapps/meteor/tests/data/livechat/department.tspackages/core-typings/src/migrations/IControl.tsapps/meteor/app/livechat/imports/server/rest/sms.tsapps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsxpackages/core-typings/src/IRocketChatRecord.tspackages/core-typings/src/IOAuthRefreshToken.tsapps/meteor/client/views/room/contextualBar/RoomFiles/RoomFiles.stories.tsxpackages/core-typings/src/IOEmbedCache.tspackages/core-typings/src/IEmailMessageHistory.tsapps/meteor/client/hooks/useWorkspaceInfo.tspackages/core-typings/src/IBanner.tspackages/core-typings/src/IOAuthApps.tspackages/core-typings/src/IEmailInbox.tsapps/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.tsapps/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.tsapps/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.tsapps/meteor/app/file-upload/ufs/Webdav/server.tsapps/meteor/app/file-upload/ufs/AmazonS3/server.tsapps/meteor/app/file-upload/server/lib/FileUpload.tsapps/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
_updatedAtto the mock data correctly aligns with the updated record type that now inherits_updatedAtfromIRocketChatRecord.apps/meteor/client/views/room/contextualBar/RoomFiles/RoomFiles.stories.tsx (1)
30-31: LGTM!Story mock data correctly updated to include the now-required
_updatedAtfield, 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 — unconditionalnew Date(file._updatedAt)is consistent with_updatedAtnow being required.The other date fields (
uploadedAt,modifiedAt,expiresAt) remain optional and are conditionally constructed, while_updatedAtis correctly treated as always-present per the updated core typings.apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts (1)
40-46: LGTM — unconditionalnew Dateis consistent with_updatedAtnow being required.The other timestamp fields (
uploadedAt,modifiedAt,expiresAt) remain conditionally converted because they're optional onIUpload, while_updatedAtis now guaranteed viaIRocketChatRecord. The change aligns with the PR objective.apps/meteor/tests/mocks/data.ts (1)
436-446: LGTM!The addition of
_updatedAttocreateFakeTagis consistent with how otherSerialized<…>fake creators in this file handle the field (e.g.,createFakeAgent,createFakeBusinessUnit,createFakeDepartment), and it's correctly placed before the...overridesspread.packages/core-typings/src/ILivechatDepartment.ts (1)
1-3: LGTM — clean adoption ofIRocketChatRecord.Extending
IRocketChatRecordcentralizes_idand_updatedAtconsistently, 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 updatedCustomSoundContexttype and thedefaultSoundsarray 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
listtype now matches the provider'squeryFnreturn type and the updateddefaultSoundstype, keeping the public contract consistent across the custom sound system.apps/meteor/server/services/import/service.ts (1)
147-147: LGTM —_updatedAtfield 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
IRocketChatRecordprovides both_idand_updatedAtconsistently, removing the need for a local_iddeclaration. 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
selectproperly converts_updatedAtandlastMessageSentAtfrom their serialized string forms back toDateobjects. The remainingcreatedAtfield inIStatsalready acceptsstring, 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.
createOrUpdateTagconstructs a record manually and doesn't include_updatedAt, soOmit<ILivechatTag, '_updatedAt'>is the correct return type.packages/core-typings/src/IEmailInbox.ts (1)
1-3: Consistent migration to IRocketChatRecord.
IEmailInboxcorrectly inherits_idand_updatedAtfromIRocketChatRecord. The existingIEmailInboxPayloadtype on line 32 properly omits_updatedAtwhich now comes via inheritance.packages/core-typings/src/IReadReceipt.ts (1)
2-2: Consistent migration to IRocketChatRecord.
IReadReceiptnow inherits both_idand_updatedAtfromIRocketChatRecord. Note that this adds a new required_updatedAtfield 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. TheOmit<ILivechatTag, '_updatedAt'>return type accurately describes this. The type aligns with the model interface definition inILivechatTagModel.ts.packages/core-typings/src/IOAuthApps.ts (1)
1-3: Consistent migration to IRocketChatRecord.
IOAuthAppscorrectly inherits_idand_updatedAtfromIRocketChatRecord, replacing the previously local declarations. Domain-specific fields like_createdAtand_createdByremain 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
TimestampSchemais a good pattern for ensuring_updatedAtis consistently typed across all record types. The empty interface extendingz.infer<>preserves a named type for consumers.
2-2: : The importimport * as z from 'zod'is consistent with the project convention. All zod imports across the codebase use the namespace import styleimport * as z from 'zod', not alternative patterns likeimport { 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
IRocketChatRecordcorrectly replaces the local_iddeclaration and adds the required_updatedAtfield, 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-disablefor naming convention is reasonable to preserve backward compatibility with the existingMessageReadsname.packages/model-typings/src/models/ILivechatBusinessHoursModel.ts (1)
26-26: LGTM — correctly excludes_updatedAtfrom insertion input.Since
_updatedAtis now part ofILivechatBusinessHourviaIRocketChatRecord, omitting it from theinsertOneparameter is correct — the database layer should set this field automatically.packages/core-typings/src/IServerEvent.ts (1)
1-1: LGTM — consistent migration to IRocketChatRecord.
IServerEventcorrectly inherits_idand_updatedAtfrom the base record type.Also applies to: 18-18
packages/core-typings/src/migrations/IControl.ts (1)
1-9: Remove the concern about_updatedAtnot being set in migration control documents. TheBaseRaw.updateMany()method automatically adds_updatedAtvia thesetUpdatedAt()function, which detects MongoDB operators and injects the timestamp into the$setclause. Migration control documents are guaranteed to have this field, making the type cast ingetControl()safe.packages/core-typings/src/ILivechatBusinessHour.ts (1)
33-41: LGTM — consistent adoption ofIRocketChatRecord.The migration from locally declared
_id/_updatedAtto extendingIRocketChatRecordis clean and aligns with the PR objective. Downstream consumers already useOmit<ILivechatBusinessHour, '_updatedAt'>where the field isn't yet available.packages/core-typings/src/IUpload.ts (1)
5-67: LGTM —IUploadnow inherits identity fields fromIRocketChatRecord.apps/meteor/app/livechat/imports/server/rest/sms.ts (1)
30-30: LGTM — correctly excludes_updatedAtfrom the input shape.Since
IUploadnow inherits a required_updatedAtfromIRocketChatRecord, 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 —ILivechatTagproperly migrated toIRocketChatRecord.apps/meteor/client/views/omnichannel/tags/TagEditWithDepartmentData.tsx (1)
1-9: LGTM — correct use ofSerialized<ILivechatTag>for API-sourced data.Since
ILivechatTagnow includes_updatedAt: DateviaIRocketChatRecord, wrapping inSerializedproperly reflects the wire format whereDatefields become strings.apps/meteor/client/views/omnichannel/tags/TagEdit.tsx (1)
27-27: LGTM — prop type aligns with the parent component'sSerialized<ILivechatTag>.packages/core-typings/src/ICustomUserStatus.ts (1)
4-4: No issues found. The dual extension is valid: bothIUserStatusandIRocketChatRecorddeclare_id: string(compatible), and_updatedAtis only inIRocketChatRecord. 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, soOmit<ILivechatTag, '_updatedAt'>correctly reflects what the validator actually accepts.packages/core-typings/src/ISession.ts (1)
1-16: LGTM — ISession correctly extends IRocketChatRecord.Centralizing
_idand_updatedAtunderIRocketChatRecordis consistent with the PR objective. Note that_updatedAtgoes 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, andstatusType, so omitting_updatedAtfrom the parameter type accurately reflects the actual data contract.packages/core-typings/src/IOAuthAccessToken.ts (1)
1-10: LGTM — clean migration to IRocketChatRecord.
_idand_updatedAtare 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
_updatedAtfield and centralizes_idunder 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 thecopypath (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 ofIRocketChatRecordbase.Replacing the standalone
_iddeclaration withIRocketChatRecordinheritance givesIImportRecord(and all its sub-interfaces) a properly typed_idand_updatedAt. Clean and consistent with the rest of the PR.packages/core-typings/src/IOAuthRefreshToken.ts (1)
1-3: LGTM —IOAuthRefreshTokennow correctly inherits fromIRocketChatRecord.Consistent with the PR-wide pattern. The interface gains
_idand_updatedAtfrom 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, andtype— 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 — standardIRocketChatRecordadoption.packages/core-typings/src/IEmailMessageHistory.ts (1)
1-3: LGTM — standardIRocketChatRecordadoption.packages/model-typings/src/models/IEmailMessageHistoryModel.ts (1)
4-7: LGTM — correct use ofInsertionModelfor the create signature.Using
InsertionModel<IEmailMessageHistory>properly reflects that_updatedAtis managed by the persistence layer and_idis optional at insertion time.packages/models/src/models/EmailMessageHistory.ts (1)
16-22: LGTM — implementation aligns with the updated model typing.The
createdAtis correctly set at insertion time, and_updatedAtis presumably managed byBaseRaw.insertOne.packages/core-typings/src/ICronHistoryItem.ts (1)
1-10: LGTM — properly extendsIRocketChatRecordfor 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
_updatedAtisn'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 —INotificationcorrectly extendsIRocketChatRecord.packages/core-typings/src/IBanner.ts (1)
13-35: LGTM — schema and interface properly unified underIRocketChatRecordSchema/IRocketChatRecord.The dual extension on
IBanner(line 35) is slightly redundant sinceIBannerSchemaalready extendsIRocketChatRecordSchema, 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 ontoIRocketChatRecord.Extending
IRocketChatRecordproperly inherits_idand_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'>andPick<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 forgetPathis 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 thefileparameter increatehas 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 fullIUploadshape.apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.stories.tsx (1)
20-84: Mock data correctly updated to include required_updatedAtfield.The
IRoleobjects now satisfy theIRocketChatRecordcontract. 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 updatedIRoletype.Both role entries now include
_updatedAt, matching the story data and satisfying theIRocketChatRecordrequirement.apps/meteor/ee/server/lib/roles/insertRole.ts (1)
12-12: Input type correctly excludes_updatedAt.Since
_updatedAtis server-managed (set byRoles.createWithRandomId), excluding it from the input prevents callers from providing a potentially stale timestamp. The return typePromise<IRole>still includes_updatedAtfrom the DB response, which is correct.apps/meteor/client/views/admin/users/AdminUserForm.tsx (1)
53-53: LGTM — type change toSerialized<IRole>[]is consistent and correct.The component only destructures
_id,name, anddescriptionfrom role objects (line 135), all of which are strings unaffected by serialization. This aligns with the same change applied acrossAdminUserFormWithData,UsersTable, andUsersTableFilters.apps/meteor/client/views/admin/users/UsersTable/UsersTable.tsx (1)
27-27: LGTM — consistent type update.The
roleDataprop 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_updatedAtfrom the input parameter.The
_updatedAtfield is managed by the database layer, so excluding it fromroleDataprevents callers from accidentally supplying a stale or incorrect timestamp. The re-fetch at lines 56–61 ensures the returnedIRolehas the correct server-set_updatedAt.apps/meteor/client/views/admin/users/AdminUserFormWithData.tsx (1)
1-1: LGTM — consistent type propagation toAdminUserForm.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, | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 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
fiRepository: 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);
EOFRepository: 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 2Repository: 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.
| 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).
Proposed changes (including videos or screenshots)
Some record types (i.e. types that represent database documents) are not properly declaring the presence of the
_updatedAtfield. 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
User Interface
Refactor