Skip to content

[OSDEV-2357] Add API endpoint to list partner fields#873

Merged
protsack-stephan merged 8 commits intomainfrom
OSDEV-2357-add-parnter-field-endpoints
Feb 10, 2026
Merged

[OSDEV-2357] Add API endpoint to list partner fields#873
protsack-stephan merged 8 commits intomainfrom
OSDEV-2357-add-parnter-field-endpoints

Conversation

@protsack-stephan
Copy link
Collaborator

@protsack-stephan protsack-stephan commented Feb 2, 2026

Summary:

  • Adds a new read-only API endpoint /api/partner-fields/ for listing partner fields
  • Implements cursor-based pagination with configurable page size via ?limit= parameter
  • Restricts access to superusers only

Changes:

  • New PartnerFieldSerializer exposing uuid, name, type, json_schema, active, system_field, created_at, and updated_at fields
  • New PartnerFieldsViewSet (read-only) with PartnerFieldCursorPagination (default 20 items, max 100)
  • New GET /api/partner-fields/ endpoint

@protsack-stephan protsack-stephan changed the title [OSDEV-2357] Add partner fields related API endpoint(s) [OSDEV-2357] Add list partner fields API endpoint Feb 2, 2026
@protsack-stephan protsack-stephan marked this pull request as ready for review February 2, 2026 15:24
@coderabbitai
Copy link

coderabbitai bot commented Feb 2, 2026

📝 Walkthrough

Walkthrough

Adds a new read-only API endpoint GET api/partner-fields/ that returns active PartnerField records with cursor-based pagination. Implements a DRF ModelSerializer, a superuser-only ReadOnlyModelViewSet with pagination, URL routing, tests, and a release-note entry.

Changes

Cohort / File(s) Summary
Serializer
src/django/api/serializers/partner_field/partner_field_serializer.py
New PartnerFieldSerializer (ModelSerializer) exposing uuid, name, type, json_schema, active, system_field, created_at, updated_at.
ViewSet & Pagination
src/django/api/views/partner_fields/partner_fields_view_set.py
New PartnerFieldsViewSet (ReadOnlyModelViewSet) with PartnerFieldCursorPagination (page_size=20, page_size_query_param="limit", max_page_size=100, ordering by created_at), superuser-only permission.
Routing & Exports
src/django/oar/urls.py, src/django/api/views/__init__.py
Registers GET api/partner-fields/ route and re-exports PartnerFieldsViewSet.
Tests
src/django/api/tests/test_partner_fields_view_set.py
Comprehensive tests for auth (401/403/200), active filtering, cursor pagination and limit enforcement, and disallowed mutating operations.
Docs
doc/release/RELEASE-NOTES.md
Release notes entry referencing the new API endpoint (OSDEV-2357).

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Client as Client
participant Router as API Router
participant ViewSet as PartnerFieldsViewSet
participant Serializer as PartnerFieldSerializer
participant DB as Database
Client->>Router: GET /api/partner-fields/?cursor=...
Router->>ViewSet: route to list action
ViewSet->>DB: query active PartnerField ordered by created_at (cursor)
DB-->>ViewSet: records page
ViewSet->>Serializer: serialize records
Serializer-->>ViewSet: JSON payload
ViewSet-->>Client: 200 OK (results, next_cursor)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • VadimKovalenkoSNF
  • vlad-shapik
  • roman-stolar
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding a new API endpoint for listing partner fields, matching the primary objective of this pull request.
Description check ✅ Passed The description provides relevant details about the changeset, including the endpoint, pagination implementation, access restrictions, and new components created, all aligned with the actual code changes.
Docstring Coverage ✅ Passed Docstring coverage is 94.12% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch OSDEV-2357-add-parnter-field-endpoints

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
src/django/api/views/partner_fields/partner_fields_view_set.py (1)

34-34: Disabling throttling entirely — is this intentional?

throttle_classes = [] removes all rate limiting. While this is a superuser-only endpoint, a compromised superuser token could still be used to hammer the endpoint. Consider whether the default throttle classes are acceptable here instead of explicitly opting out.


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 and usage tips.

Copy link

@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

🤖 Fix all issues with AI agents
In `@src/django/api/tests/test_partner_fields_view_set.py`:
- Around line 20-24: The test uses a hardcoded password in self.user_password
which triggers Ruff S105; replace the literal with a generated secret (e.g.,
call secrets.token_urlsafe or django.utils.crypto.get_random_string) and assign
that to self.user_password before calling
self.user.set_password(self.user_password), and ensure you add the corresponding
import (secrets or get_random_string) at the top of the test file;
alternatively, if you intentionally want a constant, add a targeted noqa comment
on the self.user_password assignment line to silence S105.
🧹 Nitpick comments (2)
doc/release/RELEASE-NOTES.md (1)

26-26: Clarify access scope in the release notes.
Since the endpoint is superuser-only, note that restriction to prevent confusion for external consumers.

✍️ Suggested wording
-* [OSDEV-2357](https://opensupplyhub.atlassian.net/browse/OSDEV-2357) - Add `GET api/partner-fields/` endpoint to retrieve partner active fields with pagination support.
+* [OSDEV-2357](https://opensupplyhub.atlassian.net/browse/OSDEV-2357) - Add `GET api/partner-fields/` endpoint (superuser-only) to retrieve partner active fields with pagination support.
src/django/api/views/partner_fields/partner_fields_view_set.py (1)

17-26: Add a deterministic tie‑breaker to cursor ordering.

Cursor pagination requires stable, deterministic ordering to avoid repeating or skipping items. Since created_at alone is not guaranteed to be unique (especially under high concurrency), add uuid (the primary key) as a secondary ordering field to ensure consistent pagination behavior.

♻️ Suggested change
-    ordering = "created_at"
+    ordering = ("created_at", "uuid")

DRF 3.15 supports tuple/list syntax for multi-field ordering, and the additional fields serve as deterministic tie-breakers while the first field determines cursor positions.

Copy link
Contributor

@VadimKovalenkoSNF VadimKovalenkoSNF left a comment

Choose a reason for hiding this comment

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

I left few questions, can you take a look? Otherwise, lgtm.

Copy link
Contributor

@VadimKovalenkoSNF VadimKovalenkoSNF left a comment

Choose a reason for hiding this comment

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

Thank you for this work, approved!

@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 9, 2026

Copy link
Contributor

@vlad-shapik vlad-shapik left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@VadimKovalenkoSNF VadimKovalenkoSNF left a comment

Choose a reason for hiding this comment

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

Re-approved.

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