| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Move audit event creation from client-side to service functions for search, repos, file source, and file tree endpoints. Add source metadata to distinguish MCP requests from other API calls. Extend analytics SQL to include new actions and display MCP request and API request counts on the analytics dashboard. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. Configuration used: Organization UI Review profile: CHILL Plan: Pro 📥 CommitsReviewing files that changed from the base of the PR and between 6726cf2 and 3af7c41. 📒 Files selected for processing (10)
WalkthroughMoves audit event emission from client to server-side service functions, adds a request source field (from X-Sourcebot-Client-Source), records MCP vs API requests, exposes mcp_requests and api_requests in analytics types/queries, adds pruning for audit retention, and updates docs and data generation. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Server
participant AuditService
participant DB
participant AnalyticsUI
Client->>Server: request (includes X-Sourcebot-Client-Source header)
Server->>AuditService: emit audit event (actor, action, target, metadata.source)
AuditService->>DB: insert audit record
Note right of DB: DB stores record with source and timestamp
Server->>Client: respond with requested data
AnalyticsUI->>Server: query analytics (rows + retention + oldestRecordDate)
Server->>DB: aggregate audits by action + metadata.source
DB-->>Server: aggregated rows (mcp_requests, api_requests, etc.)
Server-->>AnalyticsUI: analytics response (rows, retentionDays, oldestRecordDate)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labelssourcebot-team Suggested reviewers
❌ Failed checks (1 warning)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
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. ❤️ ShareComment @coderabbitai help to get the list of available commands and usage tips. |
Sorry, something went wrong.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)packages/web/src/features/search/searchApi.ts (1)🤖 Prompt for all review comments with AI agentspackages/web/src/ee/features/analytics/types.ts (1)31-40: Consider extracting duplicated audit logic.
The audit blocks in search() and streamSearch() are identical. This duplication exists across multiple files in this PR. Consider extracting a helper function to reduce repetition and centralize the audit pattern.
♻️ Suggested helper extraction (local to this file or shared)// Could be placed in a shared audit utilities file const auditCodeSearch = async (user: UserWithAccounts, org: { id: number }) => { const source = (await headers()).get('X-Sourcebot-Client-Source') ?? undefined; getAuditService().createAudit({ action: 'user.performed_code_search', actor: { id: user.id, type: 'user' }, target: { id: org.id.toString(), type: 'org' }, orgId: org.id, metadata: { source }, }).catch(() => {}); };Then in both functions:
withOptionalAuthV2(async ({ prisma, user, org }) => { if (user) { - const source = (await headers()).get('X-Sourcebot-Client-Source') ?? undefined; - getAuditService().createAudit({ - action: 'user.performed_code_search', - actor: { id: user.id, type: 'user' }, - target: { id: org.id.toString(), type: 'org' }, - orgId: org.id, - metadata: { source }, - }).catch(() => {}); + await auditCodeSearch(user, org); }Also applies to: 62-71
🤖 Prompt for AI AgentsVerify each finding against the current code and only fix it if needed. In `@packages/web/src/features/search/searchApi.ts` around lines 31 - 40, Extract the duplicated audit logic into a helper (e.g., auditCodeSearch) and replace the repeated blocks in search() and streamSearch() with a single call to that helper; the helper should capture the source via (await headers()).get('X-Sourcebot-Client-Source') ?? undefined and call getAuditService().createAudit({ action: 'user.performed_code_search', actor: { id: user.id, type: 'user' }, target: { id: org.id.toString(), type: 'org' }, orgId: org.id, metadata: { source } }).catch(() => {}), then invoke auditCodeSearch(user, org) from both search() and streamSearch() to remove duplication.packages/web/src/ee/features/analytics/analyticsContent.tsx (1)9-11: Tighten counter field validation to integer, non-negative values.
These are count metrics; enforcing .int().nonnegative() avoids silently accepting invalid payloads.
Suggested schema hardening🤖 Prompt for AI Agents- mcp_requests: z.number(), - api_requests: z.number(), - active_users: z.number(), + mcp_requests: z.number().int().nonnegative(), + api_requests: z.number().int().nonnegative(), + active_users: z.number().int().nonnegative(),Verify each finding against the current code and only fix it if needed. In `@packages/web/src/ee/features/analytics/types.ts` around lines 9 - 11, The count fields mcp_requests, api_requests, and active_users in the analytics schema are plain z.number() and should be restricted to integer, non-negative values; update their validators to use .int().nonnegative() on each of those fields (locate the schema definition in types.ts where mcp_requests, api_requests, and active_users are declared) so the schema enforces integer non-negative counters.packages/web/src/ee/features/analytics/actions.ts (1)178-178: Avoid hardcoded skeleton count drift.
Line 178 hardcodes 6; consider deriving from a shared chart-count constant to keep loading UI in sync when charts are added/removed.
Minimal refactor🤖 Prompt for AI Agents+const ANALYTICS_CHART_COUNT = 6 + function LoadingSkeleton() { return ( @@ - {[1, 2, 3, 4, 5, 6].map((chartIndex) => ( + {Array.from({ length: ANALYTICS_CHART_COUNT }, (_, i) => i + 1).map((chartIndex) => (Verify each finding against the current code and only fix it if needed. In `@packages/web/src/ee/features/analytics/analyticsContent.tsx` at line 178, Replace the hardcoded array [1,2,3,4,5,6] used to render skeletons with a single source-of-truth chart count constant (e.g., CHART_COUNT) exported from the analytics/chart configuration or the component that defines the list of charts; update the mapping to iterate based on that CHART_COUNT (e.g., Array.from({ length: CHART_COUNT })) so the skeleton count automatically stays in sync whenever charts are added/removed (ensure you add or import CHART_COUNT and replace occurrences in analyticsContent.tsx where the hardcoded six is used).87-87: Use an explicit API-source allowlist for api_requests.
Line 87 currently treats any non-null, non-mcp source as API. That can overcount if new source labels are introduced later (e.g., non-API internal clients). Prefer explicit allowed API source values.
🤖 Prompt for AI AgentsVerify each finding against the current code and only fix it if needed. In `@packages/web/src/ee/features/analytics/actions.ts` at line 87, The COUNT(*) FILTER that defines api_requests currently treats any non-null/non-'mcp' metadata->>'source' as API; change this to an explicit allowlist check against known API source values (e.g. metadata->>'source' IN ( ... )) so only intended sources count as api_requests, update the SQL expression that produces api_requests accordingly, and if the allowed sources are used elsewhere consider extracting them to a shared constant or config and adjust any tests that rely on the previous behavior.
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@CHANGELOG.md`:
- Line 11: The changelog entry mixes tenses—change the phrase "Move audit events
from client-side to service functions to capture all API calls (web UI, MCP, and
non-MCP)" to past tense (e.g., "Moved audit events from client-side to service
functions to capture all API calls (web UI, MCP, and non-MCP)") so the entire
bullet reads consistently in past tense with the rest of the entry.
---
Nitpick comments:
In `@packages/web/src/ee/features/analytics/actions.ts`:
- Line 87: The COUNT(*) FILTER that defines api_requests currently treats any
non-null/non-'mcp' metadata->>'source' as API; change this to an explicit
allowlist check against known API source values (e.g. metadata->>'source' IN (
... )) so only intended sources count as api_requests, update the SQL expression
that produces api_requests accordingly, and if the allowed sources are used
elsewhere consider extracting them to a shared constant or config and adjust any
tests that rely on the previous behavior.
In `@packages/web/src/ee/features/analytics/analyticsContent.tsx`:
- Line 178: Replace the hardcoded array [1,2,3,4,5,6] used to render skeletons
with a single source-of-truth chart count constant (e.g., CHART_COUNT) exported
from the analytics/chart configuration or the component that defines the list of
charts; update the mapping to iterate based on that CHART_COUNT (e.g.,
Array.from({ length: CHART_COUNT })) so the skeleton count automatically stays
in sync whenever charts are added/removed (ensure you add or import CHART_COUNT
and replace occurrences in analyticsContent.tsx where the hardcoded six is
used).
In `@packages/web/src/ee/features/analytics/types.ts`:
- Around line 9-11: The count fields mcp_requests, api_requests, and
active_users in the analytics schema are plain z.number() and should be
restricted to integer, non-negative values; update their validators to use
.int().nonnegative() on each of those fields (locate the schema definition in
types.ts where mcp_requests, api_requests, and active_users are declared) so the
schema enforces integer non-negative counters.
In `@packages/web/src/features/search/searchApi.ts`:
- Around line 31-40: Extract the duplicated audit logic into a helper (e.g.,
auditCodeSearch) and replace the repeated blocks in search() and streamSearch()
with a single call to that helper; the helper should capture the source via
(await headers()).get('X-Sourcebot-Client-Source') ?? undefined and call
getAuditService().createAudit({ action: 'user.performed_code_search', actor: {
id: user.id, type: 'user' }, target: { id: org.id.toString(), type: 'org' },
orgId: org.id, metadata: { source } }).catch(() => {}), then invoke
auditCodeSearch(user, org) from both search() and streamSearch() to remove
duplication.
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📥 CommitsReviewing files that changed from the base of the PR and between 8e0e737 and 6726cf2.
📒 Files selected for processing (10)
Sorry, something went wrong.
| ## [Unreleased] | ||
|
|
||
| ### Added | ||
| - Added MCP and API key usage tracking to analytics dashboard. Move audit events from client-side to service functions to capture all API calls (web UI, MCP, and non-MCP). Display MCP requests and API requests on separate charts. [#948](https://github.com/sourcebot-dev/sourcebot/pull/948) |
There was a problem hiding this comment.
⚠️ Potential issue | 🟡 Minor
Use consistent past tense in the changelog sentence.
Line 11 says “Move audit events…” while the rest of the entry is in past tense. This reads awkwardly in release notes.
✏️ Proposed wording tweak-- Added MCP and API key usage tracking to analytics dashboard. Move audit events from client-side to service functions to capture all API calls (web UI, MCP, and non-MCP). Display MCP requests and API requests on separate charts. [`#948`](https://github.com/sourcebot-dev/sourcebot/pull/948)
+- Added MCP and API key usage tracking to the analytics dashboard. Moved audit events from client-side to service functions to capture all API calls (web UI, MCP, and non-MCP). Displayed MCP request and API request counts on separate charts. [`#948`](https://github.com/sourcebot-dev/sourcebot/pull/948)‼️ 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.
| - Added MCP and API key usage tracking to analytics dashboard. Move audit events from client-side to service functions to capture all API calls (web UI, MCP, and non-MCP). Display MCP requests and API requests on separate charts. [#948](https://github.com/sourcebot-dev/sourcebot/pull/948) | |
| - Added MCP and API key usage tracking to the analytics dashboard. Moved audit events from client-side to service functions to capture all API calls (web UI, MCP, and non-MCP). Displayed MCP request and API request counts on separate charts. [`#948`](https://github.com/sourcebot-dev/sourcebot/pull/948) |
Verify each finding against the current code and only fix it if needed. In `@CHANGELOG.md` at line 11, The changelog entry mixes tenses—change the phrase "Move audit events from client-side to service functions to capture all API calls (web UI, MCP, and non-MCP)" to past tense (e.g., "Moved audit events from client-side to service functions to capture all API calls (web UI, MCP, and non-MCP)") so the entire bullet reads consistently in past tense with the rest of the entry.
Sorry, something went wrong.
- Add SOURCEBOT_EE_AUDIT_RETENTION_DAYS env var (default 180) and AuditLogPruner background job that prunes old audit records daily in batches - Surface retention period and oldest record date in analytics page header - Update audit action types table in docs (remove 4 stale, add 11 missing) - Add audit log storage section to sizing guide with enterprise callout and storage estimates - Update mock data script with mixed-usage user profiles and new audit actions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(web): add MCP and API key usage tracking to analytics Move audit event creation from client-side to service functions for search, repos, file source, and file tree endpoints. Add source metadata to distinguish MCP requests from other API calls. Extend analytics SQL to include new actions and display MCP request and API request counts on the analytics dashboard. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * chore: update CHANGELOG for MCP analytics tracking (#948) * feat: add audit log retention policy, update analytics UI and docs - Add SOURCEBOT_EE_AUDIT_RETENTION_DAYS env var (default 180) and AuditLogPruner background job that prunes old audit records daily in batches - Surface retention period and oldest record date in analytics page header - Update audit action types table in docs (remove 4 stale, add 11 missing) - Add audit log storage section to sizing guide with enterprise callout and storage estimates - Update mock data script with mixed-usage user profiles and new audit actions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: update CHANGELOG for audit log retention policy (#950) * feat(web): add sourceOverride to getFileSource and getTree Extend the sourceOverride pattern to getFileSource and getTree so internal callers (chat AI agent) can tag audit events with the correct source instead of relying on the HTTP header. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(web): restructure analytics by source and add global active users - Tag all audit events with source metadata (sourcebot-web-client, sourcebot-ask-agent, sourcebot-ui-codenav, mcp) via sourceOverride - Restructure analytics SQL to segment by Web App (sourcebot-*), MCP, and API (everything else) - Add global active users chart at top of analytics page - Add info hover tooltips explaining each chart - Prefix chart names with their section (Web/MCP/API) for clarity - Update inject-audit-data script to use correct source values Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(db): backfill audit source metadata and add v2 inject script Add a migration that backfills the 'source' field in audit metadata for historical events created before source tracking was introduced. All old events were web-only, so code searches and chats get 'sourcebot-web-client' and navigations get 'sourcebot-ui-codenav'. Also restore the original inject-audit-data script and add inject-audit-data-v2 with source-aware mock data generation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(web): add source-segmented analytics with MCP/API tracking Restructure analytics dashboard to segment metrics by source (web, MCP, API). Add audit events for file source, file tree, and repo listing actions. Pass source metadata through all audit event paths including MCP server, chat blocking API, and code navigation. Backfill historical audit events with sourcebot-web-client source. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * shift migrations * new docs and news data * update readme to point to new demo site * fix(web): Log audit failures instead of silently swallowing errors Replace empty .catch(() => {}) on getAuditService().createAudit() in askCodebase with a handler that logs the error and audit context (action, actorId, orgId, source) for debugging and alerting. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(web): Use UTC timezone for "Data since" date display Adds timeZone: "UTC" to toLocaleDateString() call so the oldest record date doesn't shift by a day depending on the client's local timezone. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: use type-only imports and update import source in inject-audit-data-v2 Convert Script, PrismaClient, and Prisma imports to type-only imports since they are only used in type positions. Update PrismaClient/Prisma import source from "../../dist" to "@sourcebot/db" to match the pattern in scriptRunner.ts. Also fix broken API reference link in sizing guide docs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(web): Remove redundant .catch() on createAudit calls createAudit already catches errors internally and logs them with context, so the .catch(() => {}) at each call site was redundant. Removed from all 6 call sites: askCodebase, getFileSourceApi, getTreeApi, searchApi (x2), and listReposApi. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(web): Rename sourceOverride param to source The "override" suffix is redundant — callers are simply providing the source value. Renamed across all 9 files (function signatures, types, and call sites). No behavioral changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * changelog typo * fix news data * fix(web): Resolve variable shadowing in getFileSourceApi Rename local `source` variable (git file content) to `fileContent` to avoid shadowing the `source` parameter, which caused a TypeScript "Block-scoped variable used before declaration" error. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
| Back | FazBrowse Home | New Git URL |
Summary
Analytics: MCP & API usage tracking
Audit log retention policy
Analytics UI: retention info
Documentation updates
Mock data script
Screenshots
Retention policy and oldest audit log date displayed in analytics header:
Test plan
Linear: SOU-579
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Documentation