From 75863157c017b99f755cec4b642e619ec9edba0f Mon Sep 17 00:00:00 2001 From: codyllord Date: Thu, 10 Sep 2026 16:31:50 +0000 Subject: [PATCH 1/3] feat(services): add get_access_audit to the System API MCP tool catalogue Read-only tool that reports last-used / never-used / stale API keys, roles and users from system/access_usage. Catalogue and spec go from 17 to 18 tools; df-system-mcp-server TOOL_NAMES must list it after list_admins. --- .../df-service-details/system-mcp-tools.spec.ts | 5 +++-- .../adf-services/df-service-details/system-mcp-tools.ts | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/app/adf-services/df-service-details/system-mcp-tools.spec.ts b/src/app/adf-services/df-service-details/system-mcp-tools.spec.ts index f1d21e91..47a29205 100644 --- a/src/app/adf-services/df-service-details/system-mcp-tools.spec.ts +++ b/src/app/adf-services/df-service-details/system-mcp-tools.spec.ts @@ -22,12 +22,13 @@ const EXPECTED_TOOL_NAMES = [ 'create_app', 'get_app', 'list_admins', + 'get_access_audit', 'call_system_api', ]; describe('SYSTEM_MCP_TOOLS catalogue', () => { - it('contains exactly the 17 tools exposed by df-system-mcp-server', () => { - expect(SYSTEM_MCP_TOOLS.length).toBe(17); + it('contains exactly the 18 tools exposed by df-system-mcp-server', () => { + expect(SYSTEM_MCP_TOOLS.length).toBe(18); expect(SYSTEM_MCP_TOOLS.map(t => t.name)).toEqual(EXPECTED_TOOL_NAMES); }); diff --git a/src/app/adf-services/df-service-details/system-mcp-tools.ts b/src/app/adf-services/df-service-details/system-mcp-tools.ts index c884bd61..3db1114c 100644 --- a/src/app/adf-services/df-service-details/system-mcp-tools.ts +++ b/src/app/adf-services/df-service-details/system-mcp-tools.ts @@ -101,6 +101,13 @@ export const SYSTEM_MCP_TOOLS: ReadonlyArray = [ title: 'List Admins', description: 'List the administrator accounts on this instance.', }, + // Access audit (read-only) + { + name: 'get_access_audit', + title: 'Get Access Audit', + description: + 'Report last-used / never-used / stale API keys, roles and users from system/access_usage.', + }, // Generic { name: 'call_system_api', From f44fe183e37a8359ae79bd93c584cb5ed52db1f6 Mon Sep 17 00:00:00 2001 From: codyllord Date: Thu, 10 Sep 2026 16:39:48 +0000 Subject: [PATCH 2/3] feat(access-usage): last-used column and "Not used in" filter on apps, roles, users, admins Join GET system/access_usage client-side (like the apps table's AI usage join) through a new DfAccessUsageService, and opt the apps, roles, users and admins tables into it via DfManageTableComponent.enableAccessUsage(): - "Last used" (apps, roles) / "Last active" (users, admins) column with relative time or "Never"; tooltip carries the exact time, the service and status of the last use, the last denial, stale window, last login and 30-day volume when present, and "no use recorded since" tracking start for never-used subjects - muted text for stale / never-used subjects, a warning icon for inactive keys that clients still send, an "Unreferenced" badge on roles - "Not used in" selector (Any / 30 / 90 / 180 days / Never used), filtering the loaded rows client-side; the column sorts by last use The request is silent: on 404 (older DreamFactory), 401/403, 400 or any error the column and filter stay hidden and the tables render as before. --- .../df-manage-admins-table.component.ts | 1 + .../df-manage-apps-table.component.html | 33 +- .../df-manage-apps-table.component.ts | 4 + .../df-manage-apps-table.spec.ts | 63 ++++ .../df-manage-roles-table.component.ts | 1 + .../df-manage-users-table.component.ts | 1 + .../df-access-usage-cell.component.html | 26 ++ .../df-access-usage-cell.component.scss | 23 ++ .../df-access-usage-cell.component.spec.ts | 143 ++++++++ .../df-access-usage-cell.component.ts | 81 +++++ .../access-usage-table-state.ts | 79 +++++ .../df-manage-table-access-usage.spec.ts | 192 ++++++++++ .../df-manage-table.component.html | 33 +- .../df-manage-table.component.scss | 5 + .../df-manage-table.component.ts | 64 +++- src/app/shared/constants/urls.ts | 1 + .../services/df-access-usage.service.spec.ts | 160 +++++++++ .../services/df-access-usage.service.ts | 72 ++++ src/app/shared/types/access-usage.ts | 59 +++ src/app/shared/utilities/access-usage.spec.ts | 335 ++++++++++++++++++ src/app/shared/utilities/access-usage.ts | 228 ++++++++++++ src/assets/i18n/en.json | 29 ++ src/styles.scss | 6 + 23 files changed, 1634 insertions(+), 5 deletions(-) create mode 100644 src/app/shared/components/df-access-usage-cell/df-access-usage-cell.component.html create mode 100644 src/app/shared/components/df-access-usage-cell/df-access-usage-cell.component.scss create mode 100644 src/app/shared/components/df-access-usage-cell/df-access-usage-cell.component.spec.ts create mode 100644 src/app/shared/components/df-access-usage-cell/df-access-usage-cell.component.ts create mode 100644 src/app/shared/components/df-manage-table/access-usage-table-state.ts create mode 100644 src/app/shared/components/df-manage-table/df-manage-table-access-usage.spec.ts create mode 100644 src/app/shared/services/df-access-usage.service.spec.ts create mode 100644 src/app/shared/services/df-access-usage.service.ts create mode 100644 src/app/shared/types/access-usage.ts create mode 100644 src/app/shared/utilities/access-usage.spec.ts create mode 100644 src/app/shared/utilities/access-usage.ts diff --git a/src/app/adf-admins/df-manage-admins/df-manage-admins-table.component.ts b/src/app/adf-admins/df-manage-admins/df-manage-admins-table.component.ts index d50c6dac..10ca137c 100644 --- a/src/app/adf-admins/df-manage-admins/df-manage-admins-table.component.ts +++ b/src/app/adf-admins/df-manage-admins/df-manage-admins-table.component.ts @@ -39,6 +39,7 @@ export class DfManageAdminsTableComponent extends DfManageTableComponent
+ + + {{ 'accessUsage.filter.label' | transloco }} + + + {{ option.label | transloco }} + + + + {{ column?.cell(row) }} + - + {{ 'noFilterResults' | transloco }}
+ + + {{ 'accessUsage.filter.label' | transloco }} + + + {{ option.label | transloco }} + + + + {{ column?.cell(row) }}
+ - + {{ 'noFilterResults' | transloco }}