Skip to content

feat: Project Configuration Change Log - #373

Merged
yash-pouranik merged 5 commits into
geturbackend:mainfrom
VivekTekwani021:feat/project-changelog
Jul 31, 2026
Merged

feat: Project Configuration Change Log#373
yash-pouranik merged 5 commits into
geturbackend:mainfrom
VivekTekwani021:feat/project-changelog

Conversation

@VivekTekwani021

@VivekTekwani021 VivekTekwani021 commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Adds an audit trail for all project-level config changes — tracks what was changed, by whom, and when.

Why

In team projects with multiple admins, there was no visibility into who changed settings like auth, CORS domains, RLS rules, or external DB config.

What's added

  • ProjectConfigLog model — stores each config change event
  • GET /api/projects/:projectId/config-logs — paginated API endpoint (filterable by category)
  • Instrumented 7 controller functions: updateProject, toggleAuth, togglePublicSignup, updateAuthProviders, updateAllowedDomains, updateExternalConfig, updateCollectionRls

Notes

  • Sensitive values (keys, URIs, secrets) are masked as •••••••• — nothing sensitive stored in logs
  • Logging errors are swallowed — a log write failure never affects the primary API response
  • Logs are read-only

Summary by CodeRabbit

  • New Features
    • Added a project configuration history audit trail.
    • Configuration changes now record the acting member, category, timestamp, and relevant details, with sensitive values masked.
    • Added a protected, paginated API for viewing configuration history with category filtering.
    • Logging failures do not interrupt configuration updates.

@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

@VivekTekwani021 is attempting to deploy a commit to the Yash Pouranik's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@VivekTekwani021, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 29 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fd768eba-9e5d-4068-8928-5064e9889b9d

📥 Commits

Reviewing files that changed from the base of the PR and between 4df5df3 and 16c6e28.

📒 Files selected for processing (3)
  • apps/dashboard-api/src/__tests__/configLog.controller.test.js
  • apps/dashboard-api/src/controllers/configLog.controller.js
  • apps/dashboard-api/src/controllers/project.controller.js
📝 Walkthrough

Walkthrough

Adds the ProjectConfigLog model and non-blocking writer, instruments supported project configuration mutations with masked audit data, and exposes a protected paginated API with category filtering.

Changes

Configuration audit trail

Layer / File(s) Summary
Audit log contract and writer
ISSUE.md, packages/common/src/models/ProjectConfigLog.js, packages/common/src/index.js, apps/dashboard-api/src/utils/logConfigChange.js
Defines the audit log schema and exports it through the common package. Adds a writer that stores user identity and optional diff data while swallowing database errors.
Project mutation instrumentation
apps/dashboard-api/src/controllers/project.controller.js
Records supported project configuration changes, including BYOD, project information, Resend, domains, authentication, signup, OAuth providers, and collection RLS settings. Masks sensitive values.
Configuration log retrieval API
apps/dashboard-api/src/routes/projects.js, apps/dashboard-api/src/controllers/configLog.controller.js
Adds the protected GET /:projectId/config-logs route. Returns newest-first logs with pagination and optional category filtering.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  actor Member
  participant projectsRoute as projects route
  participant getConfigLogs
  participant ProjectConfigLog
  Member->>projectsRoute: GET /:projectId/config-logs
  projectsRoute->>getConfigLogs: dispatch authenticated request
  getConfigLogs->>ProjectConfigLog: query logs and count
  ProjectConfigLog-->>getConfigLogs: paginated records and total
  getConfigLogs-->>Member: pagination response
Loading

Possibly related issues

  • geturbackend/urBackend#372 — Directly covers the Project Configuration Change Log feature implemented here.

Possibly related PRs

Suggested labels: type:feature

Suggested reviewers: nitin-kumar-yadav1307, yash-pouranik

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: adding a project configuration change log.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@VivekTekwani021

Copy link
Copy Markdown
Contributor Author

issue #372

