Skip to content

Conversation

@lwin-kyaw
Copy link
Contributor

@lwin-kyaw lwin-kyaw commented Dec 17, 2025

Explanation

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Adds an updatedAt timestamp to claim drafts and updates it on create/update, with tests and changelog updated.

  • Claims Controller:
    • Types: Include updatedAt in ClaimDraft (packages/claims-controller/src/types.ts).
    • Logic: saveOrUpdateClaimDraft now sets updatedAt on create and refreshes it on updates; return value includes updatedAt (packages/claims-controller/src/ClaimsController.ts).
    • Tests: Update draft tests to expect updatedAt (packages/claims-controller/src/ClaimsController.test.ts).
  • Docs:
    • Update changelog to note updatedAt addition (packages/claims-controller/CHANGELOG.md).

Written by Cursor Bugbot for commit 23cae10. This will update automatically on new commits. Configure here.

@lwin-kyaw lwin-kyaw requested a review from a team as a code owner December 17, 2025 06:24
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Bug: Updated draft return omits new timestamp

When updating an existing draft, saveOrUpdateClaimDraft writes a merged object with a new updatedAt into state, but returns draft as ClaimDraft (the input), which can omit updatedAt and other persisted fields. This makes the function’s return value inconsistent with state and can break callers expecting the new updatedAt.

packages/claims-controller/src/ClaimsController.ts#L225-L247

*/
saveOrUpdateClaimDraft(draft: Partial<ClaimDraft>): ClaimDraft {
const { drafts } = this.state;
const isExistingDraft = drafts.some(
(existingDraft) =>
draft.draftId && existingDraft.draftId === draft.draftId,
);
if (isExistingDraft) {
this.update((state) => {
state.drafts = state.drafts.map((existingDraft) =>
existingDraft.draftId === draft.draftId
? {
...existingDraft,
...draft,
updatedAt: new Date().toISOString(),
}
: existingDraft,
);
});
return draft as ClaimDraft;
}

Fix in Cursor Fix in Web


@lwin-kyaw lwin-kyaw requested a review from a team as a code owner December 17, 2025 06:25
@lwin-kyaw
Copy link
Contributor Author

@metamaskbot publish-preview

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Bug: Updated draft return omits new timestamp

When updating an existing draft, saveOrUpdateClaimDraft writes updatedAt (and merged fields) into state.drafts, but it returns the input draft cast to ClaimDraft. Callers relying on the return value won’t see the newly generated updatedAt, making the API inconsistent with the “returns the saved draft” behavior used for new drafts.

packages/claims-controller/src/ClaimsController.ts#L233-L247

if (isExistingDraft) {
this.update((state) => {
state.drafts = state.drafts.map((existingDraft) =>
existingDraft.draftId === draft.draftId
? {
...existingDraft,
...draft,
updatedAt: new Date().toISOString(),
}
: existingDraft,
);
});
return draft as ClaimDraft;
}

Fix in Cursor Fix in Web


@lwin-kyaw lwin-kyaw added area-shield Transaction Shield team-shield labels Dec 17, 2025
cursor[bot]

This comment was marked as outdated.

@lwin-kyaw lwin-kyaw force-pushed the fix/claims-draft-timestamp branch from 5f79425 to 23cae10 Compare December 17, 2025 06:47
@lwin-kyaw
Copy link
Contributor Author

@metamaskbot publish-preview

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Bug: Persisted drafts may lack `updatedAt`

updatedAt is only set when creating or updating via saveOrUpdateClaimDraft, but existing persisted state.drafts from older versions can remain without updatedAt indefinitely (until edited). Consumers that start relying on draft.updatedAt after this change may break or mis-sort drafts for upgraded users.

packages/claims-controller/src/ClaimsController.ts#L225-L273

*/
saveOrUpdateClaimDraft(draft: Partial<ClaimDraft>): ClaimDraft {
const { drafts } = this.state;
const isExistingDraft = drafts.some(
(existingDraft) =>
draft.draftId && existingDraft.draftId === draft.draftId,
);
if (isExistingDraft) {
const updatedAt = new Date().toISOString();
this.update((state) => {
state.drafts = state.drafts.map((existingDraft) =>
existingDraft.draftId === draft.draftId
? {
...existingDraft,
...draft,
updatedAt,
}
: existingDraft,
);
});
return { ...draft, updatedAt } as ClaimDraft;
}
// generate a new draft id, name and add it to the state
const draftId = `draft-${Date.now()}`;
const newDraft: ClaimDraft = {
...draft,
draftId,
updatedAt: new Date().toISOString(),
};
this.update((state) => {
state.drafts.push(newDraft);
});
return newDraft;
}
/**
* Get the list of claim drafts.
*
* @returns The list of claim drafts.
*/
getClaimDrafts(): ClaimDraft[] {
return this.state.drafts;
}

packages/claims-controller/src/types.ts#L50-L61

export type ClaimDraft = Partial<
Omit<
Claim,
'id' | 'shortId' | 'createdAt' | 'intercomId' | 'status' | 'attachments'
>
> & {
/**
* The draft ID.
*/
draftId: string;
};

Fix in Cursor Fix in Web


@lwin-kyaw
Copy link
Contributor Author

Bug: Persisted drafts may lack updatedAt

updatedAt is only set when creating or updating via saveOrUpdateClaimDraft, but existing persisted state.drafts from older versions can remain without updatedAt indefinitely (until edited). Consumers that start relying on draft.updatedAt after this change may break or mis-sort drafts for upgraded users.

packages/claims-controller/src/ClaimsController.ts#L225-L273

*/
saveOrUpdateClaimDraft(draft: Partial<ClaimDraft>): ClaimDraft {
const { drafts } = this.state;
const isExistingDraft = drafts.some(
(existingDraft) =>
draft.draftId && existingDraft.draftId === draft.draftId,
);
if (isExistingDraft) {
const updatedAt = new Date().toISOString();
this.update((state) => {
state.drafts = state.drafts.map((existingDraft) =>
existingDraft.draftId === draft.draftId
? {
...existingDraft,
...draft,
updatedAt,
}
: existingDraft,
);
});
return { ...draft, updatedAt } as ClaimDraft;
}
// generate a new draft id, name and add it to the state
const draftId = `draft-${Date.now()}`;
const newDraft: ClaimDraft = {
...draft,
draftId,
updatedAt: new Date().toISOString(),
};
this.update((state) => {
state.drafts.push(newDraft);
});
return newDraft;
}
/**
* Get the list of claim drafts.
*
* @returns The list of claim drafts.
*/
getClaimDrafts(): ClaimDraft[] {
return this.state.drafts;
}

packages/claims-controller/src/types.ts#L50-L61

export type ClaimDraft = Partial<
Omit<
Claim,
'id' | 'shortId' | 'createdAt' | 'intercomId' | 'status' | 'attachments'
>
> & {
/**
* The draft ID.
*/
draftId: string;
};

Fix in Cursor Fix in Web

claims draft is not released yet in the clients. So, it's safe to assume that this won't be an issue.

@lwin-kyaw lwin-kyaw added this pull request to the merge queue Dec 17, 2025
Merged via the queue into main with commit a44b12f Dec 17, 2025
285 checks passed
@lwin-kyaw lwin-kyaw deleted the fix/claims-draft-timestamp branch December 17, 2025 07:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-shield Transaction Shield team-shield

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants