Skip to content

last modified added#1321

Merged
siddhant3030 merged 5 commits intomainfrom
feature/last_modified_in_report
May 4, 2026
Merged

last modified added#1321
siddhant3030 merged 5 commits intomainfrom
feature/last_modified_in_report

Conversation

@siddhant3030
Copy link
Copy Markdown
Contributor

@siddhant3030 siddhant3030 commented Apr 29, 2026

Summary by CodeRabbit

  • New Features
    • Snapshots now record and display who last modified the summary (shows editor's email in snapshot metadata); snapshot view always includes a last-modified field (null if never edited).
  • Database
    • Migration added to persist the last-modified user on snapshots.
  • Tests
    • Extended test coverage for last-modified behavior, summary update flows, and view data.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 29, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b2e23af4-b563-43df-9bbd-2dddfbf2364c

📥 Commits

Reviewing files that changed from the base of the PR and between ab21163 and 7e839c3.

📒 Files selected for processing (7)
  • ddpui/api/report_api.py
  • ddpui/core/reports/report_service.py
  • ddpui/migrations/0157_add_last_modified_by_to_report_snapshot.py
  • ddpui/migrations/0158_merge_20260415_1814.py
  • ddpui/migrations/0159_merge_20260504_0910.py
  • ddpui/models/report.py
  • ddpui/tests/core/reports/test_report_service.py
✅ Files skipped from review due to trivial changes (1)
  • ddpui/models/report.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • ddpui/api/report_api.py
  • ddpui/tests/core/reports/test_report_service.py
  • ddpui/core/reports/report_service.py

Walkthrough

Adds a nullable ReportSnapshot.last_modified_by FK and migration, updates ReportService.update_snapshot to accept an OrgUser and record last_modified_by when summary changes, threads the authenticated orguser from the API into the service call, and exposes the editor’s email in snapshot view metadata and tests.

Changes

Report snapshot last-modifier and update flow

Layer / File(s) Summary
Data Shape / Migrations
ddpui/models/report.py, ddpui/migrations/0157_add_last_modified_by_to_report_snapshot.py, ddpui/migrations/0158_merge_20260415_1814.py, ddpui/migrations/0159_merge_20260504_0910.py
Adds ReportSnapshot.last_modified_by: ForeignKey(OrgUser, on_delete=SET_NULL, null=True, blank=True, related_name="modified_snapshots") and adds two merge migrations plus the schema migration.
Core Implementation
ddpui/core/reports/report_service.py
get_snapshot now select_related includes last_modified_by__user; get_snapshot_view_data adds report_metadata.last_modified_by from snapshot.last_modified_by.user.email (or None); update_snapshot signature changed to (snapshot_id, data, orguser), scopes lookup via orguser.org, and when data.summary is set it assigns snapshot.last_modified_by = orguser and saves summary, last_modified_by, and updated_at.
API Wiring
ddpui/api/report_api.py
update_snapshot endpoint now calls ReportService.update_snapshot(snapshot_id, payload, orguser) (argument order changed; passes authenticated orguser).
Tests
ddpui/tests/core/reports/test_report_service.py
Tests updated to call update_snapshot(..., data, orguser) and assert last_modified_by is set only when summary changes, reflects the editing OrgUser (email), remains None if summary is None, and that created_by remains the original creator after subsequent edits.

Sequence Diagram

sequenceDiagram
    participant Client
    participant API as API Endpoint
    participant Service as ReportService
    participant DB as Database

    Client->>API: PATCH /snapshot/{id} (payload with summary)
    API->>API: Authenticate -> obtain orguser
    API->>Service: update_snapshot(snapshot_id, payload, orguser)
    Service->>DB: SELECT snapshot (select_related created_by, last_modified_by)
    DB-->>Service: ReportSnapshot
    alt summary changed
        Service->>Service: snapshot.summary = payload.summary
        Service->>Service: snapshot.last_modified_by = orguser
        Service->>Service: snapshot.updated_at = now
        Service->>DB: SAVE snapshot (summary, last_modified_by, updated_at)
        DB-->>Service: Persisted
    end
    Service->>Service: Build view data (include last_modified_by.user.email or null)
    Service-->>API: Updated snapshot + metadata
    API-->>Client: 200 OK with snapshot and metadata
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • Ishankoradia
  • himanshudube97
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'last modified added' is vague and lacks specificity about what feature was added or where it applies. Revise the title to be more descriptive, such as 'Track last modified user in report snapshots' or 'Add last_modified_by field to report snapshots'.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/last_modified_in_report

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

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

@sentry
Copy link
Copy Markdown

sentry Bot commented Apr 29, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 58.43%. Comparing base (9594f2a) to head (202c4fd).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1321   +/-   ##
=======================================
  Coverage   58.42%   58.43%           
=======================================
  Files         132      132           
  Lines       15653    15654    +1     
=======================================
+ Hits         9146     9147    +1     
  Misses       6507     6507           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread ddpui/api/report_api.py Outdated
Comment thread ddpui/core/reports/report_service.py Outdated
Comment thread ddpui/models/report.py
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ddpui/core/reports/report_service.py`:
- Around line 549-553: The code unconditionally sets snapshot.last_modified_by
whenever data.summary is present, which can overwrite attribution even if the
summary is unchanged; change the logic in report_service.py so you first compare
the incoming data.summary with snapshot.summary (handling None safely) and only
assign snapshot.summary, snapshot.last_modified_by and call
snapshot.save(update_fields=["summary","last_modified_by","updated_at"]) when
the values differ; keep the existing behavior of returning snapshot otherwise.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b7df436c-6d8f-4996-8e27-083e0e9727f6

📥 Commits

Reviewing files that changed from the base of the PR and between 05357c2 and 8e26715.

📒 Files selected for processing (6)
  • ddpui/api/report_api.py
  • ddpui/core/reports/report_service.py
  • ddpui/migrations/0157_add_last_modified_by_to_report_snapshot.py
  • ddpui/migrations/0158_merge_20260415_1814.py
  • ddpui/models/report.py
  • ddpui/tests/core/reports/test_report_service.py

Comment on lines 549 to 553
if data.summary is not None:
snapshot.summary = data.summary
snapshot.save(update_fields=["summary"])
snapshot.last_modified_by = orguser
snapshot.save(update_fields=["summary", "last_modified_by", "updated_at"])
return snapshot
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Only set last_modified_by when summary actually changes.

Current logic updates attribution whenever summary is present, even if unchanged, which can corrupt audit intent.

Suggested fix
-        if data.summary is not None:
+        if data.summary is not None and data.summary != snapshot.summary:
             snapshot.summary = data.summary
             snapshot.last_modified_by = orguser
             snapshot.save(update_fields=["summary", "last_modified_by", "updated_at"])
📝 Committable suggestion

‼️ 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.

Suggested change
if data.summary is not None:
snapshot.summary = data.summary
snapshot.save(update_fields=["summary"])
snapshot.last_modified_by = orguser
snapshot.save(update_fields=["summary", "last_modified_by", "updated_at"])
return snapshot
if data.summary is not None and data.summary != snapshot.summary:
snapshot.summary = data.summary
snapshot.last_modified_by = orguser
snapshot.save(update_fields=["summary", "last_modified_by", "updated_at"])
return snapshot
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ddpui/core/reports/report_service.py` around lines 549 - 553, The code
unconditionally sets snapshot.last_modified_by whenever data.summary is present,
which can overwrite attribution even if the summary is unchanged; change the
logic in report_service.py so you first compare the incoming data.summary with
snapshot.summary (handling None safely) and only assign snapshot.summary,
snapshot.last_modified_by and call
snapshot.save(update_fields=["summary","last_modified_by","updated_at"]) when
the values differ; keep the existing behavior of returning snapshot otherwise.

@siddhant3030 siddhant3030 force-pushed the feature/last_modified_in_report branch from 8e26715 to de105ad Compare April 30, 2026 05:56
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
ddpui/core/reports/report_service.py (1)

546-550: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Prevent audit attribution changes on no-op summary updates.

Line 546 still updates last_modified_by whenever summary is present, even when the incoming text equals the existing summary. That makes idempotent requests look like real edits.

Proposed fix
-        if data.summary is not None:
+        if data.summary is not None and data.summary != snapshot.summary:
             snapshot.summary = data.summary
             snapshot.last_modified_by = orguser
             snapshot.save(update_fields=["summary", "last_modified_by", "updated_at"])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ddpui/core/reports/report_service.py` around lines 546 - 550, The code
unconditionally sets snapshot.last_modified_by and saves audit fields whenever
data.summary is present, even if data.summary equals snapshot.summary; change
the logic in report_service.py so you first compare snapshot.summary and
data.summary and only assign snapshot.summary = data.summary, set
snapshot.last_modified_by = orguser, and include "last_modified_by" in the
save(update_fields=[...]) list when the summary actually changed; if the
incoming summary is identical, do not modify last_modified_by or include it in
update_fields (only touch "updated_at"/others as appropriate) and still return
snapshot.
🧹 Nitpick comments (1)
ddpui/tests/core/reports/test_report_service.py (1)

513-560: ⚡ Quick win

Add coverage for unchanged-summary updates.

Current cases cover summary=None and changed summaries, but not summary set to the same existing value. Add a test asserting last_modified_by is not rewritten on no-op text updates.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ddpui/tests/core/reports/test_report_service.py` around lines 513 - 560, Add
a test that verifies ReportService.update_snapshot does not update
last_modified_by when the summary provided equals the existing summary: set
sample_snapshot.summary to a specific string and save, ensure
sample_snapshot.last_modified_by is None (or capture current value), call
ReportService.update_snapshot(sample_snapshot.id, SnapshotUpdate(summary="same
value"), orguser) with the exact same text, and assert that last_modified_by
remains unchanged (still None or equal to the captured value); reference
ReportService.update_snapshot, SnapshotUpdate, sample_snapshot and orguser to
locate where to add this new test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@ddpui/core/reports/report_service.py`:
- Around line 546-550: The code unconditionally sets snapshot.last_modified_by
and saves audit fields whenever data.summary is present, even if data.summary
equals snapshot.summary; change the logic in report_service.py so you first
compare snapshot.summary and data.summary and only assign snapshot.summary =
data.summary, set snapshot.last_modified_by = orguser, and include
"last_modified_by" in the save(update_fields=[...]) list when the summary
actually changed; if the incoming summary is identical, do not modify
last_modified_by or include it in update_fields (only touch "updated_at"/others
as appropriate) and still return snapshot.

---

Nitpick comments:
In `@ddpui/tests/core/reports/test_report_service.py`:
- Around line 513-560: Add a test that verifies ReportService.update_snapshot
does not update last_modified_by when the summary provided equals the existing
summary: set sample_snapshot.summary to a specific string and save, ensure
sample_snapshot.last_modified_by is None (or capture current value), call
ReportService.update_snapshot(sample_snapshot.id, SnapshotUpdate(summary="same
value"), orguser) with the exact same text, and assert that last_modified_by
remains unchanged (still None or equal to the captured value); reference
ReportService.update_snapshot, SnapshotUpdate, sample_snapshot and orguser to
locate where to add this new test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 795453c6-f0ce-4071-8879-44448ccf8e3e

📥 Commits

Reviewing files that changed from the base of the PR and between 8e26715 and de105ad.

📒 Files selected for processing (6)
  • ddpui/api/report_api.py
  • ddpui/core/reports/report_service.py
  • ddpui/migrations/0157_add_last_modified_by_to_report_snapshot.py
  • ddpui/migrations/0158_merge_20260415_1814.py
  • ddpui/models/report.py
  • ddpui/tests/core/reports/test_report_service.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • ddpui/api/report_api.py
  • ddpui/models/report.py

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
ddpui/core/reports/report_service.py (1)

547-550: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Only stamp last_modified_by when the summary actually changes.

Line 547-550 still overwrites attribution for no-op updates, which muddies audit history. Compare against snapshot.summary before assigning.

Suggested fix
-        if data.summary is not None:
+        if data.summary is not None and data.summary != snapshot.summary:
             snapshot.summary = data.summary
             snapshot.last_modified_by = orguser
             snapshot.save(update_fields=["summary", "last_modified_by", "updated_at"])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ddpui/core/reports/report_service.py` around lines 547 - 550, The code
currently sets snapshot.last_modified_by and saves even when data.summary equals
snapshot.summary; change the logic in report_service.py to compare data.summary
against snapshot.summary and only assign snapshot.summary = data.summary, set
snapshot.last_modified_by = orguser, and call snapshot.save(update_fields=[...])
when the value actually differs (otherwise do nothing), ensuring update_fields
still include "summary", "last_modified_by", and "updated_at" for the
real-change branch.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@ddpui/core/reports/report_service.py`:
- Around line 547-550: The code currently sets snapshot.last_modified_by and
saves even when data.summary equals snapshot.summary; change the logic in
report_service.py to compare data.summary against snapshot.summary and only
assign snapshot.summary = data.summary, set snapshot.last_modified_by = orguser,
and call snapshot.save(update_fields=[...]) when the value actually differs
(otherwise do nothing), ensuring update_fields still include "summary",
"last_modified_by", and "updated_at" for the real-change branch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a625472d-74d9-4151-b0c4-61f4690bfb13

📥 Commits

Reviewing files that changed from the base of the PR and between de105ad and ab21163.

📒 Files selected for processing (3)
  • ddpui/api/report_api.py
  • ddpui/core/reports/report_service.py
  • ddpui/models/report.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • ddpui/api/report_api.py
  • ddpui/models/report.py

siddhant3030 and others added 3 commits May 4, 2026 14:40
Resolves conflicting leaf nodes between 0158_allow_null_period_end_on_snapshot
(from main) and 0158_merge_20260415_1814 (last_modified_by feature).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@siddhant3030 siddhant3030 force-pushed the feature/last_modified_in_report branch from 7884260 to 60ef9cc Compare May 4, 2026 09:11
@siddhant3030 siddhant3030 merged commit 629762e into main May 4, 2026
4 of 5 checks passed
@siddhant3030 siddhant3030 deleted the feature/last_modified_in_report branch May 4, 2026 17:14
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.

2 participants