Users - Views & Endpoints

Location: api/nextango/apps/users/views.py, api/nextango/apps/users/urls.py Last Updated: 2026-07-08

Overview

UserViewSet is the primary API surface: it nests every role's data inside the user response, so a client does not need a second request to see an employee's PIN status or a customer's loyalty points. The role-specific ViewSets (EmployeeViewSet, CustomerViewSet, ManagerViewSet, InfluencerViewSet, VipViewSet) are kept only for backward compatibility and are not the recommended integration path for new code. UserProductCollectionViewSet covers wishlists, curations, and staff picks.

URL Registration

Every ViewSet in this file is registered twice. The canonical, client-facing paths come from the project's root router (nextango/urls.py), mounted at the URL root:

ViewSetCanonical path
UserViewSet/users/
EmployeeViewSet/employees/
CustomerViewSet/customers/
ManagerViewSet/managers/
InfluencerViewSet/influencers/
VipViewSet/vips/
UserProductCollectionViewSet/user-collections/

Note the collections slug differs between the two registrations: user-collections on the root router, collections on the app router.

The app's own urls.py is mounted at users/auth/, which produces a second, longer set of paths (the app router nests its ViewSets under a further users/ segment, so for example the user list is also reachable at /users/auth/users/users/ and collections at /users/auth/users/collections/). The users/auth/ mount is primarily how the authentication endpoints (PIN login, refresh, logout) are served; see Authentication. Paths in the sections below are the canonical root-router paths.

Permissions

None of the ViewSets in this file declare permission_classes, so DRF's DEFAULT_PERMISSION_CLASSES applies. That default resolves to IsActiveUser in production and AllowAny when DEBUG=True (nextango/settings/base.py:251-253). In a production deployment these endpoints therefore require an authenticated, active user; in a DEBUG environment they are open.

UserViewSet

Base: ModelViewSet Canonical URL: /users/

GET /users/

Lists users. Supports ?store=<uuid-or-sanity-id> to filter to employees and managers assigned to that store. The filter matches both the plain-string and reference-object shapes found in store_assignments. Response includes each user's primary_role, all_roles, roles_count, primary_role_data, and nested employee_roles / customer_roles / manager_roles / influencer_roles / vip_roles arrays.

GET/PUT/PATCH/DELETE /users/{id}/

Standard detail operations on a User record.

GET /users/me/

Returns the currently authenticated user, serialized the same way as the list/detail endpoints. Used by POS and dashboard clients after login.

GET /users/{id}/role_details/

Returns only the primary role's model data (an EmployeeSerializer, CustomerSerializer, etc. response, chosen by user.get_primary_role()). Returns 404 if the user has no primary role, 400 if the primary role does not map to a known serializer.

Role-Specific ViewSets (deprecated)

Each of these returns raw role-model instances rather than nested user data, so a second request against UserViewSet is needed to get parent-user context. Each carries a migration note in code pointing callers at UserViewSet and role_details.

ViewSetCanonical URLLookup fieldNotes
EmployeeViewSet/employees/employee_idAlso exposes GET /analytics/performance/ and GET /analytics/cash-drawer/, both ?store_id= + date-range filtered, backed by EmployeeAnalyticsService
CustomerViewSet/customers/default (pk)Also exposes GET /analytics/summary/ and GET /analytics/top/ (?limit=), backed by CustomerAnalyticsService
ManagerViewSet/managers/employee_id
InfluencerViewSet/influencers/default (pk)
VipViewSet/vips/default (pk)

UserProductCollectionViewSet

Base: ModelViewSet Canonical URL: /user-collections/

Query filters: ?owner=<uuid>, ?collection_type=wishlist|curation|staff-pick, ?is_public=true|false, ?is_featured=true|false.

GET /user-collections/my_collections/

Collections owned by the authenticated user.

GET /user-collections/featured/

Public, featured collections; the source for storefront discovery modules. Requires is_featured=true and is_public=true.

POST /user-collections/{id}/add_item/

Request: {"inventory_level_id": "<uuid>"}

Adds the given InventoryLevel to the collection's items M2M and returns the updated collection. 400 if inventory_level_id is missing, 404 if the InventoryLevel does not exist.

POST /user-collections/{id}/remove_item/

Same request shape as add_item; removes the item instead.

Authentication and Auth Endpoints

PIN login, token refresh, and logout are served from this app's urls.py under the users/auth/ mount and documented on the Authentication page: POST /users/auth/pin-login/, POST /users/auth/refresh/, POST /users/auth/logout/.

Was this page helpful?