- ID
- 1377bbae-3dca-4f4e-9c1c-526b3133985e
BE-7303 Evaluate CX skip/unskip endpoint strategy - dedicated internal CX endpoints
- source :: https://hungryroot.atlassian.net/browse/BE-7303
- tags :: Hungryroot API Project
- epic :: EP-411 Eng Parking Lot
- sprint :: HR BE Sprint 105 HR BE Sprint 106 HR BE Sprint 107
- status :: Status - To Do
- priority :: Priority - Low
- points :: 0.5
Tasks
DONE Investigate key differences between V1 and V2 skip and unskip endpoints
- ID
- b7a12255-fba2-fe85-5875-3e678acb53e1
- Note taken on
TODO Create tickets for dedicated CX internal endpoints for skip and unskip
Description
Background
We had to rollback a previous change (see diff below) that attempted to move the
CX tool's skip/unskip functionality from the v2 PATCH
/api/v2/customers/{id}/orders/{id}/ endpoint to the v1 POST /api/skip_order/ and
POST /api/unskip_order/ endpoints. The rollback was needed because the v1
skip/unskip endpoints have different behavior from what CX requires (e.g.,
different validation rules, permission handling, and side effects).
The v1 endpoints (app/views/api.skip_order and app/views/api.unskip_order) use
app.services.api.delivery.skip_order / unskip_order which have different logic
from the v2 OrderDetailSerializer.update() flow (in app/rest/order.py).
Key Differences
| Concern | v1 skip_order / unskip_order | v2 OrderDetailSerializer.update() |
| Permission check | is_user_in_group(request.user, 'support') - allows support to act on other users' orders | Standard DRF permission classes |
| Skip logic | Delegates to api.skip_order() service which has its own validation, is_in_support param | Inline validation + direct model update |
| Unskip logic | Delegates to api.unskip_order() service | Inline validation + calculate_preferred_date() + shuffle check |
| is_cx_action | Passed via POST body | Passed via query param ?is_cx_action=true |
Client Usage Audit
Codebase audit (completed):
skipOrder in api.js: Exported (httpPost('/api/skip_order/', {id: orderId})) but
not imported or used anywhere in the frontend. Dead code.
postUnskipOrder in api.js: Used only in CX tool's StatusModule.jsx (currently
rolled back to use v2 PATCH).
cxSkipOrder in internal.js: Used only in CX tool's StatusModule.jsx (currently
rolled back to use v2 PATCH).
No mobile/native client references to /api/skip_order/ or /api/unskip_order/ found
in the codebase.
No other Python views reference these endpoints beyond the v1 URL registration
in app/urls/apiv1.py.
!! Datadog audit required !! The codebase audit only confirms there are no
references in our code. We must check Datadog for actual traffic to these
endpoints from mobile and web clients before making any changes:
Check request volume to POST /api/skip_order/ and POST /api/unskip_order/ in Datadog
APM
Break down by client (mobile app vs web vs CX tool) to confirm no external
consumers
If there is mobile/web client traffic, those consumers must be migrated before
any endpoint changes
Goal
We want to keep skip/unskip for CX internal to the backoffice compute. The CX
tool should use either:
A NEW CX specific v2 API with CX-appropriate behavior, OR
A dedicated internal API endpoint (under /api/internal/ or similar) purpose-built
for CX use
The v1 /api/skip_order/ and /api/unskip_order/ endpoints should NOT be the path
forward for CX -- they are customer-facing endpoints with different validation
and side-effect behavior.
Options to Evaluate
Option A: Dedicated CX skip/unskip endpoints in api-internal
Create new endpoints under the internal API (e.g., POST
/api/internal/cx_skip_order/ and POST /api/internal/cx_unskip_order/) that:
Are restricted to support group users
Use the appropriate skip/unskip logic for CX use cases
Accept is_cx_action in the POST body
Live in app/views/internal.py or a dedicated CX module
Run on backoffice compute only
Option B: Create a NEW v2 API with CX-specific behavior
Keep the current v2 PATCH approach but ensure the is_cx_action query param
properly differentiates CX behavior (e.g., bypassing certain validations that
don't apply to support actions). This already runs on backoffice compute.
Acceptance Criteria
- [ ] Check Datadog for actual traffic to /api/skip_order/ and /api/unskip_order/ from mobile and web clients
- [ ] Decide on the approach (A, B, or C)
- [ ] Confirm no external client depends on these endpoints (Datadog + codebase)
- [ ] Implement the chosen approach, keeping it on backoffice compute
- [ ] Update the CX tool frontend (StatusModule.jsx) to use the new/chosen endpoints
- [ ] Remove dead code (skipOrder export in api.js if confirmed unused)
- [ ] Add/update tests for the new endpoint(s)
Related
Rolled-back PR that attempted this migration
app/views/api.py lines 380-438 (current v1 skip/unskip)
app/rest/order.py lines 919-968 (v2 skip/unskip via OrderDetailSerializer)
app/frontend/react/src/cx_tool/customerOrders/orderDetails/StatusModule.jsx (CX
tool consumer)
BE-7294: Allow CX actions to bypass order status validation on skip/unskip