@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
ur-backend-web-dashboard Ready Ready Preview Jul 31, 2026 6:07am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
urbackend Skipped Skipped Jul 31, 2026 6:07am

Comment thread apps/dashboard-api/src/controllers/configLog.controller.js Fixed
Comment thread apps/dashboard-api/src/controllers/configLog.controller.js Fixed

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/dashboard-api/src/controllers/configLog.controller.js`:
- Around line 43-54: Update the response object in
apps/dashboard-api/src/controllers/configLog.controller.js:43-54 to include a
top-level message describing the successful configuration-log retrieval, while
preserving the existing success and data fields. Update the documented response
example in ISSUE.md:83-107 with the same message field and value.

In `@apps/dashboard-api/src/controllers/project.controller.js`:
- Around line 2856-2867: Update the diff construction in the OAuth config audit
logging block to record the persisted enabled state from the saved project
provider configuration, rather than coercing parsed[provider].enabled. Preserve
request-provided enabled values when present, while falling back to
project.authProviders[provider].enabled for partial clientId or clientSecret
updates.
- Around line 791-805: Update the Config Audit Log block around byodChanges and
logConfigChange so database and storage updates produce separate records: emit a
byod_db entry with only the database diff when updateData["resources.db.config"]
changes, and a byod_storage entry with only the storage diff when
updateData["resources.storage.config"] changes. Remove the combined
category/label selection so both records are written when both configurations
change.

In `@ISSUE.md`:
- Around line 68-70: Update the code fence for the GET
/api/projects/:projectId/config-logs endpoint in ISSUE.md to specify the http
language on its opening fence.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 72b3df15-440f-43f7-9dfe-d428dd1f86c0

📥 Commits

Reviewing files that changed from the base of the PR and between 94c9d71 and 4df5df3.

📒 Files selected for processing (7)
  • ISSUE.md
  • apps/dashboard-api/src/controllers/configLog.controller.js
  • apps/dashboard-api/src/controllers/project.controller.js
  • apps/dashboard-api/src/routes/projects.js
  • apps/dashboard-api/src/utils/logConfigChange.js
  • packages/common/src/index.js
  • packages/common/src/models/ProjectConfigLog.js

Comment thread apps/dashboard-api/src/controllers/configLog.controller.js
Comment thread apps/dashboard-api/src/controllers/project.controller.js
Comment thread apps/dashboard-api/src/controllers/project.controller.js
Comment thread ISSUE.md Outdated
@yash-pouranik

Copy link
Copy Markdown
Member

is this good to merge??
@coderabbitai
??

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== PR status and existing review comments ==='
gh pr view 373 --repo geturbackend/urBackend --json state,isDraft,mergeable,reviewDecision,statusCheckRollup,reviews,comments \
  --jq '{state, isDraft, mergeable, reviewDecision, checks: [.statusCheckRollup[]? | {name, status, conclusion}], reviews: [.reviews[]? | {author: .author.login, state}], comments: [.comments[]? | {author: .author.login, body}]}'

echo '=== Changed files ==='
git diff --name-status HEAD^ HEAD

echo '=== Changed implementation diff ==='
git diff --unified=80 HEAD^ HEAD -- \
  apps/dashboard-api/src/controllers/configLog.controller.js \
  apps/dashboard-api/src/controllers/project.controller.js \
  apps/dashboard-api/src/routes/projects.js \
  apps/dashboard-api/src/utils/logConfigChange.js \
  packages/common/src/models/ProjectConfigLog.js \
  packages/common/src/index.js

echo '=== Changed-file outlines ==='
for f in \
  apps/dashboard-api/src/controllers/configLog.controller.js \
  apps/dashboard-api/src/controllers/project.controller.js \
  apps/dashboard-api/src/routes/projects.js \
  apps/dashboard-api/src/utils/logConfigChange.js \
  packages/common/src/models/ProjectConfigLog.js \
  packages/common/src/index.js
do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    ast-grep outline "$f" --items all --view compact || true
  fi
done

Length of output: 21273


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Complete PR file list ==='
gh api --paginate 'repos/geturbackend/urBackend/pulls/373/files?per_page=100' \
  --jq '.[] | {filename, status, additions, deletions, patch}'

echo '=== Current source outlines ==='
for f in \
  apps/dashboard-api/src/controllers/configLog.controller.js \
  apps/dashboard-api/src/controllers/project.controller.js \
  apps/dashboard-api/src/routes/projects.js \
  apps/dashboard-api/src/utils/logConfigChange.js \
  packages/common/src/models/ProjectConfigLog.js \
  packages/common/src/index.js
do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    ast-grep outline "$f" --items all --view expanded || true
  fi
done

echo '=== Route authorization and endpoint placement ==='
if [ -f apps/dashboard-api/src/routes/projects.js ]; then
  rg -n -C 6 'config-logs|authorizeProject|router\.(get|post|patch|put|delete)' \
    apps/dashboard-api/src/routes/projects.js
fi

echo '=== Audit-log usages and tests ==='
rg -n -C 4 '\blogConfigChange\s*\(|\bgetConfigLogs\s*\(|ProjectConfigLog' \
  --glob '!node_modules/**' --glob '!dist/**' --glob '!build/**' .

Length of output: 54473


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Audit call sites with persistence context ==='
for range in \
  '730,825' \
  '1875,1995' \
  '2350,2455' \
  '2635,2755' \
  '2735,2800' \
  '2790,2885' \
  '2885,2975'
do
  echo "--- apps/dashboard-api/src/controllers/project.controller.js:$range ---"
  sed -n "$range p" apps/dashboard-api/src/controllers/project.controller.js
done

echo '=== authorizeProject middleware ==='
ast-grep outline apps/dashboard-api/src/middlewares/authorizeProject.js --items all --view expanded || true
cat -n apps/dashboard-api/src/middlewares/authorizeProject.js

echo '=== Candidate dashboard-api tests ==='
fd -t f . apps/dashboard-api | rg -i '(^|/)(test|tests|__tests__)/|(\.test|\.spec)\.(js|ts)$' | head -200

echo '=== Test and test-script references for project controller/routes ==='
rg -n -i -C 3 '(project\.controller|routes/projects|updateProject|toggleAuth|allowed-domains|supertest)' \
  apps/dashboard-api \
  -g '*test*' -g '*spec*' -g 'package.json' || true

Length of output: 40174


@yash-pouranik Yes. I found no blocking issue in #373.

The PR is mergeable. Required CI checks pass. The new endpoint verifies project membership. The audit calls occur after successful mutations. The logging helper does not affect primary API responses if it fails. Sensitive configuration values are masked.

The PR has no focused tests for GET /api/projects/:projectId/config-logs or logConfigChange. Add those tests in a follow-up if practical. This is not a merge blocker.

[approve]

You are interacting with an AI system.

@vercel
vercel Bot temporarily deployed to Preview – urbackend July 31, 2026 06:06 Inactive
@yash-pouranik

Copy link
Copy Markdown
Member

now check
@coderabbitai

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="geturbackend/urBackend"
pr="373"

echo "=== Pull request state, commits, checks, and reviews ==="
gh pr view "$pr" --repo "$repo" \
  --json state,isDraft,mergeable,reviewDecision,headRefOid,commits,statusCheckRollup,reviews \
  --jq '{
    state,
    isDraft,
    mergeable,
    reviewDecision,
    headRefOid,
    commits: [.commits[] | {oid: .oid, messageHeadline: .messageHeadline}],
    checks: [.statusCheckRollup[]? | {name, status, conclusion}],
    reviews: [.reviews[]? | {author: .author.login, state, submittedAt}]
  }'

echo "=== Changed files and patch at current PR head ==="
gh api --paginate "repos/$repo/pulls/$pr/files?per_page=100" \
  --jq '.[] | {filename, status, additions, deletions, patch}'

echo "=== Current audit-log implementation outlines ==="
for f in \
  apps/dashboard-api/src/controllers/configLog.controller.js \
  apps/dashboard-api/src/controllers/project.controller.js \
  apps/dashboard-api/src/routes/projects.js \
  apps/dashboard-api/src/utils/logConfigChange.js \
  packages/common/src/models/ProjectConfigLog.js \
  packages/common/src/index.js
do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    ast-grep outline "$f" --items all --view expanded || true
  fi
done

echo "=== Routes, authorization, controller query, and log helper ==="
for f in \
  apps/dashboard-api/src/routes/projects.js \
  apps/dashboard-api/src/controllers/configLog.controller.js \
  apps/dashboard-api/src/utils/logConfigChange.js \
  packages/common/src/models/ProjectConfigLog.js
do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    cat -n "$f"
  fi
done

echo "=== Configuration-log call sites with surrounding context ==="
rg -n -C 8 '\blogConfigChange\s*\(' \
  apps/dashboard-api/src/controllers/project.controller.js || true

echo "=== Focused tests and test-script references ==="
fd -t f . apps/dashboard-api packages/common | rg -i '(^|/)(test|tests|__tests__)/|(\.test|\.spec)\.(js|ts)$' || true
rg -n -i -C 2 '(config-logs|configlog|logconfigchange|ProjectConfigLog)' \
  apps/dashboard-api packages/common \
  -g 'package.json' -g '*test*' -g '*spec*' || true

Length of output: 68070


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Shared error constructor and project authorization ==="
for f in \
  packages/common/src/utils/AppError.js \
  apps/dashboard-api/src/middlewares/authorizeProject.js
do
  echo "--- $f ---"
  if [ -f "$f" ]; then
    ast-grep outline "$f" --items all --view expanded || true
    cat -n "$f"
  fi
done

echo "=== Updated project-handler bodies ==="
for range in \
  '690,820' \
  '1860,1995' \
  '2340,2455' \
  '2630,2760' \
  '2760,2885' \
  '2885,2985'
do
  echo "--- apps/dashboard-api/src/controllers/project.controller.js:$range ---"
  sed -n "${range}p" apps/dashboard-api/src/controllers/project.controller.js
done

echo "=== Existing model conventions ==="
for f in \
  packages/common/src/models/MailLog.js \
  packages/common/src/models/DeveloperActivity.js \
  packages/common/src/models/PlatformEvent.js
do
  echo "--- $f ---"
  if [ -f "$f" ]; then
    sed -n '1,180p' "$f"
  fi
done

echo "=== Current checks at the current head ==="
gh pr view 373 --repo geturbackend/urBackend \
  --json headRefOid,mergeable,reviewDecision,statusCheckRollup \
  --jq '{headRefOid, mergeable, reviewDecision, checks: [.statusCheckRollup[]? | {name,status,conclusion}]}'

Length of output: 36021


🏁 Script executed:

#!/bin/bash
set -euo pipefail

gh pr view 373 --repo geturbackend/urBackend \
  --json state,isDraft,mergeable,headRefOid,statusCheckRollup \
  --jq '{
    state,
    isDraft,
    mergeable,
    headRefOid,
    checks: [.statusCheckRollup[]? | {name,status,conclusion,detailsUrl}]
  }'

Length of output: 1863


@​yash-pouranik I found no blocking issue in the current head.

The added controller tests address the previous test gap. The endpoint validates membership and rejects unsafe category filters. The audit logging occurs after successful mutations. Sensitive BYOD and Resend values remain masked.

The PR is mergeable, but these required checks are still running:

  • frontend-lint
  • Analyze (javascript-typescript)
  • dashboard-api-tests
  • public-api-tests
  • sdk-tests

Do not merge until these checks pass.

You are interacting with an AI system.

@yash-pouranik
yash-pouranik merged commit 1bf1705 into geturbackend:main Jul 31, 2026
11 checks passed
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.

3 participants