Skip to content

feat: add optional field audit columns to permission manager - #1992

Open
paustint wants to merge 1 commit into
mainfrom
feat/field-permission-audit-columns
Open

feat: add optional field audit columns to permission manager#1992
paustint wants to merge 1 commit into
mainfrom
feat/field-permission-audit-columns

Conversation

@paustint

Copy link
Copy Markdown
Contributor

Created/modified date and user for each field, toggled from a gear menu on the Field Permissions tab and always included in exports. Data comes from Tooling CustomField joined on FieldDefinitionId, since EntityParticle has no audit fields. Standard fields have none in Salesforce, so they stay blank.

Closes #900

Copilot AI lite review requested due to automatic review settings August 22, 2026 13:31
@paustint
paustint force-pushed the feat/field-permission-audit-columns branch from bd5a957 to 5173cb9 Compare August 22, 2026 13:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds optional Salesforce custom-field audit metadata to the Permission Manager, with configurable table columns and audit data included in exports.

Changes:

  • Queries and joins CustomField audit data.
  • Adds persisted gear-menu column visibility controls.
  • Includes audit fields in CSV/XLSX exports with tests.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.

Show a summary per file
File Description
libs/types/src/lib/ui/permission-manager-types.ts Adds audit metadata and row fields.
libs/types/src/lib/salesforce/record.types.ts Defines CustomField audit records.
libs/shared/ui-app-state/src/lib/ui-app-state.ts Adds the audit-column storage key.
libs/shared/constants/src/lib/shared-constants.ts Adds the analytics event key.
libs/features/manage-permissions/src/utils/permission-manager-utils.ts Builds audit queries.
libs/features/manage-permissions/src/utils/permission-manager-table-utils.tsx Adds audit columns and row mapping.
libs/features/manage-permissions/src/utils/permission-manager-field-audit-columns.ts Defines audit-column keys, labels, and helpers.
libs/features/manage-permissions/src/utils/permission-manager-export-utils.ts Exports audit columns and values.
libs/features/manage-permissions/src/utils/__tests__/permission-manager-field-rows-audit.spec.ts Tests audit row mapping.
libs/features/manage-permissions/src/utils/__tests__/permission-manager-field-export.spec.ts Tests audit exports.
libs/features/manage-permissions/src/utils/__tests__/permission-manager-field-audit-columns.spec.ts Tests column behavior.
libs/features/manage-permissions/src/utils/__tests__/permission-manager-custom-field-audit-query.spec.ts Tests query construction.
libs/features/manage-permissions/src/usePermissionRecords.tsx Loads and joins audit data.
libs/features/manage-permissions/src/ManagePermissionsEditor.tsx Manages visibility, persistence, and exports.
libs/features/manage-permissions/src/FieldAuditColumnsPopover.tsx Provides audit-column controls.
Suppressed comments (2)

libs/features/manage-permissions/src/ManagePermissionsEditor.tsx:884

  • When reloadPermissions sets hasLoaded to false, this Tabs instance is unmounted and the new instance initializes to Field Permissions. activeTabId is not reset, so reloading from System Permissions leaves the visible tab on Field Permissions while this condition remains false and hides the audit gear until the user switches tabs. Reset activeTabId when starting the reload, or make the tab selection controlled.
            <Icon type="utility" icon="refresh" className="slds-button__icon slds-button__icon_left" />

libs/features/manage-permissions/src/utils/permission-manager-utils.ts:1064

  • This lookup relies exclusively on EntityDefinition.QualifiedApiName, so any object/API response where that relationship does not resolve makes the new audit data disappear (or causes the whole supplemental query to be marked unavailable). The existing CustomField resolver in libs/features/analysis-shared/src/field-usage/compute-field-usage-where-used.ts explicitly falls back to TableEnumOrId for unresolved lookups; apply the same fallback here so audit columns do not become blank for those objects.
          field: 'EntityDefinition.QualifiedApiName',

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI review requested due to automatic review settings August 22, 2026 13:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@paustint
paustint force-pushed the feat/field-permission-audit-columns branch from 5173cb9 to 3d9d5d6 Compare August 23, 2026 01:40
@paustint

Copy link
Copy Markdown
Contributor Author

Code review summary

Automated review (Claude Code). Fixes below are pushed as an amend to the PR head.

Verdict: solid, well-tested implementation. The Tooling CustomField join was verified against a live org and is correct.

Verified live: the EntityDefinitionId join works for both standard and custom objects, CustomField supports queryMore, xlsx merges shift correctly, and a Tooling failure degrades gracefully rather than failing the whole permission-manager load.

Fixed and pushed

  • FieldAuditColumnsPopover.tsx — replaced hand-rolled SLDS checkbox markup with the shared Checkbox from @jetstream/ui, matching the fieldset+legend convention used in TeamLoginConfiguration.tsx. The wrapping slds-form-element__control div was dropped because Checkbox emits its own and nesting them is invalid SLDS; fieldset grouping and label/id association are unchanged.
  • Extracted and tested the join key. ${EntityDefinitionId}.${Id.slice(0, 15)} was the riskiest line in the PR and had no test. Moved to getFieldDefinitionKeyFromCustomField in permission-manager-utils.ts with a 4-case spec (standard object, custom object, 18-char id truncated, 15-char id unchanged). Pure extraction — key format is byte-identical.
  • permission-manager-table-utils.tsx — doc comment contradicted the code it describes; updated for the audit columns.

(110 tests pass, up from 106; typecheck clean.)

Needs a decision

  • The opt-in audit query runs unconditionally (usePermissionRecords.tsx:107), inside a blocking Promise.all — so it slows every permission-manager load even when all audit columns are hidden. Fixing it means restructuring the fetch gating.
  • Exports always gain 4 columns (permission-manager-export-utils.ts:27), shifting every downstream permission column index. That breaks existing user templates — worth a release-note callout if intended.

Branch is behind main by 2 merge commits (#1980, #1990, unrelated files) — needs a rebase before merge.

Created/modified date and user for each field, toggled from a gear menu on
the Field Permissions tab and always included in exports. Data comes from
Tooling CustomField joined on FieldDefinitionId, since EntityParticle has no
audit fields. Standard fields have none in Salesforce, so they stay blank.

Closes #900
@paustint
paustint force-pushed the feat/field-permission-audit-columns branch from 3d9d5d6 to 6f02b8a Compare August 23, 2026 12:43
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.

Sort Fields by Created Date in Manage Permissions View

2 participants