Skip to content

refactor(audit): derive updatedFields through one shared helper - #6604

Merged
waleedlatif1 merged 2 commits into
stagingfrom
refactor/audit-updated-fields-helper
Aug 12, 2026
Merged

refactor(audit): derive updatedFields through one shared helper#6604
waleedlatif1 merged 2 commits into
stagingfrom
refactor/audit-updated-fields-helper

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Six copies of Object.keys(updateData).filter(k => k !== 'updatedAt') across four files each decided independently which columns an audit row reports. The updatedAt exclusion is an audit convention, not a local detail, so it moves to @sim/audit as auditUpdatedFields and becomes a single edit
  • Fixes a real inconsistency along the way: v1/admin/organizations/[id]/route.ts evaluated the expression twice in one handler and filed it under the metadata key fields, while every other site uses updatedFields. Any consumer filtering on updatedFields silently missed org updates. Verified nothing reads metadata.fields before renaming
  • Follow-up to fix(mcp): audit the columns an MCP server update wrote, not the params it got #6598 and fix(mcp): audit an upsert that rewrites or revives a server #6602, which converged the MCP paths onto reporting written columns

Sites converted

File Was
lib/mcp/orchestration/server-lifecycle.ts:403 inline
lib/mcp/orchestration/workflow-mcp-lifecycle.ts:552, :939 inline ×2
lib/credentials/orchestration/index.ts:339 inline
app/api/v1/admin/organizations/[id]/route.ts:182, :193 inline ×2, double-evaluated, key fields

Testing-mock note

auditMock carries the real implementation, not a vi.fn() stub — callers under test derive their audit metadata through it, so stubbing would erase exactly what those tests assert. The two suites that hand-roll their own @sim/audit factory (credentials/orchestration, workflow-mcp-lifecycle) source it from auditMock rather than re-inlining, so there is still one implementation.

Type of Change

  • Refactor

Testing

  • New packages/audit/src/updated-fields.test.ts: written columns, updatedAt dropped, explicitly-null columns kept (clearing a value is a change), and the only-updatedAt empty case
  • 933 tests pass across lib/mcp, lib/credentials, lib/copilot/tools/handlers/deployment, app/api/mcp, app/api/v1/admin, app/api/v2/mcp; 29 in packages/audit
  • lint:check and check:api-validation:strict pass; typecheck clean

Local-verification caveat worth knowing: this was developed in a git worktree whose node_modules symlinks to the main checkout, so @sim/audit and @sim/testing resolve to the main copy and a new package export is invisible to the worktree's test run. Every result above was produced by temporarily materializing the two package files into the main checkout, running, then restoring it — otherwise the run reports phantom failures that look like this change breaking 100+ audit-mocking suites.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Aug 12, 2026 5:10am

Request Review

@cursor

cursor Bot commented Aug 12, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Pure refactor of identical audit metadata derivation with a small metadata key rename; no auth, security, or write-path behavior changes.

Overview
Consolidates six copies of the Object.keys(...).filter(k !== 'updatedAt') audit convention into a shared auditUpdatedFields helper in @sim/audit, and switches credential, MCP server, workflow MCP, and admin org update paths to use it.

Also renames the admin organization update audit metadata key from fields to updatedFields so it matches every other writer. Test mocks expose the real helper (not a stub) so assertions on derived fields keep working.

Reviewed by Cursor Bugbot for commit 9c6d5b6. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR centralizes audit updated-field derivation in @sim/audit and adopts the helper across organization, credential, and MCP update paths. It also standardizes organization audit metadata on updatedFields and updates shared test mocks.

  • Adds and exports auditUpdatedFields.
  • Replaces six inline field-filter expressions with the shared helper.
  • Adds helper behavior and mock-parity tests.
  • Renames organization audit metadata from fields to updatedFields.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
packages/audit/src/updated-fields.ts Introduces the shared helper that returns written keys while excluding updatedAt.
apps/sim/app/api/v1/admin/organizations/[id]/route.ts Reuses one derived field list for logging and standardized organization audit metadata.
apps/sim/lib/credentials/orchestration/index.ts Replaces inline audit-field derivation with the shared helper.
apps/sim/lib/mcp/orchestration/server-lifecycle.ts Uses the shared helper for updated fields returned from MCP server updates.
apps/sim/lib/mcp/orchestration/workflow-mcp-lifecycle.ts Uses the shared helper in workflow MCP server and tool update audit paths.
packages/testing/src/mocks/audit.mock.ts Exposes auditUpdatedFields through the shared audit test mock.

Reviews (2): Last reviewed commit: "test(audit): pin the testing mock's copy..." | Re-trigger Greptile

Comment thread packages/audit/src/index.ts
Comment thread packages/testing/src/mocks/audit.mock.ts
Six copies of Object.keys(updateData).filter(k => k !== 'updatedAt') across
four files decided, independently, which columns an audit row reports. The
exclusion set is an audit convention, not a local detail, so it moves to
@sim/audit as auditUpdatedFields and the exclusion becomes a single edit.

The admin organizations route evaluated the expression twice in one handler
and filed it under the metadata key `fields` while every other site uses
`updatedFields`, so any consumer filtering on updatedFields silently missed
org updates. It now computes once and uses the shared key; nothing reads
metadata.fields.

auditMock carries the real implementation rather than a stub, since callers
under test derive their audit metadata through it. The two suites that
hand-roll an @sim/audit factory source it from there.
@sim/audit devDepends on @sim/testing, so the mock cannot import the real
helper without closing a package cycle. Assert parity from the audit side
instead, where the dependency already runs the safe direction, so a change to
the exclusion convention cannot leave mocked callers validating behavior the
deployed helper no longer has.
@waleedlatif1
waleedlatif1 force-pushed the refactor/audit-updated-fields-helper branch from 1257a97 to 9c6d5b6 Compare August 12, 2026 05:10
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@waleedlatif1
waleedlatif1 merged commit 068422b into staging Aug 12, 2026
24 checks passed
@waleedlatif1
waleedlatif1 deleted the refactor/audit-updated-fields-helper branch August 12, 2026 05:12

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 9c6d5b6. Configure here.

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