Feature/snapshot subscription graphql - #5058
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughChangesSubscription models and persistence
Entity subscription GraphQL surface
Snapshot subscription GraphQL surface
Subscription administration
Chapter search query
Snapshot automation target arrangement
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## feature/community-snapshots #5058 +/- ##
===============================================================
+ Coverage 98.77% 98.78% +0.01%
===============================================================
Files 543 546 +3
Lines 17443 17739 +296
Branches 2539 2571 +32
===============================================================
+ Hits 17229 17524 +295
- Misses 88 89 +1
Partials 126 126
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 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 `@backend/apps/owasp/api/internal/mutations/snapshot_subscription.py`:
- Around line 167-173: The unsubscribe-token lookup in SnapshotSubscription
mutation only handles SnapshotSubscription.DoesNotExist and ValueError, but
invalid UUID input raises Django’s ValidationError before the query completes.
Update the exception handling in the mutation that calls
SnapshotSubscription.objects.get(unsubscribe_token=token) to also catch
ValidationError, and make sure the needed import from django.core.exceptions is
added so malformed tokens return the existing invalid-token result instead of an
unhandled error.
- Around line 63-86: The subscription creation logic in SnapshotSubscription
mutation is checking only
SnapshotSubscription.objects.filter(user=user).exists(), which blocks
re-subscription after cancel and still allows a race before create(). Update the
check to distinguish active vs inactive subscriptions (for example, based on
is_active in the SnapshotSubscription model) so canceled users can subscribe
again, and make the create path resilient to concurrent requests by handling the
one-to-one constraint failure around the subscription creation in the mutation
that builds the SnapshotSubscriptionResult.
In `@backend/apps/owasp/models/snapshot_subscription.py`:
- Around line 34-45: The subscription creation flow is blocking re-subscribes
because it treats inactive records as existing subscriptions. Update the
existence check in create_snapshot_subscription to only consider active
SnapshotSubscription rows by filtering on user and is_active=True, while keeping
the cancellation/unsubscribe behavior in cancel_snapshot_subscription and
unsubscribe_by_token unchanged so users can recreate a subscription after
canceling it.
In `@backend/tests/unit/apps/owasp/admin/snapshot_subscription_test.py`:
- Around line 12-45: The test only checks SnapshotSubscriptionAdmin directly and
misses whether apps.owasp.admin actually registers the model with admin.site.
Update the test in snapshot_subscription_test to import the admin package/module
that performs registration and assert SnapshotSubscription is present in
admin.site._registry, or that the registry entry is an instance of
SnapshotSubscriptionAdmin, so a broken import or missing admin.site.register
call is caught.
In
`@backend/tests/unit/apps/owasp/api/internal/mutations/snapshot_subscription_test.py`:
- Around line 187-195: Update test_malformed_token in
snapshot_subscription_test.py to match Django ORM behavior by mocking
django.core.exceptions.ValidationError instead of ValueError for
SnapshotSubscription.objects.get and keep the same unsubscribe_by_token
assertion. Also add a new test_create_after_cancel around
create_snapshot_subscription to verify a user can create a new subscription
after a previously cancelled/inactive one, so the test covers the intended
recreate flow rather than blocking on any existing record.
In
`@backend/tests/unit/apps/owasp/api/internal/queries/snapshot_subscription_test.py`:
- Around line 34-59: The snapshot subscription tests are calling the Strawberry
Django field descriptor directly instead of the underlying resolver, so they
never execute the real my_subscription logic. Update the tests in
SnapshotSubscriptionQuery to fetch the my_subscription field from the class and
invoke its base_resolver.func with self.query and info, so the resolver
implementation is actually exercised for the authenticated, not found, and found
cases.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 1a833131-728a-4590-803c-f98c71da2af2
⛔ Files ignored due to path filters (1)
frontend/src/types/__generated__/graphql.tsis excluded by!**/__generated__/**
📒 Files selected for processing (18)
backend/apps/owasp/admin/__init__.pybackend/apps/owasp/admin/snapshot_subscription.pybackend/apps/owasp/api/internal/mutations/__init__.pybackend/apps/owasp/api/internal/mutations/snapshot_subscription.pybackend/apps/owasp/api/internal/nodes/snapshot_subscription.pybackend/apps/owasp/api/internal/queries/__init__.pybackend/apps/owasp/api/internal/queries/snapshot_subscription.pybackend/apps/owasp/migrations/0075_snapshotsubscription.pybackend/apps/owasp/models/__init__.pybackend/apps/owasp/models/snapshot_subscription.pybackend/data/nest.dumpbackend/settings/graphql.pybackend/tests/unit/apps/owasp/admin/snapshot_subscription_test.pybackend/tests/unit/apps/owasp/api/internal/mutations/__init__.pybackend/tests/unit/apps/owasp/api/internal/mutations/snapshot_subscription_test.pybackend/tests/unit/apps/owasp/api/internal/nodes/snapshot_subscription_test.pybackend/tests/unit/apps/owasp/api/internal/queries/snapshot_subscription_test.pybackend/tests/unit/apps/owasp/models/snapshot_subscription_test.py
There was a problem hiding this comment.
2 issues found across 19 files
Confidence score: 2/5
- In
backend/apps/owasp/api/internal/mutations/snapshot_subscription.py, the create subscription path appears to block previously canceled users by only checking record existence, so users can get stuck permanently inactive via GraphQL after canceling — update the logic to allow reactivation (or check active state) before merging. - In
backend/apps/owasp/api/internal/mutations/snapshot_subscription.py,unsubscribe_by_tokendoes not catchValidationErrorfor malformed UUID tokens, which can bubble up as an unhandled GraphQL error instead of a controlled response — add UUID validation/error handling and return a safe client-facing error before merging.
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
22b8e4b to
5a1831b
Compare
|
Contribution validation failed:
|
5a1831b to
0f4f87b
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
backend/tests/unit/apps/owasp/api/internal/queries/snapshot_subscription_test.py (1)
34-37: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winResolver invocation still bypasses the actual resolver function.
field = SnapshotSubscriptionQuery.__dict__["my_subscription"]returns theStrawberryDjangoFielddescriptor (post-decoration), not the plainmy_subscriptionfunction. Calling it directly asfield(self.query, info=info)doesn't match how the field wraps/exposes its resolver, so this likely doesn't exercise the realmy_subscriptionbody (unauthenticated check,SnapshotSubscription.objects.get,DoesNotExisthandling).This is the same pattern flagged in a previous review of this exact resolver: access the underlying function via
base_resolverinstead.🐛 Suggested fix
def _resolve_my_subscription(self, info): """Invoke the underlying resolver for my_subscription.""" field = SnapshotSubscriptionQuery.__dict__["my_subscription"] - return field(self.query, info=info) + return field.base_resolver.func(self.query, info=info)Since the current call may silently pass/fail without ever running the real
my_subscriptionlogic, please confirm these tests actually fail/pass for the right reasons (e.g. temporarily break the resolver logic and re-run).🤖 Prompt for 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. In `@backend/tests/unit/apps/owasp/api/internal/queries/snapshot_subscription_test.py` around lines 34 - 37, The test helper for SnapshotSubscriptionQuery.my_subscription is invoking the StrawberryDjangoField descriptor directly instead of the underlying resolver, so it may not exercise the real resolver logic. Update _resolve_my_subscription to call the actual resolver via the field’s base_resolver on SnapshotSubscriptionQuery.my_subscription, and make sure the tests validate the unauthenticated path, SnapshotSubscription.objects.get lookup, and DoesNotExist handling by exercising the real my_subscription body.
🤖 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 `@backend/apps/owasp/api/internal/mutations/snapshot_subscription.py`:
- Around line 59-81: Wrap the project preference replacement logic in
_sync_project_preferences with a transaction so the delete-and-recreate sequence
is atomic, and make sure
create_snapshot_subscription/update_snapshot_subscription paths that call it are
protected as well. Handle IntegrityError at the mutation boundary so
reactivation or updates cannot leave SnapshotSubscription.project_preferences in
a partially applied state if a ProjectSubscriptionPreference.objects.create call
fails.
In `@backend/apps/owasp/api/internal/nodes/project_subscription_preference.py`:
- Around line 21-24: The `ProjectSubscriptionPreference.project` resolver is
using `prefetch_related` for a single ForeignKey, which is less appropriate than
a join-based fetch. Update the `@strawberry_django.field` configuration on
`project` to use `select_related` for the `project` relation instead, keeping
the resolver and `ProjectSubscriptionPreference`/`ProjectNode` signatures
unchanged.
In `@backend/apps/owasp/models/snapshot_subscription.py`:
- Around line 64-65: Remove the stale “Per-project preferences” comment from
snapshot_subscription.py so the section no longer suggests a missing field.
Update the SnapshotSubscription model definition by deleting that header comment
and keeping the surrounding class members aligned with the current schema, since
per-project preferences now belong in ProjectSubscriptionPreference.
In `@backend/tests/unit/apps/owasp/api/internal/queries/chapter_test.py`:
- Around line 136-151: The search_chapters test currently stubs __getitem__
without verifying the slice, so it can pass even if the limit is removed. Update
test_search_chapters_valid_query in ChapterQuery to assert that the ordered
queryset is sliced with SEARCH_CHAPTERS_LIMIT by checking the __getitem__ call
on mock_ordered_qs, while keeping the existing filter and order_by expectations.
---
Duplicate comments:
In
`@backend/tests/unit/apps/owasp/api/internal/queries/snapshot_subscription_test.py`:
- Around line 34-37: The test helper for
SnapshotSubscriptionQuery.my_subscription is invoking the StrawberryDjangoField
descriptor directly instead of the underlying resolver, so it may not exercise
the real resolver logic. Update _resolve_my_subscription to call the actual
resolver via the field’s base_resolver on
SnapshotSubscriptionQuery.my_subscription, and make sure the tests validate the
unauthenticated path, SnapshotSubscription.objects.get lookup, and DoesNotExist
handling by exercising the real my_subscription body.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 77b3504b-b851-4fc3-94c1-8db02ec93813
⛔ Files ignored due to path filters (1)
frontend/src/types/__generated__/graphql.tsis excluded by!**/__generated__/**
📒 Files selected for processing (25)
backend/apps/owasp/Makefilebackend/apps/owasp/admin/snapshot_subscription.pybackend/apps/owasp/api/internal/mutations/__init__.pybackend/apps/owasp/api/internal/mutations/snapshot_subscription.pybackend/apps/owasp/api/internal/nodes/chapter.pybackend/apps/owasp/api/internal/nodes/project_subscription_preference.pybackend/apps/owasp/api/internal/nodes/snapshot_subscription.pybackend/apps/owasp/api/internal/queries/__init__.pybackend/apps/owasp/api/internal/queries/chapter.pybackend/apps/owasp/api/internal/queries/snapshot_subscription.pybackend/apps/owasp/migrations/0076_add_project_subscription_preference.pybackend/apps/owasp/models/__init__.pybackend/apps/owasp/models/project_subscription_preference.pybackend/apps/owasp/models/snapshot_subscription.pybackend/data/nest.dumpbackend/settings/graphql.pybackend/tests/unit/apps/owasp/admin/snapshot_subscription_test.pybackend/tests/unit/apps/owasp/api/internal/mutations/__init__.pybackend/tests/unit/apps/owasp/api/internal/mutations/snapshot_subscription_test.pybackend/tests/unit/apps/owasp/api/internal/nodes/project_subscription_preference_test.pybackend/tests/unit/apps/owasp/api/internal/nodes/snapshot_subscription_test.pybackend/tests/unit/apps/owasp/api/internal/queries/chapter_test.pybackend/tests/unit/apps/owasp/api/internal/queries/snapshot_subscription_test.pybackend/tests/unit/apps/owasp/models/project_subscription_preference_test.pybackend/tests/unit/apps/owasp/models/snapshot_subscription_test.py
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
backend/apps/owasp/models/snapshot_subscription.py (1)
64-65: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winStale "Per-project preferences" comment still present.
This section header comment has no corresponding field anymore — per-project preferences now live in
ProjectSubscriptionPreference. This was flagged in a previous review round and appears unresolved.🧹 Proposed cleanup
- # Per-project preferences - created_at = models.DateTimeField(auto_now_add=True)🤖 Prompt for 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. In `@backend/apps/owasp/models/snapshot_subscription.py` around lines 64 - 65, Remove the stale “Per-project preferences” section header from snapshot_subscription.py, since the related data now lives in ProjectSubscriptionPreference. Update the surrounding class or model definitions in SnapshotSubscription so the comments only describe fields that still exist, and keep any remaining section headers aligned with the actual attributes.
🤖 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
`@backend/tests/unit/apps/owasp/api/internal/mutations/snapshot_subscription_test.py`:
- Around line 134-148: Add test coverage for the new project preferences sync
path in both TestCreateSnapshotSubscription and TestUpdateSnapshotSubscription,
since current tests only cover subscribed_chapter_ids and never exercise
input_data.project_preferences. Update the relevant mutation tests to pass
project_preferences and assert that _sync_project_preferences is triggered,
including the delete-and-create flow via
ProjectSubscriptionPreference.objects.create with the expected values. Use the
create_snapshot_subscription and update_snapshot_subscription mutation entry
points to locate the behavior.
---
Duplicate comments:
In `@backend/apps/owasp/models/snapshot_subscription.py`:
- Around line 64-65: Remove the stale “Per-project preferences” section header
from snapshot_subscription.py, since the related data now lives in
ProjectSubscriptionPreference. Update the surrounding class or model definitions
in SnapshotSubscription so the comments only describe fields that still exist,
and keep any remaining section headers aligned with the actual attributes.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 44fa69f1-2f8c-4d00-9630-76901f8b255c
📒 Files selected for processing (20)
backend/apps/owasp/Makefilebackend/apps/owasp/admin/snapshot_subscription.pybackend/apps/owasp/api/internal/mutations/snapshot_subscription.pybackend/apps/owasp/api/internal/nodes/chapter.pybackend/apps/owasp/api/internal/nodes/project_subscription_preference.pybackend/apps/owasp/api/internal/nodes/snapshot_subscription.pybackend/apps/owasp/api/internal/queries/chapter.pybackend/apps/owasp/migrations/0076_add_project_subscription_preference.pybackend/apps/owasp/models/__init__.pybackend/apps/owasp/models/project_subscription_preference.pybackend/apps/owasp/models/snapshot_subscription.pybackend/data/nest.dumpbackend/tests/unit/apps/owasp/admin/snapshot_subscription_test.pybackend/tests/unit/apps/owasp/api/internal/mutations/snapshot_subscription_test.pybackend/tests/unit/apps/owasp/api/internal/nodes/project_subscription_preference_test.pybackend/tests/unit/apps/owasp/api/internal/nodes/snapshot_subscription_test.pybackend/tests/unit/apps/owasp/api/internal/queries/chapter_test.pybackend/tests/unit/apps/owasp/api/internal/queries/snapshot_subscription_test.pybackend/tests/unit/apps/owasp/models/project_subscription_preference_test.pybackend/tests/unit/apps/owasp/models/snapshot_subscription_test.py
There was a problem hiding this comment.
All reported issues were addressed across 26 files
Confidence score: 5/5
- Safe to merge after the addressed issues were fixed.
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
backend/apps/owasp/api/internal/mutations/snapshot_subscription.py (2)
59-95: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winAdd a size cap on
project_preferencesto bound the per-item create loop.
_sync_project_preferencesiteratespreferencesand issues oneProjectSubscriptionPreference.objects.create()per item with no upper bound on list length. Since this is reachable from an authenticated mutation input (CreateSnapshotSubscriptionInput/UpdateSnapshotSubscriptionInput.project_preferences), a client could submit an arbitrarily large list, causing a large burst of synchronous DB writes within a single request/transaction. Consider capping the list length (mirroring theMAX_LIMIT-style constants used elsewhere, e.g.backend/apps/owasp/api/internal/queries/chapter.py) and/or usingbulk_createinstead of a per-item loop.♻️ Suggested change
+MAX_PROJECT_PREFERENCES = 100 + def _sync_project_preferences( subscription: SnapshotSubscription, preferences: list[ProjectPreferenceInput], ) -> None: ... project_ids = [pref.project_id for pref in preferences] + if len(project_ids) > MAX_PROJECT_PREFERENCES: + msg = f"Too many project preferences (max {MAX_PROJECT_PREFERENCES})." + raise ValueError(msg) if len(project_ids) != len(set(project_ids)): msg = "Duplicate project IDs in preferences." raise ValueError(msg) try: with transaction.atomic(): subscription.project_preferences.all().delete() - - for pref in preferences: - ProjectSubscriptionPreference.objects.create( - subscription=subscription, - project_id=pref.project_id, - include_issues=pref.include_issues, - include_pull_requests=pref.include_pull_requests, - include_releases=pref.include_releases, - ) + ProjectSubscriptionPreference.objects.bulk_create( + ProjectSubscriptionPreference( + subscription=subscription, + project_id=pref.project_id, + include_issues=pref.include_issues, + include_pull_requests=pref.include_pull_requests, + include_releases=pref.include_releases, + ) + for pref in preferences + ) except IntegrityError: msg = "Invalid project ID in preferences." raise ValueError(msg) from None🤖 Prompt for 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. In `@backend/apps/owasp/api/internal/mutations/snapshot_subscription.py` around lines 59 - 95, The _sync_project_preferences helper accepts an unbounded preferences list and creates one ProjectSubscriptionPreference row per item, so add a hard maximum for project_preferences before the transaction starts. Use the existing style of MAX_LIMIT-style constants used elsewhere and enforce it in _sync_project_preferences (or in the SnapshotSubscription mutation input path) so CreateSnapshotSubscriptionInput and UpdateSnapshotSubscriptionInput reject oversized lists. If appropriate, replace the per-item ProjectSubscriptionPreference.objects.create loop with bulk_create to reduce write overhead while keeping the duplicate-ID and IntegrityError handling intact.
275-299: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winAvoid returning
subscriptionfrom the token-based unsubscribe mutation.SnapshotSubscriptionNodecan reachProjectNode.recent_issues.author/assignees, andUserNodeexposesok/messagehere.🤖 Prompt for 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. In `@backend/apps/owasp/api/internal/mutations/snapshot_subscription.py` around lines 275 - 299, The unsubscribe_by_token mutation is returning a SnapshotSubscription object that can expose sensitive fields through SnapshotSubscriptionNode and related resolvers. Update unsubscribe_by_token in SnapshotSubscriptionResult handling so it returns only ok and message for both success and failure cases, and remove the subscription payload from the successful response; keep the token lookup, is_active check, and save logic unchanged.
🤖 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
`@backend/tests/unit/apps/owasp/api/internal/mutations/snapshot_subscription_test.py`:
- Around line 151-186: Add tests for the new validation branches in
`_sync_project_preferences` for both `create_snapshot_subscription` and the
update mutation path. Cover duplicate `project_id` inputs so the duplicate-check
`ValueError` is exercised and assert the mutation returns a failed result with
the validation message. Also add a test that patches
`ProjectSubscriptionPreference.objects.create` to raise `IntegrityError` and
verify it is mapped to `result.ok is False` with the "Invalid project ID in
preferences." message. Use the existing `mutations`,
`CreateSnapshotSubscriptionInput`, and update mutation test setup to locate the
relevant paths.
---
Outside diff comments:
In `@backend/apps/owasp/api/internal/mutations/snapshot_subscription.py`:
- Around line 59-95: The _sync_project_preferences helper accepts an unbounded
preferences list and creates one ProjectSubscriptionPreference row per item, so
add a hard maximum for project_preferences before the transaction starts. Use
the existing style of MAX_LIMIT-style constants used elsewhere and enforce it in
_sync_project_preferences (or in the SnapshotSubscription mutation input path)
so CreateSnapshotSubscriptionInput and UpdateSnapshotSubscriptionInput reject
oversized lists. If appropriate, replace the per-item
ProjectSubscriptionPreference.objects.create loop with bulk_create to reduce
write overhead while keeping the duplicate-ID and IntegrityError handling
intact.
- Around line 275-299: The unsubscribe_by_token mutation is returning a
SnapshotSubscription object that can expose sensitive fields through
SnapshotSubscriptionNode and related resolvers. Update unsubscribe_by_token in
SnapshotSubscriptionResult handling so it returns only ok and message for both
success and failure cases, and remove the subscription payload from the
successful response; keep the token lookup, is_active check, and save logic
unchanged.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: a44d03fd-97c5-458a-9e5c-31af054d9c72
📒 Files selected for processing (5)
backend/apps/owasp/api/internal/mutations/snapshot_subscription.pybackend/apps/owasp/api/internal/nodes/project_subscription_preference.pybackend/apps/owasp/models/snapshot_subscription.pybackend/tests/unit/apps/owasp/api/internal/mutations/snapshot_subscription_test.pybackend/tests/unit/apps/owasp/api/internal/queries/chapter_test.py
💤 Files with no reviewable changes (1)
- backend/apps/owasp/models/snapshot_subscription.py
There was a problem hiding this comment.
1 issue found across 2 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
Hi @arkid15r, please review it and let me know if any changes are required. |
1 similar comment
Signed-off-by: Harsh <harshit1092004@gmail.com>
6c8ae84 to
2bf8b4d
Compare
There was a problem hiding this comment.
Review completed against the latest diff
Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.
Re-trigger cubic
Signed-off-by: Harsh <harshit1092004@gmail.com>
There was a problem hiding this comment.
No issues found across 24 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.
Re-trigger cubic
Signed-off-by: Harsh <harshit1092004@gmail.com>
|
|
Hi @arkid15r, please review it and let me know if changes are required. |



Proposed change
Resolves #5056
Adds GraphQL mutations and query for managing snapshot digest subscriptions. Users can create, update, and cancel their subscription, and unsubscribe directly from email links using a token-based endpoint that requires no login.
Checklist