FASHIONISTAR CI/CD
🔄 Celery Queues Deploy: d915798567b1052828794606dda8e62b4500f337 [GitHub Actions]
607bf71 | openapi: 3.0.3 | |
| info: | |
| title: Fashionistar API | |
| version: 1.0.0 | |
| description: |- | |
| Nigeria's Premier AI-Powered Fashion E-Commerce Platform API. | |
| **v1 (DRF/Sync):** Standard REST endpoints, WSGI-safe, Celery-backed. | |
| **v1 (Ninja/Async):** High-concurrency async endpoints, ASGI-native. | |
| **Authentication:** Bearer JWT (SimpleJWT). Get tokens via `/api/v1/auth/login/`. | |
| **Register first:** `POST /api/v1/auth/register/` → verify OTP → login. | |
| paths: | |
| /api/v1/admin_backend/auth/users/{user_id}/: | |
| get: | |
| operationId: v1_admin_backend_auth_users_retrieve | |
| parameters: | |
| - in: path | |
| name: user_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| put: | |
| operationId: v1_admin_backend_auth_users_update | |
| parameters: | |
| - in: path | |
| name: user_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/auth/users/{user_id}/force-password-reset/: | |
| post: | |
| operationId: v1_admin_backend_auth_users_force_password_reset_create | |
| parameters: | |
| - in: path | |
| name: user_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/auth/users/{user_id}/reactivate/: | |
| post: | |
| operationId: v1_admin_backend_auth_users_reactivate_create | |
| parameters: | |
| - in: path | |
| name: user_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/auth/users/{user_id}/suspend/: | |
| post: | |
| operationId: v1_admin_backend_auth_users_suspend_create | |
| parameters: | |
| - in: path | |
| name: user_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/auth/users/{user_id}/update-role/: | |
| post: | |
| operationId: v1_admin_backend_auth_users_update_role_create | |
| parameters: | |
| - in: path | |
| name: user_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/auth/users/{user_id}/verify/: | |
| post: | |
| operationId: v1_admin_backend_auth_users_verify_create | |
| parameters: | |
| - in: path | |
| name: user_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/catalog/blog/{post_id}/archive/: | |
| post: | |
| operationId: v1_admin_backend_catalog_blog_archive_create | |
| parameters: | |
| - in: path | |
| name: post_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/catalog/blog/{post_id}/update/: | |
| patch: | |
| operationId: v1_admin_backend_catalog_blog_update_partial_update | |
| parameters: | |
| - in: path | |
| name: post_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/catalog/blog/create/: | |
| post: | |
| operationId: v1_admin_backend_catalog_blog_create_create | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/catalog/brands/{brand_id}/archive/: | |
| post: | |
| operationId: v1_admin_backend_catalog_brands_archive_create | |
| parameters: | |
| - in: path | |
| name: brand_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/catalog/brands/{brand_id}/update/: | |
| patch: | |
| operationId: v1_admin_backend_catalog_brands_update_partial_update | |
| parameters: | |
| - in: path | |
| name: brand_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/catalog/brands/create/: | |
| post: | |
| operationId: v1_admin_backend_catalog_brands_create_create | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/catalog/categories/{category_id}/archive/: | |
| post: | |
| operationId: v1_admin_backend_catalog_categories_archive_create | |
| parameters: | |
| - in: path | |
| name: category_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/catalog/categories/{category_id}/update/: | |
| patch: | |
| operationId: v1_admin_backend_catalog_categories_update_partial_update | |
| parameters: | |
| - in: path | |
| name: category_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/catalog/categories/create/: | |
| post: | |
| operationId: v1_admin_backend_catalog_categories_create_create | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/catalog/collections/{collection_id}/archive/: | |
| post: | |
| operationId: v1_admin_backend_catalog_collections_archive_create | |
| parameters: | |
| - in: path | |
| name: collection_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/catalog/collections/{collection_id}/update/: | |
| patch: | |
| operationId: v1_admin_backend_catalog_collections_update_partial_update | |
| parameters: | |
| - in: path | |
| name: collection_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/catalog/collections/create/: | |
| post: | |
| operationId: v1_admin_backend_catalog_collections_create_create | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/chat/escalations/{escalation_id}/resolve/: | |
| post: | |
| operationId: v1_admin_backend_chat_escalations_resolve_create | |
| parameters: | |
| - in: path | |
| name: escalation_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/client/profiles/{profile_id}/: | |
| put: | |
| operationId: v1_admin_backend_client_profiles_update | |
| parameters: | |
| - in: path | |
| name: profile_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| patch: | |
| operationId: v1_admin_backend_client_profiles_partial_update | |
| parameters: | |
| - in: path | |
| name: profile_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/delivery/{order_id}/update/: | |
| post: | |
| operationId: v1_admin_backend_delivery_update_create | |
| description: Updates delivery status for legacy orders while apps/order migration | |
| is pending. | |
| summary: Update Delivery Status | |
| parameters: | |
| - in: path | |
| name: order_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/DeliveryStatusUpdateRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/DeliveryStatusUpdateRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/DeliveryStatusUpdateRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/DeliveryStatusUpdate' | |
| description: '' | |
| /api/v1/admin_backend/measurements/{profile_id}/verify/: | |
| post: | |
| operationId: v1_admin_backend_measurements_verify_create | |
| parameters: | |
| - in: path | |
| name: profile_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/notification/broadcast/: | |
| post: | |
| operationId: v1_admin_backend_notification_broadcast_create | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/order/{id}/cancel/: | |
| post: | |
| operationId: v1_admin_backend_order_cancel_create | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/order/{id}/release-escrow/: | |
| post: | |
| operationId: v1_admin_backend_order_release_escrow_create | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/order/{id}/transition/: | |
| post: | |
| operationId: v1_admin_backend_order_transition_create | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/payment/{payment_intent_id}/refund/: | |
| post: | |
| operationId: v1_admin_backend_payment_refund_create | |
| parameters: | |
| - in: path | |
| name: payment_intent_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/providers/cloudinary/update/: | |
| post: | |
| operationId: v1_admin_backend_providers_cloudinary_update_create | |
| description: POST /api/admin/providers/cloudinary/update/ | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/providers/email/update/: | |
| post: | |
| operationId: v1_admin_backend_providers_email_update_create | |
| description: POST /api/admin/providers/email/update/ | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/providers/kyc/update/: | |
| post: | |
| operationId: v1_admin_backend_providers_kyc_update_create | |
| description: POST /api/admin/providers/kyc/update/ | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/providers/sms/update/: | |
| post: | |
| operationId: v1_admin_backend_providers_sms_update_create | |
| description: POST /api/admin/providers/sms/update/ | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/settings/update/: | |
| post: | |
| operationId: v1_admin_backend_settings_update_create | |
| description: POST /api/admin/settings/update/ | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/support/{ticket_id}/assign/: | |
| post: | |
| operationId: v1_admin_backend_support_assign_create | |
| parameters: | |
| - in: path | |
| name: ticket_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/support/{ticket_id}/resolve/: | |
| post: | |
| operationId: v1_admin_backend_support_resolve_create | |
| parameters: | |
| - in: path | |
| name: ticket_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/vendor/{vendor_id}/approve/: | |
| post: | |
| operationId: v1_admin_backend_vendor_approve_create | |
| description: POST /api/admin/vendor/{vendor_id}/approve/ | |
| parameters: | |
| - in: path | |
| name: vendor_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/vendor/{vendor_id}/commission/: | |
| patch: | |
| operationId: v1_admin_backend_vendor_commission_partial_update | |
| description: PATCH /api/admin/vendor/{vendor_id}/commission/ | |
| parameters: | |
| - in: path | |
| name: vendor_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/vendor/{vendor_id}/featured/: | |
| patch: | |
| operationId: v1_admin_backend_vendor_featured_partial_update | |
| description: PATCH /api/admin/vendor/{vendor_id}/featured/ | |
| parameters: | |
| - in: path | |
| name: vendor_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/vendor/{vendor_id}/reactivate/: | |
| post: | |
| operationId: v1_admin_backend_vendor_reactivate_create | |
| description: POST /api/admin/vendor/{vendor_id}/reactivate/ | |
| parameters: | |
| - in: path | |
| name: vendor_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/vendor/{vendor_id}/reject/: | |
| post: | |
| operationId: v1_admin_backend_vendor_reject_create | |
| description: POST /api/admin/vendor/{vendor_id}/reject/ | |
| parameters: | |
| - in: path | |
| name: vendor_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/admin_backend/vendor/{vendor_id}/suspend/: | |
| post: | |
| operationId: v1_admin_backend_vendor_suspend_create | |
| description: POST /api/admin/vendor/{vendor_id}/suspend/ | |
| parameters: | |
| - in: path | |
| name: vendor_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/analytics/alert-rules/: | |
| get: | |
| operationId: v1_analytics_alert_rules_list | |
| description: ViewSet for managing alert rules (admin only). | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedAlertRuleList' | |
| description: '' | |
| post: | |
| operationId: v1_analytics_alert_rules_create | |
| description: ViewSet for managing alert rules (admin only). | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AlertRuleRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AlertRuleRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AlertRuleRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '201': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AlertRule' | |
| description: '' | |
| /api/v1/analytics/alert-rules/{id}/: | |
| get: | |
| operationId: v1_analytics_alert_rules_retrieve | |
| description: ViewSet for managing alert rules (admin only). | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: integer | |
| description: A unique integer value identifying this Alert Rule. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AlertRule' | |
| description: '' | |
| put: | |
| operationId: v1_analytics_alert_rules_update | |
| description: ViewSet for managing alert rules (admin only). | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: integer | |
| description: A unique integer value identifying this Alert Rule. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AlertRuleRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AlertRuleRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AlertRuleRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AlertRule' | |
| description: '' | |
| patch: | |
| operationId: v1_analytics_alert_rules_partial_update | |
| description: ViewSet for managing alert rules (admin only). | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: integer | |
| description: A unique integer value identifying this Alert Rule. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedAlertRuleRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedAlertRuleRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedAlertRuleRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AlertRule' | |
| description: '' | |
| delete: | |
| operationId: v1_analytics_alert_rules_destroy | |
| description: ViewSet for managing alert rules (admin only). | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: integer | |
| description: A unique integer value identifying this Alert Rule. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/analytics/alerts/: | |
| get: | |
| operationId: v1_analytics_alerts_list | |
| description: ViewSet for viewing fired alerts. | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedAlertList' | |
| description: '' | |
| /api/v1/analytics/alerts/{id}/: | |
| get: | |
| operationId: v1_analytics_alerts_retrieve | |
| description: ViewSet for viewing fired alerts. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: integer | |
| description: A unique integer value identifying this Alert. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Alert' | |
| description: '' | |
| /api/v1/analytics/alerts/resolve_all/: | |
| post: | |
| operationId: v1_analytics_alerts_resolve_all_create | |
| description: Resolve all currently firing alerts. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AlertRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AlertRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AlertRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Alert' | |
| description: '' | |
| /api/v1/analytics/business-metrics/: | |
| get: | |
| operationId: v1_analytics_business_metrics_list | |
| description: ViewSet for viewing business aggregates (admin only). | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedBusinessMetricList' | |
| description: '' | |
| /api/v1/analytics/business-metrics/{id}/: | |
| get: | |
| operationId: v1_analytics_business_metrics_retrieve | |
| description: ViewSet for viewing business aggregates (admin only). | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: integer | |
| description: A unique integer value identifying this Business Metric. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/BusinessMetric' | |
| description: '' | |
| /api/v1/analytics/calculate-business-metrics/: | |
| post: | |
| operationId: v1_analytics_calculate_business_metrics_create | |
| description: Calculate e-commerce aggregates. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/analytics/check-alerts/: | |
| post: | |
| operationId: v1_analytics_check_alerts_create | |
| description: Evaluate alert rules. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/analytics/metrics/: | |
| get: | |
| operationId: v1_analytics_metrics_list | |
| description: ViewSet for viewing system telemetry metrics. | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedMetricList' | |
| description: '' | |
| /api/v1/analytics/metrics/{id}/: | |
| get: | |
| operationId: v1_analytics_metrics_retrieve | |
| description: ViewSet for viewing system telemetry metrics. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: integer | |
| description: A unique integer value identifying this Metric. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Metric' | |
| description: '' | |
| /api/v1/analytics/performance-analytics/: | |
| get: | |
| operationId: v1_analytics_performance_analytics_retrieve | |
| description: Retrieve API latency analytics. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/analytics/performance-metrics/: | |
| get: | |
| operationId: v1_analytics_performance_metrics_list | |
| description: ViewSet for checking API latencies. | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedPerformanceMetricList' | |
| description: '' | |
| /api/v1/analytics/performance-metrics/{id}/: | |
| get: | |
| operationId: v1_analytics_performance_metrics_retrieve | |
| description: ViewSet for checking API latencies. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: integer | |
| description: A unique integer value identifying this Performance Metric. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PerformanceMetric' | |
| description: '' | |
| /api/v1/analytics/record-metric/: | |
| post: | |
| operationId: v1_analytics_record_metric_create | |
| description: Record a new telemetry metric. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/analytics/system-overview/: | |
| get: | |
| operationId: v1_analytics_system_overview_retrieve | |
| description: Retrieve a system-wide overview of active indicators. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/analytics/user-activities/: | |
| get: | |
| operationId: v1_analytics_user_activities_list | |
| description: ViewSet for auditing user activities. | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedUserActivityList' | |
| description: '' | |
| /api/v1/analytics/user-activities/{id}/: | |
| get: | |
| operationId: v1_analytics_user_activities_retrieve | |
| description: ViewSet for auditing user activities. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: integer | |
| description: A unique integer value identifying this User Activity. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/UserActivity' | |
| description: '' | |
| /api/v1/analytics/user-analytics/: | |
| get: | |
| operationId: v1_analytics_user_analytics_retrieve | |
| description: Retrieve user activity statistics. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/auth/google/: | |
| post: | |
| operationId: v1_auth_google_create | |
| description: |- | |
| Authenticate a user via Google OAuth2 ID Token. | |
| Flow: | |
| 1. Verify the provided 'id_token' with Google's public keys. | |
| 2. Identify or register the user based on email (is_new flag returned). | |
| 3. Provision defaults for new client users asynchronously. | |
| 4. Record UserSession and LoginEvent for audit tracking. | |
| 5. Issue JWT tokens and profile state for frontend routing. | |
| Status Codes: | |
| - 201 Created: New user registered. | |
| - 200 OK: Returning user logged in. | |
| - 401 Unauthorized: Invalid or expired token. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthGoogleAuthRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AuthGoogleAuthRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AuthGoogleAuthRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '201': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthGoogleAuth' | |
| description: '' | |
| /api/v1/auth/login/: | |
| post: | |
| operationId: v1_auth_login_create | |
| description: |- | |
| POST /api/v1/auth/login/ | |
| Synchronous Login — email/phone + password → JWT tokens. | |
| Success Response 200: | |
| { "access": "<JWT>", "refresh": "<JWT>", "user_id": "...", "role": "..." } | |
| Cookie: | |
| fashionistar_rt (HttpOnly) → refresh token | |
| Status Codes: | |
| - 200 OK: Authentication successful. | |
| - 401 Unauthorized: Invalid credentials. | |
| - 403 Forbidden: Account unverified or deactivated. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthLoginRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AuthLoginRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AuthLoginRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/auth/login-events/: | |
| get: | |
| operationId: v1_auth_login_events_list | |
| description: Return recent login-event audit entries for the authenticated user. | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedLoginEventList' | |
| description: '' | |
| /api/v1/auth/logout/: | |
| post: | |
| operationId: v1_auth_logout_create | |
| description: |- | |
| POST /api/v1/auth/logout/ | |
| Terminate the user session and blacklist the refresh token. | |
| Flow: | |
| 1. Accept current refresh token. | |
| 2. Blacklist the token in the database to prevent reuse. | |
| 3. Clear the HttpOnly session cookie. | |
| 4. Dispatch log_logout() audit event on commit (compliance). | |
| Status Codes: | |
| - 200 OK: Logout successful. | |
| - 400 Bad Request: Token already invalid. | |
| - 401 Unauthorized: Not authenticated. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthLogoutRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AuthLogoutRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AuthLogoutRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthLogout' | |
| description: '' | |
| /api/v1/auth/me/: | |
| get: | |
| operationId: v1_auth_me_retrieve | |
| description: |- | |
| GET /api/v1/auth/me/ | |
| Returns the authenticated user's full profile via MeSerializer. | |
| Used by useAuthHydration() to rehydrate Zustand on page refresh. | |
| Authorization: Bearer <access_token> | |
| Error 401: Not authenticated / token expired. | |
| Response shape (stable contract with frontend): | |
| { | |
| "user_id": "uuid-string", | |
| "identifying_info": "email@example.com" | "+2348012345678", | |
| "member_id": "FASTAR000001" | null, | |
| "email": "email@example.com" | null, | |
| "phone": "+2348012345678" | null, | |
| "first_name": "John" | "", | |
| "last_name": "Doe" | "", | |
| "role": "client" | "vendor" | "staff" | ..., | |
| "auth_provider": "email" | "phone" | "google", | |
| "is_verified": true | false, | |
| "is_active": true | false, | |
| "is_staff": true | false, | |
| "avatar": "https://res.cloudinary.com/..." | null, | |
| "bio": "..." | "", | |
| "country": "Nigeria" | "", | |
| "state": "Lagos" | "", | |
| "city": "Ikeja" | "", | |
| "address": "..." | "", | |
| "date_joined": "2024-01-15T10:30:00+00:00" | null, | |
| "last_login": "2024-01-15T10:30:00+00:00" | null | |
| } | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthMe' | |
| description: '' | |
| /api/v1/auth/register/: | |
| post: | |
| operationId: v1_auth_register_create | |
| description: |- | |
| POST /api/v1/auth/register/ | |
| Synchronous user registration. | |
| Accepts email OR phone + password + role, creates the user inside an | |
| atomic transaction, generates a 6-digit OTP, and dispatches it via | |
| Email (if email provided) or SMS (if phone only). | |
| Mirrors legacy: ``userauths.views.RegisterViewCelery`` | |
| Request Body: | |
| email (str, optional) : User email address. | |
| phone (str, optional) : Phone in E.164 format (+234...). | |
| password (str, required) : Min 8 chars. | |
| password2 (str, required) : Must match password. | |
| role (str, required) : 'vendor' or 'client'. | |
| Success Response 201: | |
| { "message": "...", "user_id": "<uuid>", "email": "...", "phone": null } | |
| Error Responses: | |
| 400 — Validation error | |
| 500 — Unexpected server error (transaction rolled back) | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthUserRegistrationRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AuthUserRegistrationRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AuthUserRegistrationRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '201': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthUserRegistration' | |
| description: '' | |
| /api/v1/auth/resend-otp/: | |
| post: | |
| operationId: v1_auth_resend_otp_create | |
| description: |- | |
| POST /api/v1/auth/resend-otp/ | |
| Regenerate and resend a 6-digit OTP code. | |
| Flow: | |
| 1. Validate user existence by email or phone. | |
| 2. Regenerate a new secure OTP code. | |
| 3. Dispatch via the primary communication channel. | |
| Status Codes: | |
| - 200 OK: OTP resent successfully. | |
| - 400 Bad Request: Validation or throttled request. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthResendOTPRequestRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AuthResendOTPRequestRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AuthResendOTPRequestRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/auth/sessions/: | |
| get: | |
| operationId: v1_auth_sessions_list | |
| description: List active sessions for the authenticated user. | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedUserSessionList' | |
| description: '' | |
| /api/v1/auth/sessions/{session_id}/: | |
| delete: | |
| operationId: v1_auth_sessions_destroy | |
| description: Revoke a specific active session owned by the authenticated user. | |
| parameters: | |
| - in: path | |
| name: session_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/auth/sessions/revoke-others/: | |
| post: | |
| operationId: v1_auth_sessions_revoke_others_create | |
| description: Terminates every active session on the account except the current | |
| request's session. | |
| summary: Revoke all other sessions | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/auth/token/refresh/: | |
| post: | |
| operationId: v1_auth_token_refresh_create | |
| description: |- | |
| POST /api/v1/auth/token/refresh/ | |
| Refresh JWT access tokens using the stored refresh token. | |
| Flow: | |
| 1. Extract refresh token from request body (or HttpOnly cookie). | |
| 2. Verify refresh token validity via SimpleJWT. | |
| 3. Issue new short-lived access token. | |
| Status Codes: | |
| - 200 OK: Access token refreshed. | |
| - 401 Unauthorized: Invalid or expired refresh token. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthTokenRefreshRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AuthTokenRefreshRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AuthTokenRefreshRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthTokenRefresh' | |
| description: '' | |
| /api/v1/auth/verify-otp/: | |
| post: | |
| operationId: v1_auth_verify_otp_create | |
| description: |- | |
| POST /api/v1/auth/verify-otp/ | |
| Verify the 6-digit OTP code and activate the user account. | |
| Flow: | |
| 1. Accept OTP code (O(1) Redis lookup by hash). | |
| 2. Identify the user ID associated with the OTP. | |
| 3. Activate the user (is_verified=True, is_active=True). | |
| 4. Auto-issue JWT session tokens on successful verification. | |
| Security: | |
| One-time use. OTP is deleted from Redis immediately upon verification. | |
| Issues JWT tokens immediately on success so the user is logged in. | |
| Status Codes: | |
| - 200 OK: Verification successful, account activated. | |
| - 400 Bad Request: Invalid or expired OTP. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthOTPRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AuthOTPRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AuthOTPRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthOTP' | |
| description: '' | |
| /api/v1/catalog/blog/: | |
| post: | |
| operationId: v1_catalog_blog_create | |
| description: Create a catalog resource through the configured domain service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPostRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPostRequest' | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPostRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPost' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPost' | |
| text/html: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPost' | |
| description: '' | |
| /api/v1/catalog/blog/{slug}/: | |
| put: | |
| operationId: v1_catalog_blog_update | |
| description: Replace a catalog resource through the configured domain service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPostRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPostRequest' | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPostRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPost' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPost' | |
| text/html: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPost' | |
| description: '' | |
| patch: | |
| operationId: v1_catalog_blog_partial_update | |
| description: Partially update a catalog resource through the configured service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedCatalogBlogPostRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedCatalogBlogPostRequest' | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedCatalogBlogPostRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPost' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPost' | |
| text/html: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBlogPost' | |
| description: '' | |
| delete: | |
| operationId: v1_catalog_blog_destroy | |
| description: Archive a catalog resource through the configured domain service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/catalog/brands/: | |
| post: | |
| operationId: v1_catalog_brands_create | |
| description: Create a catalog resource through the configured domain service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrandRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrandRequest' | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrandRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrand' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrand' | |
| text/html: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrand' | |
| description: '' | |
| /api/v1/catalog/brands/{slug}/: | |
| put: | |
| operationId: v1_catalog_brands_update | |
| description: Replace a catalog resource through the configured domain service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrandRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrandRequest' | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrandRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrand' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrand' | |
| text/html: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrand' | |
| description: '' | |
| patch: | |
| operationId: v1_catalog_brands_partial_update | |
| description: Partially update a catalog resource through the configured service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedCatalogBrandRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedCatalogBrandRequest' | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedCatalogBrandRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrand' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrand' | |
| text/html: | |
| schema: | |
| $ref: '#/components/schemas/CatalogBrand' | |
| description: '' | |
| delete: | |
| operationId: v1_catalog_brands_destroy | |
| description: Archive a catalog resource through the configured domain service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/catalog/categories/: | |
| post: | |
| operationId: v1_catalog_categories_create | |
| description: Create a catalog resource through the configured domain service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategoryRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategoryRequest' | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategoryRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategory' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategory' | |
| text/html: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategory' | |
| description: '' | |
| /api/v1/catalog/categories/{slug}/: | |
| put: | |
| operationId: v1_catalog_categories_update | |
| description: Replace a catalog resource through the configured domain service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategoryRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategoryRequest' | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategoryRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategory' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategory' | |
| text/html: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategory' | |
| description: '' | |
| patch: | |
| operationId: v1_catalog_categories_partial_update | |
| description: Partially update a catalog resource through the configured service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedCatalogCategoryRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedCatalogCategoryRequest' | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedCatalogCategoryRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategory' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategory' | |
| text/html: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCategory' | |
| description: '' | |
| delete: | |
| operationId: v1_catalog_categories_destroy | |
| description: Archive a catalog resource through the configured domain service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/catalog/collections/: | |
| post: | |
| operationId: v1_catalog_collections_create | |
| description: Create a catalog resource through the configured domain service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollectionRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollectionRequest' | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollectionRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollection' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollection' | |
| text/html: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollection' | |
| description: '' | |
| /api/v1/catalog/collections/{slug}/: | |
| put: | |
| operationId: v1_catalog_collections_update | |
| description: Replace a catalog resource through the configured domain service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollectionRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollectionRequest' | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollectionRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollection' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollection' | |
| text/html: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollection' | |
| description: '' | |
| patch: | |
| operationId: v1_catalog_collections_partial_update | |
| description: Partially update a catalog resource through the configured service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedCatalogCollectionRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedCatalogCollectionRequest' | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedCatalogCollectionRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollection' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollection' | |
| text/html: | |
| schema: | |
| $ref: '#/components/schemas/CatalogCollection' | |
| description: '' | |
| delete: | |
| operationId: v1_catalog_collections_destroy | |
| description: Archive a catalog resource through the configured domain service. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/chat/conversations/: | |
| get: | |
| operationId: v1_chat_conversations_retrieve | |
| description: |- | |
| GET /api/v1/chat/conversations/ | |
| Returns all conversations for the authenticated user. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/chat/conversations/{conversation_id}/: | |
| get: | |
| operationId: v1_chat_conversations_retrieve_2 | |
| description: |- | |
| GET /api/v1/chat/conversations/<conversation_id>/ | |
| GET messages for a conversation (paginated, newest-first). | |
| Also marks all messages as read for the requesting participant. | |
| parameters: | |
| - in: path | |
| name: conversation_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/chat/conversations/{conversation_id}/flag/: | |
| post: | |
| operationId: v1_chat_conversations_flag_create | |
| description: |- | |
| POST /api/v1/chat/conversations/<conversation_id>/flag/ | |
| File a moderation report for a conversation. | |
| parameters: | |
| - in: path | |
| name: conversation_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/chat/conversations/{conversation_id}/messages/: | |
| post: | |
| operationId: v1_chat_conversations_messages_create | |
| description: |- | |
| POST /api/v1/chat/conversations/<conversation_id>/messages/ | |
| Send a text message in a conversation. | |
| parameters: | |
| - in: path | |
| name: conversation_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/chat/conversations/{conversation_id}/offers/: | |
| post: | |
| operationId: v1_chat_conversations_offers_create | |
| description: |- | |
| POST /api/v1/chat/conversations/<conversation_id>/offers/ | |
| Vendor creates a price offer for the buyer. | |
| parameters: | |
| - in: path | |
| name: conversation_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/chat/conversations/{conversation_id}/read/: | |
| post: | |
| operationId: v1_chat_conversations_read_create | |
| description: |- | |
| POST /api/v1/chat/conversations/<conversation_id>/read/ | |
| Mark all messages in a conversation as read for the requesting participant. | |
| parameters: | |
| - in: path | |
| name: conversation_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/chat/conversations/start/: | |
| post: | |
| operationId: v1_chat_conversations_start_create | |
| description: |- | |
| POST /api/v1/chat/conversations/start/ | |
| Buyer starts a new conversation with a vendor. | |
| Idempotent — returns existing active thread if one exists. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/chat/offers/{offer_id}/{action}/: | |
| post: | |
| operationId: v1_chat_offers_create | |
| description: |- | |
| POST /api/v1/chat/offers/<offer_id>/accept/ | |
| POST /api/v1/chat/offers/<offer_id>/decline/ | |
| Buyer accepts or declines an offer. | |
| parameters: | |
| - in: path | |
| name: action | |
| schema: | |
| type: string | |
| required: true | |
| - in: path | |
| name: offer_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/chatbot/api/client/end-session/: | |
| post: | |
| operationId: v1_chatbot_api_client_end_session_create | |
| description: |- | |
| پایان جلسهٔ فعال چتبات برای کاربر جاری. | |
| این اکشن، جلسهٔ فعال چتبات مرتبط با کاربر احراز هویتشده را از طریق سرویس چتبات (get_chatbot_service) خاتمه میدهد. فراخوانی سرویس معمولاً شامل عملیاتهای زیر است: | |
| - علامتگذاری جلسه بهعنوان "پایانیافته" در پایگاهداده. | |
| - ذخیره/همگامسازی وضعیت نهایی جلسه و گفتگوها. | |
| - انجام پاکسازی زمینههای مرتبط در حافظه یا صفهای پردازشی که ممکن است برای نگهداری کانتکست مکالمه استفاده شده باشند. | |
| - در صورت وجود وظایف پسزمینه (مثل انتها دادن به پردازشهای هوشمصنوعی یا آزادسازی منابع مدل)، راهاندازی یا برنامهریزی آنها. | |
| پاسخ: | |
| - موفقیت: JSON با کلید `message` و مقدار متنی تایید (HTTP 200). | |
| - خطا: در صورت بروز استثنا، JSON با کلید `error` و پیام خطا بازگردانده شده و کد وضعیت HTTP 500 برگردانده میشود. | |
| توجه: پیادهسازی دقیق رفتارهای دخیل در سرویس چتبات (ذخیرهسازی، همگامسازی مدل/وظایف پسزمینه و ...) در لایهٔ سرویس قرار دارد و این اکشن صرفاً درگاه فراخوانی و مدیریت پاسخ/خطا برای آن سرویس است. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/chatbot/api/client/request-consultation/: | |
| post: | |
| operationId: v1_chatbot_api_client_request_consultation_create | |
| description: Initiate request for custom tailoring consultation | |
| summary: Request bespoke consultation | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/BespokeConsultationRequestRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/BespokeConsultationRequestRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/BespokeConsultationRequestRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| additionalProperties: {} | |
| description: '' | |
| /api/v1/chatbot/api/client/send-message/: | |
| post: | |
| operationId: v1_chatbot_api_client_send_message_create | |
| description: Send client message and get chatbot response | |
| summary: Send message to chatbot | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/SendMessageRequestRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/SendMessageRequestRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/SendMessageRequestRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/SendMessageResponse' | |
| description: '' | |
| /api/v1/chatbot/api/client/start-session/: | |
| post: | |
| operationId: v1_chatbot_api_client_start_session_create | |
| description: Initialize or get active chatbot session for client | |
| summary: Start client chatbot session | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/StartSessionResponse' | |
| description: '' | |
| /api/v1/chatbot/api/client/style-assessment/: | |
| post: | |
| operationId: v1_chatbot_api_client_style_assessment_create | |
| description: Initialize style assessment questionnaire for the client | |
| summary: Start style assessment | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| additionalProperties: {} | |
| description: '' | |
| /api/v1/chatbot/api/client/submit-assessment/: | |
| post: | |
| operationId: v1_chatbot_api_client_submit_assessment_create | |
| description: Submit style preferences and get outfits recommendations | |
| summary: Submit style assessment responses | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/StyleAssessmentRequestRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/StyleAssessmentRequestRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/StyleAssessmentRequestRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| additionalProperties: {} | |
| description: '' | |
| /api/v1/chatbot/api/conversations/: | |
| get: | |
| operationId: v1_chatbot_api_conversations_list | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedConversationList' | |
| description: '' | |
| post: | |
| operationId: v1_chatbot_api_conversations_create | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ConversationRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/ConversationRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/ConversationRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '201': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Conversation' | |
| description: '' | |
| /api/v1/chatbot/api/conversations/{id}/: | |
| get: | |
| operationId: v1_chatbot_api_conversations_retrieve | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Conversation. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Conversation' | |
| description: '' | |
| put: | |
| operationId: v1_chatbot_api_conversations_update | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Conversation. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ConversationRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/ConversationRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/ConversationRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Conversation' | |
| description: '' | |
| patch: | |
| operationId: v1_chatbot_api_conversations_partial_update | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Conversation. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedConversationRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedConversationRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedConversationRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Conversation' | |
| description: '' | |
| delete: | |
| operationId: v1_chatbot_api_conversations_destroy | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Conversation. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/chatbot/api/conversations/{id}/history/: | |
| get: | |
| operationId: v1_chatbot_api_conversations_history_retrieve | |
| description: |- | |
| بازگرداندن تاریخچه یک مکالمه مشخص. | |
| این اکشن تاریخچه پیامهای یک گفتوگو را برمیگرداند: ابتدا شیء conversation با self.get_object() واکشی میشود، سپس پیامها بر اساس `created_at` نزولی مرتب و تا تعداد `limit` برش داده میشوند. پاسخ JSON شامل نسخهی سریالایز شدهی گفتوگو، لیست پیامها (جدیدترین ابتدا)، تعداد کل پیامها و یک فِلَگ `has_more` برای نشان دادن وجود پیامهای بیشتر است. | |
| پارامترهای کوئری: | |
| limit (int, اختیاری): حداکثر تعداد پیامهایی که برگردانده میشوند. مقدار پیشفرض 50 است. | |
| مقدار بازگشتی: | |
| rest_framework.response.Response: بدنهی JSON با کلیدهای: | |
| - conversation: دادههای سریالایز شدهٔ گفتوگو (ConversationListSerializer). | |
| - messages: فهرست پیامهای سریالایز شده (MessageSerializer) مرتبشده به صورت نزولی بر اساس `created_at`. | |
| - total_messages: تعداد کل پیامهای موجود در آن گفتوگو. | |
| - has_more: بولین که نشان میدهد آیا پیامهای بیشتری نسبت به `limit` وجود دارد یا خیر. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Conversation. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Conversation' | |
| description: '' | |
| /api/v1/chatbot/api/messages/: | |
| get: | |
| operationId: v1_chatbot_api_messages_list | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedMessageList' | |
| description: '' | |
| post: | |
| operationId: v1_chatbot_api_messages_create | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/MessageRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/MessageRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/MessageRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '201': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Message' | |
| description: '' | |
| /api/v1/chatbot/api/messages/{id}/: | |
| get: | |
| operationId: v1_chatbot_api_messages_retrieve | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Message. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Message' | |
| description: '' | |
| put: | |
| operationId: v1_chatbot_api_messages_update | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Message. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/MessageRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/MessageRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/MessageRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Message' | |
| description: '' | |
| patch: | |
| operationId: v1_chatbot_api_messages_partial_update | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Message. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedMessageRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedMessageRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedMessageRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Message' | |
| description: '' | |
| delete: | |
| operationId: v1_chatbot_api_messages_destroy | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Message. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/chatbot/api/sessions/: | |
| get: | |
| operationId: v1_chatbot_api_sessions_list | |
| description: مدیریت جلسات چتبات | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedChatbotSessionList' | |
| description: '' | |
| post: | |
| operationId: v1_chatbot_api_sessions_create | |
| description: مدیریت جلسات چتبات | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ChatbotSessionRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/ChatbotSessionRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/ChatbotSessionRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '201': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ChatbotSession' | |
| description: '' | |
| /api/v1/chatbot/api/sessions/{id}/: | |
| get: | |
| operationId: v1_chatbot_api_sessions_retrieve | |
| description: مدیریت جلسات چتبات | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Chatbot Session. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ChatbotSession' | |
| description: '' | |
| put: | |
| operationId: v1_chatbot_api_sessions_update | |
| description: مدیریت جلسات چتبات | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Chatbot Session. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ChatbotSessionRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/ChatbotSessionRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/ChatbotSessionRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ChatbotSession' | |
| description: '' | |
| patch: | |
| operationId: v1_chatbot_api_sessions_partial_update | |
| description: مدیریت جلسات چتبات | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Chatbot Session. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedChatbotSessionRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedChatbotSessionRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedChatbotSessionRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ChatbotSession' | |
| description: '' | |
| delete: | |
| operationId: v1_chatbot_api_sessions_destroy | |
| description: مدیریت جلسات چتبات | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Chatbot Session. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/chatbot/api/vendor/catalog-support/: | |
| post: | |
| operationId: v1_chatbot_api_vendor_catalog_support_create | |
| description: Get recommendation and categorization for new products | |
| summary: Request product catalog support | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/SizeRecommendationRequestRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/SizeRecommendationRequestRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/SizeRecommendationRequestRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| additionalProperties: {} | |
| description: '' | |
| /api/v1/chatbot/api/vendor/product-info/: | |
| post: | |
| operationId: v1_chatbot_api_vendor_product_info_create | |
| description: Get fabric, pricing and packaging details | |
| summary: Request product specifications | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ProductInquiryRequestRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/ProductInquiryRequestRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/ProductInquiryRequestRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| additionalProperties: {} | |
| description: '' | |
| /api/v1/chatbot/api/vendor/search-references/: | |
| get: | |
| operationId: v1_chatbot_api_vendor_search_references_retrieve | |
| description: Search design ideas, trends and fabric references | |
| summary: Search fashion references | |
| parameters: | |
| - in: query | |
| name: query | |
| schema: | |
| type: string | |
| description: Search Query | |
| - in: query | |
| name: specialty | |
| schema: | |
| type: string | |
| description: Specialty Niche | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| additionalProperties: {} | |
| description: '' | |
| /api/v1/chatbot/api/vendor/send-message/: | |
| post: | |
| operationId: v1_chatbot_api_vendor_send_message_create | |
| description: Send vendor message and get chatbot response | |
| summary: Send message to chatbot | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/SendMessageRequestRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/SendMessageRequestRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/SendMessageRequestRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/SendMessageResponse' | |
| description: '' | |
| /api/v1/chatbot/api/vendor/start-session/: | |
| post: | |
| operationId: v1_chatbot_api_vendor_start_session_create | |
| description: Initialize or get active chatbot session for vendor | |
| summary: Start vendor chatbot session | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/StartSessionResponse' | |
| description: '' | |
| /api/v1/chatbot/api/vendor/tailoring-guideline/: | |
| get: | |
| operationId: v1_chatbot_api_vendor_tailoring_guideline_retrieve | |
| description: Fetch custom tailoring assembly and pattern details | |
| summary: Get tailoring guideline | |
| parameters: | |
| - in: query | |
| name: condition | |
| schema: | |
| type: string | |
| description: Garment Type | |
| - in: query | |
| name: severity | |
| schema: | |
| type: string | |
| default: moderate | |
| description: Complexity | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| additionalProperties: {} | |
| description: '' | |
| /api/v1/client/addresses/: | |
| get: | |
| operationId: v1_client_addresses_list | |
| description: |- | |
| GET /api/v1/client/addresses/ — list saved addresses | |
| POST /api/v1/client/addresses/ — add new address | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedClientAddressList' | |
| description: '' | |
| post: | |
| operationId: v1_client_addresses_create | |
| description: |- | |
| GET /api/v1/client/addresses/ — list saved addresses | |
| POST /api/v1/client/addresses/ — add new address | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AddressCreateRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AddressCreateRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AddressCreateRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '201': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AddressCreate' | |
| description: '' | |
| /api/v1/client/addresses/{address_id}/: | |
| delete: | |
| operationId: v1_client_addresses_destroy | |
| description: DELETE /api/v1/client/addresses/{id}/ — soft-delete address | |
| parameters: | |
| - in: path | |
| name: address_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/client/addresses/{address_id}/set-default/: | |
| post: | |
| operationId: v1_client_addresses_set_default_create | |
| description: |- | |
| POST /api/v1/client/addresses/{id}/set-default/ | |
| Set a specific address as the default shipping address. | |
| parameters: | |
| - in: path | |
| name: address_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ClientAddressRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/ClientAddressRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/ClientAddressRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ClientAddress' | |
| description: '' | |
| /api/v1/client/orders/: | |
| get: | |
| operationId: v1_client_orders_list | |
| description: |- | |
| GET /api/v1/client/orders/ | |
| Return all paid orders for the authenticated client. | |
| Prefetches orderitems to avoid N+1 on order detail pages. | |
| Returns a list of all successful orders placed by the client. | |
| Validation Logic: | |
| - Filter: Only returns orders where payment_status is 'paid'. | |
| - Ordering: Date-descending (most recent first). | |
| Security: | |
| - Requires IsAuthenticated + IsClient. | |
| Status Codes: | |
| 200 OK: List of orders returned. | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedClientCartOrderList' | |
| description: '' | |
| /api/v1/client/orders/{oid}/: | |
| get: | |
| operationId: v1_client_orders_retrieve | |
| description: |- | |
| GET /api/v1/client/orders/<str:oid>/ | |
| Return detail for a single paid order scoped to this client. | |
| Uses oid (order identifier) — not PK — for public safety. | |
| Status Codes: | |
| 200 OK: Order details returned. | |
| 404 Not Found: Order missing or unauthorized. | |
| parameters: | |
| - in: path | |
| name: oid | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ClientCartOrder' | |
| description: '' | |
| /api/v1/client/profile/: | |
| get: | |
| operationId: v1_client_profile_retrieve | |
| description: |- | |
| GET /api/v1/client/profile/ — retrieve profile | |
| PATCH /api/v1/client/profile/ — update profile | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ClientProfileOutput' | |
| description: '' | |
| put: | |
| operationId: v1_client_profile_update | |
| description: |- | |
| GET /api/v1/client/profile/ — retrieve profile | |
| PATCH /api/v1/client/profile/ — update profile | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ClientProfileUpdateRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/ClientProfileUpdateRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/ClientProfileUpdateRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ClientProfileUpdate' | |
| description: '' | |
| patch: | |
| operationId: v1_client_profile_partial_update | |
| description: |- | |
| GET /api/v1/client/profile/ — retrieve profile | |
| PATCH /api/v1/client/profile/ — update profile | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedClientProfileUpdateRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedClientProfileUpdateRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedClientProfileUpdateRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ClientProfileUpdate' | |
| description: '' | |
| /api/v1/client/reviews/create/: | |
| post: | |
| operationId: v1_client_reviews_create_create | |
| description: |- | |
| POST /api/v1/client/reviews/create/ | |
| Submits a new rating and review for a product. | |
| Validation Logic: | |
| - Payload: Validates product_id presence and rating (1–5 scale). | |
| - Duplication: Enforced at serializer / model level. | |
| Security: | |
| - Requires IsAuthenticated + IsClient. | |
| Status Codes: | |
| 201 Created: Review successfully recorded. | |
| 400 Bad Request: Missing product_id or invalid rating. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ClientReviewRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/ClientReviewRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/ClientReviewRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '201': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ClientReview' | |
| description: '' | |
| /api/v1/client/wallet/balance/: | |
| get: | |
| operationId: v1_client_wallet_balance_retrieve | |
| description: |- | |
| GET /api/v1/client/wallet/balance/ | |
| Retrieves the authenticated client's current Fashionistar wallet balance. | |
| Auto-provisions a wallet via WalletProvisioningService if none exists. | |
| Security: IsAuthenticated + IsClient | |
| Status: 200 OK — balance data returned. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Wallet' | |
| description: '' | |
| /api/v1/client/wallet/topup/initiate/: | |
| post: | |
| operationId: v1_client_wallet_topup_initiate_create | |
| description: |- | |
| POST /api/v1/client/wallet/topup/initiate/ | |
| Initiates a Paystack wallet top-up payment intent. | |
| Returns a payment_url the client redirects to for card payment. | |
| Body: | |
| { | |
| "amount": 5000, // NGN amount (number) | |
| "payment_method": "card", // card | bank_transfer | |
| "callback_url": "https://.../verify" // optional redirect URL | |
| } | |
| Response (200): | |
| { | |
| "status": "pending", | |
| "payment_url": "https://paystack.com/...", | |
| "reference": "..." | |
| } | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/client/wallet/transfer/: | |
| post: | |
| operationId: v1_client_wallet_transfer_create | |
| description: |- | |
| POST /api/v1/client/wallet/transfer/ | |
| Executes an atomic wallet-to-wallet transfer to another Fashionistar user. | |
| Body: | |
| { | |
| "receiver_id": "<uuid>", | |
| "amount": "500.00", | |
| "transaction_password": "1234" | |
| } | |
| Security: | |
| - Verifies the 4-digit Transaction PIN via WalletBalanceService.transfer(). | |
| - KYC gate enforced in the service (sender must be KYC-approved). | |
| - Idempotency-Key header is forwarded to prevent duplicate transactions. | |
| Status: | |
| 200 OK: Transfer completed. | |
| 400 Bad Request: Insufficient funds, invalid PIN, or validation error. | |
| 404 Not Found: Receiver not found. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WalletTransferRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/WalletTransferRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/WalletTransferRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WalletTransfer' | |
| description: '' | |
| /api/v1/client/wallet/withdraw/: | |
| post: | |
| operationId: v1_client_wallet_withdraw_create | |
| description: |- | |
| POST /api/v1/client/wallet/withdraw/ | |
| Create a KYC-gated, PIN-protected bank withdrawal request. | |
| This is the correct financial-exit endpoint for the WithdrawalForm UI. | |
| It uses WalletWithdrawalService.request_withdrawal() which: | |
| - Asserts the user has an approved KYC submission. | |
| - Verifies the 4-digit transaction PIN. | |
| - Moves funds from available_balance → pending_balance (atomic DB txn). | |
| - Creates an immutable PAYOUT ledger entry (CBN compliance). | |
| - Writes a compliance audit trail (CBN/GDPR permanent retention). | |
| - Supports idempotency via Idempotency-Key header. | |
| Body: | |
| { | |
| "amount": "5000.00", // min ₦1,000 enforced in Zod (frontend) | |
| "pin": "1234", // 4-digit wallet PIN | |
| "bank_code": "057", // Nigerian bank code (e.g. Zenith = "057") | |
| "account_number": "0123456789", // 10-digit NUBAN | |
| "account_name": "Jane Doe" // beneficiary name | |
| } | |
| Response (200): | |
| { | |
| "transaction_id": "<uuid>", | |
| "reference": "wallet-withdrawal:...", | |
| "status": "processing", | |
| "amount": "5000.00", | |
| "available_balance": "15000.00", | |
| "pending_balance": "5000.00" | |
| } | |
| Error Codes: | |
| 400 — Invalid PIN / insufficient balance / validation errors. | |
| 403 — KYC not approved (assert_kyc_approved gate). | |
| 422 — Idempotent duplicate detected (returns existing transaction). | |
| Security: | |
| - IsAuthenticated + IsClient | |
| - KYC approved (enforced by WalletWithdrawalService) | |
| - PIN verified (bcrypt check via wallet.verify_pin()) | |
| - Idempotency-Key prevents double-submission on network retry | |
| CBN Compliance: | |
| - Funds remain in pending_balance until the payment provider confirms | |
| the bank transfer (async execution by Celery payout task). | |
| - The immutable PAYOUT ledger row is created before this response returns. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/client/wishlist/: | |
| get: | |
| operationId: v1_client_wishlist_retrieve | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ClientWishlist' | |
| description: '' | |
| /api/v1/client/wishlist/toggle/: | |
| post: | |
| operationId: v1_client_wishlist_toggle_create | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WishlistToggleRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/WishlistToggleRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/WishlistToggleRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WishlistToggle' | |
| description: '' | |
| /api/v1/common/reference/banks/: | |
| get: | |
| operationId: v1_common_reference_banks_list | |
| description: Returns banks for the specified country. Nigeria defaults to Paystack-backed | |
| bank metadata. | |
| summary: List banks | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedReferenceBankList' | |
| description: '' | |
| /api/v1/common/reference/countries/: | |
| get: | |
| operationId: v1_common_reference_countries_list | |
| description: Returns static supported country metadata for web, admin, and mobile | |
| clients. | |
| summary: List supported countries | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedReferenceCountryList' | |
| description: '' | |
| /api/v1/common/reference/countries/{country_code}/cities/: | |
| get: | |
| operationId: v1_common_reference_countries_cities_list | |
| description: Returns cities for the selected country, optionally filtered by | |
| state and LGA. | |
| summary: List cities for a country | |
| parameters: | |
| - in: path | |
| name: country_code | |
| schema: | |
| type: string | |
| required: true | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedReferenceCityList' | |
| description: '' | |
| /api/v1/common/reference/countries/{country_code}/states/: | |
| get: | |
| operationId: v1_common_reference_countries_states_list | |
| description: Returns states configured for the selected country. | |
| summary: List states for a country | |
| parameters: | |
| - in: path | |
| name: country_code | |
| schema: | |
| type: string | |
| required: true | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedReferenceStateList' | |
| description: '' | |
| /api/v1/common/reference/countries/{country_code}/states/{state_code}/lgas/: | |
| get: | |
| operationId: v1_common_reference_countries_states_lgas_list | |
| description: Returns local government areas for the selected country and state. | |
| summary: List LGAs for a state | |
| parameters: | |
| - in: path | |
| name: country_code | |
| schema: | |
| type: string | |
| required: true | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| - in: path | |
| name: state_code | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedReferenceLgaList' | |
| description: '' | |
| /api/v1/common/reference/countries/{country_code}/states/{state_code}/lgas/{lga_code}/cities/: | |
| get: | |
| operationId: v1_common_reference_countries_states_lgas_cities_list | |
| description: Returns cities for the selected country, state, and LGA. | |
| summary: List cities in an LGA | |
| parameters: | |
| - in: path | |
| name: country_code | |
| schema: | |
| type: string | |
| required: true | |
| - in: path | |
| name: lga_code | |
| schema: | |
| type: string | |
| required: true | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| - in: path | |
| name: state_code | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedReferenceCityList' | |
| description: '' | |
| /api/v1/integrations/ai/generate/: | |
| post: | |
| operationId: v1_integrations_ai_generate_create | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/integrations/credentials/: | |
| get: | |
| operationId: v1_integrations_credentials_list | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedIntegrationCredentialList' | |
| description: '' | |
| post: | |
| operationId: v1_integrations_credentials_create | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredentialRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredentialRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredentialRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '201': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredential' | |
| description: '' | |
| /api/v1/integrations/credentials/{id}/: | |
| get: | |
| operationId: v1_integrations_credentials_retrieve | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Integration Credential. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredential' | |
| description: '' | |
| put: | |
| operationId: v1_integrations_credentials_update | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Integration Credential. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredentialRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredentialRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredentialRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredential' | |
| description: '' | |
| patch: | |
| operationId: v1_integrations_credentials_partial_update | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Integration Credential. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedIntegrationCredentialRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedIntegrationCredentialRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedIntegrationCredentialRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredential' | |
| description: '' | |
| delete: | |
| operationId: v1_integrations_credentials_destroy | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Integration Credential. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/integrations/credentials/{id}/rotate/: | |
| post: | |
| operationId: v1_integrations_credentials_rotate_create | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Integration Credential. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredentialRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredentialRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredentialRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationCredential' | |
| description: '' | |
| /api/v1/integrations/logs/: | |
| get: | |
| operationId: v1_integrations_logs_list | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedIntegrationLogList' | |
| description: '' | |
| /api/v1/integrations/logs/{id}/: | |
| get: | |
| operationId: v1_integrations_logs_retrieve | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Integration Log. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationLog' | |
| description: '' | |
| /api/v1/integrations/providers/: | |
| get: | |
| operationId: v1_integrations_providers_list | |
| description: ViewSet for managing external Integration Providers. | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedIntegrationProviderList' | |
| description: '' | |
| post: | |
| operationId: v1_integrations_providers_create | |
| description: ViewSet for managing external Integration Providers. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationProviderRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationProviderRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationProviderRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '201': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationProvider' | |
| description: '' | |
| /api/v1/integrations/providers/{slug}/: | |
| get: | |
| operationId: v1_integrations_providers_retrieve | |
| description: ViewSet for managing external Integration Providers. | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| title: Unique Slug | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationProvider' | |
| description: '' | |
| put: | |
| operationId: v1_integrations_providers_update | |
| description: ViewSet for managing external Integration Providers. | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| title: Unique Slug | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationProviderRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationProviderRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationProviderRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationProvider' | |
| description: '' | |
| patch: | |
| operationId: v1_integrations_providers_partial_update | |
| description: ViewSet for managing external Integration Providers. | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| title: Unique Slug | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedIntegrationProviderRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedIntegrationProviderRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedIntegrationProviderRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationProvider' | |
| description: '' | |
| delete: | |
| operationId: v1_integrations_providers_destroy | |
| description: ViewSet for managing external Integration Providers. | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| title: Unique Slug | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/integrations/providers/{slug}/health_check/: | |
| get: | |
| operationId: v1_integrations_providers_health_check_retrieve | |
| description: ViewSet for managing external Integration Providers. | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| title: Unique Slug | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationProvider' | |
| description: '' | |
| /api/v1/integrations/providers/{slug}/statistics/: | |
| get: | |
| operationId: v1_integrations_providers_statistics_retrieve | |
| description: ViewSet for managing external Integration Providers. | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| title: Unique Slug | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/IntegrationProvider' | |
| description: '' | |
| /api/v1/integrations/rate-limits/: | |
| get: | |
| operationId: v1_integrations_rate_limits_list | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedRateLimitRuleList' | |
| description: '' | |
| post: | |
| operationId: v1_integrations_rate_limits_create | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/RateLimitRuleRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/RateLimitRuleRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/RateLimitRuleRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '201': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/RateLimitRule' | |
| description: '' | |
| /api/v1/integrations/rate-limits/{id}/: | |
| get: | |
| operationId: v1_integrations_rate_limits_retrieve | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Rate Limit Rule. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/RateLimitRule' | |
| description: '' | |
| put: | |
| operationId: v1_integrations_rate_limits_update | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Rate Limit Rule. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/RateLimitRuleRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/RateLimitRuleRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/RateLimitRuleRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/RateLimitRule' | |
| description: '' | |
| patch: | |
| operationId: v1_integrations_rate_limits_partial_update | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Rate Limit Rule. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedRateLimitRuleRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedRateLimitRuleRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedRateLimitRuleRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/RateLimitRule' | |
| description: '' | |
| delete: | |
| operationId: v1_integrations_rate_limits_destroy | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Rate Limit Rule. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/integrations/sms/send/: | |
| post: | |
| operationId: v1_integrations_sms_send_create | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/integrations/webhook-events/: | |
| get: | |
| operationId: v1_integrations_webhook_events_list | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedWebhookEventList' | |
| description: '' | |
| /api/v1/integrations/webhook-events/{id}/: | |
| get: | |
| operationId: v1_integrations_webhook_events_retrieve | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Webhook Event. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEvent' | |
| description: '' | |
| /api/v1/integrations/webhook-events/{id}/retry/: | |
| post: | |
| operationId: v1_integrations_webhook_events_retry_create | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Webhook Event. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEventRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEventRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEventRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEvent' | |
| description: '' | |
| /api/v1/integrations/webhook/{endpoint_url}/: | |
| post: | |
| operationId: v1_integrations_webhook_create | |
| parameters: | |
| - in: path | |
| name: endpoint_url | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/integrations/webhooks/: | |
| get: | |
| operationId: v1_integrations_webhooks_list | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedWebhookEndpointList' | |
| description: '' | |
| post: | |
| operationId: v1_integrations_webhooks_create | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpointRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpointRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpointRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '201': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpoint' | |
| description: '' | |
| /api/v1/integrations/webhooks/{id}/: | |
| get: | |
| operationId: v1_integrations_webhooks_retrieve | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Webhook Endpoint. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpoint' | |
| description: '' | |
| put: | |
| operationId: v1_integrations_webhooks_update | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Webhook Endpoint. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpointRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpointRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpointRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpoint' | |
| description: '' | |
| patch: | |
| operationId: v1_integrations_webhooks_partial_update | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Webhook Endpoint. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedWebhookEndpointRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedWebhookEndpointRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedWebhookEndpointRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpoint' | |
| description: '' | |
| delete: | |
| operationId: v1_integrations_webhooks_destroy | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Webhook Endpoint. | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/integrations/webhooks/{id}/test/: | |
| post: | |
| operationId: v1_integrations_webhooks_test_create | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| description: A UUID string identifying this Webhook Endpoint. | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpointRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpointRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpointRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WebhookEndpoint' | |
| description: '' | |
| /api/v1/kyc/admin/{submission_id}/approve/: | |
| post: | |
| operationId: v1_kyc_admin_approve_create | |
| description: |- | |
| POST /api/v1/kyc/admin/<submission_id>/approve/ | |
| Staff action: approve a KYC submission. | |
| Side effects: | |
| - Sets submission.status = APPROVED. | |
| - Sets VendorSetupState.id_verified = True (if user is a vendor). | |
| - Sends approval notification to the user. | |
| Body (optional): | |
| { "provider_reference": "smile_identity_job_123" } | |
| parameters: | |
| - in: path | |
| name: submission_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/kyc/admin/{submission_id}/reject/: | |
| post: | |
| operationId: v1_kyc_admin_reject_create | |
| description: |- | |
| POST /api/v1/kyc/admin/<submission_id>/reject/ | |
| Staff action: reject a KYC submission with review notes. | |
| Body: | |
| { | |
| "review_notes": "NIN document is blurry. Please resubmit a clearer photo.", | |
| "allow_resubmit": true | |
| } | |
| parameters: | |
| - in: path | |
| name: submission_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/kyc/admin/submissions/: | |
| get: | |
| operationId: v1_kyc_admin_submissions_list | |
| description: |- | |
| GET /api/v1/kyc/admin/submissions/ | |
| Staff-only endpoint to list all KYC submissions with users and documents. | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedKycSubmissionList' | |
| description: '' | |
| /api/v1/kyc/documents/upload/: | |
| post: | |
| operationId: v1_kyc_documents_upload_create | |
| description: |- | |
| POST /api/v1/kyc/documents/upload/ | |
| Record a KYC document Cloudinary upload against the user's active submission. | |
| Documents must be uploaded client-side to Cloudinary first using a | |
| presigned token from GET /api/v1/common/cloudinary/presign/?preset=kyc_docs. | |
| This endpoint records the resulting Cloudinary asset reference. | |
| Body: | |
| { | |
| "document_type": "nin_card", | |
| "document_number": "12345678901", | |
| "secure_url": "https://res.cloudinary.com/.../...", | |
| "public_id": "fashionistar/kyc/<user_id>/..." | |
| } | |
| Idempotent per (submission, document_type): re-uploading the same | |
| document type updates the existing record. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/kyc/status/: | |
| get: | |
| operationId: v1_kyc_status_retrieve | |
| description: |- | |
| GET /api/v1/kyc/status/ | |
| Returns the authenticated user's KYC submission with all documents. | |
| Delegates to get_kyc_submission_for_user selector (prefetch_related). | |
| Returns 200 with status='not_started' if no submission exists. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/kyc/submit/: | |
| post: | |
| operationId: v1_kyc_submit_create | |
| description: |- | |
| POST /api/v1/kyc/submit/ | |
| Initiate or reopen a KYC submission. | |
| - If no submission exists → creates PENDING submission. | |
| - If submission is REJECTED / RESUBMIT → resets to PENDING. | |
| - If submission is APPROVED / PENDING / IN_REVIEW → returns current state (idempotent). | |
| Body (optional): | |
| { "nin": "12345678901", "bvn": "12345678901" } | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/kyc/webhook/{provider_slug}/: | |
| post: | |
| operationId: v1_kyc_webhook_create | |
| description: |- | |
| Receive and process inbound KYC provider webhook callbacks. | |
| Workflow: | |
| 1. Extract provider_slug from URL. | |
| 2. Load KYCProviderConfig from cache. | |
| 3. Validate HMAC signature using provider's signing secret. | |
| 4. Dispatch to KycService.reconcile_webhook() for idempotent reconciliation. | |
| 5. Audit-log the outcome (compliance=True, 7-year retention). | |
| 6. Return HTTP 200 immediately (provider expects fast acknowledgement). | |
| parameters: | |
| - in: path | |
| name: provider_slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/measurements/: | |
| get: | |
| operationId: v1_measurements_retrieve | |
| description: |- | |
| GET /api/v1/measurements/ — List all profiles for the authenticated user. | |
| POST /api/v1/measurements/ — Create a new measurement profile. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| post: | |
| operationId: v1_measurements_create | |
| description: |- | |
| GET /api/v1/measurements/ — List all profiles for the authenticated user. | |
| POST /api/v1/measurements/ — Create a new measurement profile. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/measurements/{profile_id}/: | |
| get: | |
| operationId: v1_measurements_retrieve_2 | |
| description: |- | |
| GET /api/v1/measurements/<id>/ | |
| PUT /api/v1/measurements/<id>/ | |
| PATCH /api/v1/measurements/<id>/ | |
| DELETE /api/v1/measurements/<id>/ | |
| parameters: | |
| - in: path | |
| name: profile_id | |
| schema: | |
| type: integer | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| put: | |
| operationId: v1_measurements_update | |
| description: |- | |
| GET /api/v1/measurements/<id>/ | |
| PUT /api/v1/measurements/<id>/ | |
| PATCH /api/v1/measurements/<id>/ | |
| DELETE /api/v1/measurements/<id>/ | |
| parameters: | |
| - in: path | |
| name: profile_id | |
| schema: | |
| type: integer | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| patch: | |
| operationId: v1_measurements_partial_update | |
| description: |- | |
| GET /api/v1/measurements/<id>/ | |
| PUT /api/v1/measurements/<id>/ | |
| PATCH /api/v1/measurements/<id>/ | |
| DELETE /api/v1/measurements/<id>/ | |
| parameters: | |
| - in: path | |
| name: profile_id | |
| schema: | |
| type: integer | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| delete: | |
| operationId: v1_measurements_destroy | |
| description: |- | |
| GET /api/v1/measurements/<id>/ | |
| PUT /api/v1/measurements/<id>/ | |
| PATCH /api/v1/measurements/<id>/ | |
| DELETE /api/v1/measurements/<id>/ | |
| parameters: | |
| - in: path | |
| name: profile_id | |
| schema: | |
| type: integer | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/measurements/{profile_id}/set-default/: | |
| post: | |
| operationId: v1_measurements_set_default_create | |
| description: POST /api/v1/measurements/<id>/set-default/ | |
| parameters: | |
| - in: path | |
| name: profile_id | |
| schema: | |
| type: integer | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/measurements/scan/{session_id}/submit-landmarks/: | |
| post: | |
| operationId: v1_measurements_scan_submit_landmarks_create | |
| description: |- | |
| POST /api/v1/measurements/scan/<session_id>/submit-landmarks/ | |
| Accepts MediaPipe world-coordinate landmarks from the browser. | |
| Fires the process_body_scan Celery task and returns immediately. | |
| Frontend should poll: | |
| GET /api/v1/ninja/measurements/scan/<session_id>/status/ | |
| until status = 'completed' or 'failed'. | |
| Expected body: | |
| { | |
| "user_height_cm": 175.5, | |
| "user_weight_kg": 70.0, // optional | |
| "landmarks": [<33 landmark objects>] | |
| } | |
| Success response (202 Accepted): | |
| { | |
| "session_id": "...", | |
| "status": "processing", | |
| "message": "Scan submitted. Processing in progress..." | |
| } | |
| parameters: | |
| - in: path | |
| name: session_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/measurements/scan/initiate/: | |
| post: | |
| operationId: v1_measurements_scan_initiate_create | |
| description: |- | |
| POST /api/v1/measurements/scan/initiate/ | |
| Creates a BodyScanSession with status=PENDING. | |
| Returns session_id — the frontend uses this to: | |
| 1. Display a "session ready" indicator to the user | |
| 2. Submit landmark data via SubmitLandmarksView | |
| 3. Poll Ninja API for processing status | |
| No body required. Optionally accepts: | |
| { "device_type": "web" | "ios" | "android" } | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/notifications/: | |
| get: | |
| operationId: v1_notifications_retrieve | |
| description: |- | |
| GET /api/v1/notifications/ | |
| Returns the authenticated user's in-app notification feed. | |
| Supports ?unread_only=true to filter unread. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/notifications/{notification_id}/: | |
| get: | |
| operationId: v1_notifications_retrieve_2 | |
| description: |- | |
| GET /api/v1/notifications/<id>/ | |
| Returns a single notification without mutating read state. | |
| parameters: | |
| - in: path | |
| name: notification_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/notifications/mark-all-read/: | |
| post: | |
| operationId: v1_notifications_mark_all_read_create | |
| description: POST /api/v1/notifications/mark-all-read/ | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/notifications/mark-read/{notification_id}/: | |
| post: | |
| operationId: v1_notifications_mark_read_create | |
| description: POST /api/v1/notifications/mark-read/<id>/ | |
| parameters: | |
| - in: path | |
| name: notification_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/notifications/preferences/: | |
| get: | |
| operationId: v1_notifications_preferences_retrieve | |
| description: |- | |
| GET /api/v1/notifications/preferences/ — List current preferences | |
| POST /api/v1/notifications/preferences/ — Set/update a preference | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| post: | |
| operationId: v1_notifications_preferences_create | |
| description: |- | |
| GET /api/v1/notifications/preferences/ — List current preferences | |
| POST /api/v1/notifications/preferences/ — Set/update a preference | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/notifications/unread-count/: | |
| get: | |
| operationId: v1_notifications_unread_count_retrieve | |
| description: GET /api/v1/notifications/unread-count/ | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/orders/: | |
| get: | |
| operationId: v1_orders_retrieve | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/orders/{order_id}/: | |
| get: | |
| operationId: v1_orders_retrieve_2 | |
| parameters: | |
| - in: path | |
| name: order_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/orders/{order_id}/cancel/: | |
| post: | |
| operationId: v1_orders_cancel_create | |
| parameters: | |
| - in: path | |
| name: order_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/orders/{order_id}/confirm-delivery/: | |
| post: | |
| operationId: v1_orders_confirm_delivery_create | |
| description: Client confirms delivery → releases escrow. | |
| parameters: | |
| - in: path | |
| name: order_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/orders/admin/{order_id}/delivery-status/: | |
| patch: | |
| operationId: v1_orders_admin_delivery_status_partial_update | |
| description: |- | |
| Admin/staff delivery-status update endpoint. | |
| This is a DRF sync mutation because it changes order state and may trigger | |
| later escrow/provider reconciliation. The service performs the row lock; | |
| the view only validates input, checks high-trust staff access, and returns | |
| the serialized order. | |
| parameters: | |
| - in: path | |
| name: order_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/orders/place/: | |
| post: | |
| operationId: v1_orders_place_create | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/orders/vendor/: | |
| get: | |
| operationId: v1_orders_vendor_retrieve | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/orders/vendor/{order_id}/: | |
| get: | |
| operationId: v1_orders_vendor_retrieve_2 | |
| parameters: | |
| - in: path | |
| name: order_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/orders/vendor/{order_id}/production-status/: | |
| post: | |
| operationId: v1_orders_vendor_production_status_create | |
| parameters: | |
| - in: path | |
| name: order_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| patch: | |
| operationId: v1_orders_vendor_production_status_partial_update | |
| description: PATCH alias used by the frontend production-status mutation. | |
| parameters: | |
| - in: path | |
| name: order_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/orders/vendor/{order_id}/transition/: | |
| post: | |
| operationId: v1_orders_vendor_transition_create | |
| parameters: | |
| - in: path | |
| name: order_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| patch: | |
| operationId: v1_orders_vendor_transition_partial_update | |
| description: PATCH alias used by the frontend production-status mutation. | |
| parameters: | |
| - in: path | |
| name: order_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/orders/verify-pickup/: | |
| put: | |
| operationId: v1_orders_verify_pickup_update | |
| description: Verify order pickup token, release escrow, and transition to Completed | |
| status. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/password/change/: | |
| post: | |
| operationId: v1_password_change_create | |
| description: |- | |
| Authenticates current password and updates to a new one. | |
| Args: | |
| request (Request): The DRF request with old and new passwords. | |
| Returns: | |
| Response: Success confirmation or detailed error. | |
| tags: | |
| - Authentication | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PasswordChangeRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PasswordChangeRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PasswordChangeRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/password/reset-confirm/{uidb64}/{token}/: | |
| post: | |
| operationId: v1_password_reset_confirm_create | |
| description: |- | |
| Updates the user's password if the token and uidb64 are valid. | |
| Args: | |
| request (Request): The DRF request containing the new password. | |
| uidb64 (str): Base64 encoded user ID from the URL. | |
| token (str): One-time use token from the URL. | |
| Returns: | |
| Response: Success confirmation or a 400 Bad Request if validation fails. | |
| parameters: | |
| - in: path | |
| name: token | |
| schema: | |
| type: string | |
| required: true | |
| - in: path | |
| name: uidb64 | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - Authentication | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthPasswordResetConfirmEmailRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AuthPasswordResetConfirmEmailRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AuthPasswordResetConfirmEmailRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/password/reset-phone-confirm/: | |
| post: | |
| operationId: v1_password_reset_phone_confirm_create | |
| description: |- | |
| Verifies the OTP and updates the user's password. | |
| Args: | |
| request (Request): The DRF request containing OTP and new password. | |
| Returns: | |
| Response: Success confirmation or a 400 Bad Request if verification fails. | |
| tags: | |
| - Authentication | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthPasswordResetConfirmPhoneRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AuthPasswordResetConfirmPhoneRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AuthPasswordResetConfirmPhoneRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthPasswordResetConfirmPhone' | |
| description: '' | |
| /api/v1/password/reset-request/: | |
| post: | |
| operationId: v1_password_reset_request_create | |
| description: |- | |
| Processes the reset request and triggers background notification. | |
| Args: | |
| request (Request): The incoming DRF request object. | |
| Returns: | |
| Response: A standardized success response, regardless of account existence. | |
| tags: | |
| - Authentication | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthPasswordResetRequestRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AuthPasswordResetRequestRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AuthPasswordResetRequestRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/payment/banks/: | |
| get: | |
| operationId: v1_payment_banks_retrieve | |
| description: |- | |
| Retrieves the list of supported Nigerian banks for transfers. | |
| Flow: | |
| 1. Query Paystack Banks list endpoint. | |
| 2. Filter or format as needed. | |
| 3. Return to frontend for bank selection in withdrawal flows. | |
| Status Codes: | |
| 200 OK: Returns list of banks. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaystackBanksResponse' | |
| description: '' | |
| /api/v1/payment/cash/confirm/: | |
| post: | |
| operationId: v1_payment_cash_confirm_create | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CashConfirmationConfirmRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CashConfirmationConfirmRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CashConfirmationConfirmRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CashConfirmationConfirm' | |
| description: '' | |
| /api/v1/payment/cash/create/: | |
| post: | |
| operationId: v1_payment_cash_create_create | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CashConfirmationCreateRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CashConfirmationCreateRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CashConfirmationCreateRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CashConfirmationCreate' | |
| description: '' | |
| /api/v1/payment/cash/resend-token/: | |
| post: | |
| operationId: v1_payment_cash_resend_token_create | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CashConfirmationResendRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CashConfirmationResendRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CashConfirmationResendRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CashConfirmationResend' | |
| description: '' | |
| /api/v1/payment/paystack/initialize/: | |
| post: | |
| operationId: v1_payment_paystack_initialize_create | |
| description: |- | |
| Initializes a Paystack transaction and creates a PaymentIntent record. | |
| Flow: | |
| 1. Receive amount and metadata from frontend. | |
| 2. Check idempotency to prevent double-charging. | |
| 3. Call Paystack API to get an authorization URL. | |
| 4. Store the reference and link it to the current User. | |
| Status Codes: | |
| 201 Created: Initialization successful, returns Paystack URL. | |
| 400 Bad Request: Invalid payload or Paystack provider error. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaystackInitializeRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PaystackInitializeRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PaystackInitializeRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaystackInitialize' | |
| description: '' | |
| /api/v1/payment/paystack/verify/{reference}/: | |
| get: | |
| operationId: v1_payment_paystack_verify_retrieve | |
| description: |- | |
| Verifies the status of a specific Paystack transaction reference. | |
| Flow: | |
| 1. Frontend provides the reference after user payment. | |
| 2. Backend queries Paystack Verify API. | |
| 3. If success, updates PaymentIntent and associated Wallet/Order. | |
| 4. Returns final state to the frontend. | |
| Status Codes: | |
| 200 OK: Payment confirmed and processed. | |
| 400 Bad Request: Payment failed or reference not found. | |
| parameters: | |
| - in: path | |
| name: reference | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaystackVerify' | |
| description: '' | |
| /api/v1/payment/paystack/webhook/: | |
| post: | |
| operationId: v1_payment_paystack_webhook_create | |
| description: |- | |
| Asynchronous handler for Paystack webhook notifications. | |
| Flow: | |
| 1. Paystack sends a signed POST request. | |
| 2. Verify signature using environment secret. | |
| 3. Process the event (charge.success, transfer.success, etc.). | |
| 4. Ensure idempotency via reference tracking. | |
| Status Codes: | |
| 200 OK: Webhook accepted. | |
| 401 Unauthorized: Invalid signature. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaystackWebhookRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PaystackWebhookRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PaystackWebhookRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaystackWebhook' | |
| description: '' | |
| /api/v1/payment/transfer-recipient/: | |
| post: | |
| operationId: v1_payment_transfer_recipient_create | |
| description: |- | |
| Creates a Transfer Recipient on Paystack for withdrawals. | |
| Flow: | |
| 1. User provides bank code and account number. | |
| 2. Backend calls Paystack to create a recipient. | |
| 3. Store the recipient code for future transfer operations. | |
| Status Codes: | |
| 201 Created: Recipient successfully registered. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/TransferRecipientCreateRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/TransferRecipientCreateRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/TransferRecipientCreateRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/TransferRecipientCreate' | |
| description: '' | |
| /api/v1/payment/wallet/fund/: | |
| post: | |
| operationId: v1_payment_wallet_fund_create | |
| description: Shared order-payment and wallet-topup entrypoint. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WalletFundPaymentRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/WalletFundPaymentRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/WalletFundPaymentRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WalletFundPayment' | |
| description: '' | |
| /api/v1/platform/settings/public/: | |
| get: | |
| operationId: v1_platform_settings_public_retrieve | |
| description: |- | |
| GET /api/v1/platform/settings/public/ | |
| Returns public-safe platform configuration values for frontend use. | |
| Does NOT require authentication — these are public limits and branding. | |
| Response is backed by Redis (60s TTL) so it is cheap to call on every | |
| payout modal open. | |
| Response schema: | |
| { | |
| "platform_name": "Fashionistar", | |
| "min_withdrawal_ngn": "1000.00", | |
| "max_withdrawal_ngn": "2000000.00", | |
| "max_daily_withdrawal_ngn": "5000000.00", | |
| "min_wallet_topup_ngn": "500.00", | |
| "max_wallet_topup_ngn": "5000000.00", | |
| "support_email": "support@fashionistar.net", | |
| "support_phone": "+234 913 7654 300", | |
| "terms_url": "https://fashionistar.net/terms", | |
| "privacy_url": "https://fashionistar.net/privacy" | |
| } | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/: | |
| get: | |
| operationId: v1_products_retrieve | |
| description: |- | |
| GET /api/v1/products/ | |
| Public. Query params: | |
| q, category, brand, vendor, min_price, max_price, | |
| in_stock, featured, ordering, page, page_size | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/{product_slug}/reviews/: | |
| get: | |
| operationId: v1_products_reviews_retrieve | |
| description: |- | |
| GET /api/v1/products/<product_slug>/reviews/ — Public list (paginated). | |
| POST /api/v1/products/<product_slug>/reviews/ — Authenticated client submission. | |
| parameters: | |
| - in: path | |
| name: product_slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| post: | |
| operationId: v1_products_reviews_create | |
| description: |- | |
| GET /api/v1/products/<product_slug>/reviews/ — Public list (paginated). | |
| POST /api/v1/products/<product_slug>/reviews/ — Authenticated client submission. | |
| parameters: | |
| - in: path | |
| name: product_slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/{slug}/: | |
| get: | |
| operationId: v1_products_retrieve_2 | |
| description: GET /api/v1/products/<slug>/ — Public. Includes ETag cache headers. | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/{slug}/wishlist/toggle/: | |
| post: | |
| operationId: v1_products_wishlist_toggle_create_2 | |
| description: POST /api/v1/products/wishlist/<slug>/toggle/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/admin/{slug}/approve/: | |
| post: | |
| operationId: v1_products_admin_approve_create | |
| description: POST /api/v1/admin/products/<slug>/approve/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/admin/{slug}/reject/: | |
| post: | |
| operationId: v1_products_admin_reject_create | |
| description: POST /api/v1/admin/products/<slug>/reject/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/category/{category_id}/: | |
| get: | |
| operationId: v1_products_category_retrieve | |
| description: GET /api/v1/products/category/<category_id>/ — Public. | |
| parameters: | |
| - in: path | |
| name: category_id | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/commission-snapshots/: | |
| get: | |
| operationId: v1_products_commission_snapshots_retrieve | |
| description: |- | |
| Return commission snapshot list with optional filters. | |
| Query params: | |
| product_id (str): Filter by product. | |
| vendor_id (str): Filter by vendor (via product). | |
| Args: | |
| request: DRF request. | |
| Returns: | |
| 200 success_response with list of snapshot dicts. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| post: | |
| operationId: v1_products_commission_snapshots_create | |
| description: |- | |
| Create a new commission snapshot for a product. | |
| Commission snapshots are append-only. To change a rate, create a new | |
| snapshot with the updated commission_rate and a new effective_from date. | |
| Args: | |
| request: DRF request with JSON body containing: | |
| product_id (str, required): Product UUID. | |
| commission_rate (str/Decimal, required): Rate as decimal (e.g. "12.50"). | |
| effective_from (str, required): ISO 8601 datetime string. | |
| effective_to (str, optional): ISO 8601 end date. | |
| note (str, optional): Reason / notes for this rate change. | |
| Returns: | |
| 201 success_response with snapshot id. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/commission-snapshots/{id}/: | |
| get: | |
| operationId: v1_products_commission_snapshots_retrieve_2 | |
| description: Return a single commission snapshot row. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| patch: | |
| operationId: v1_products_commission_snapshots_partial_update | |
| description: |- | |
| Update mutable fields: note and effective_to only. | |
| Commission rate changes must create a new snapshot row (append-only policy). | |
| Args: | |
| request: DRF request with partial JSON body. | |
| pk: Snapshot PK string. | |
| Returns: | |
| 200 success_response or error. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/coupons/: | |
| get: | |
| operationId: v1_products_coupons_retrieve | |
| description: |- | |
| GET /api/v1/products/coupons/ | |
| POST /api/v1/products/coupons/ | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| post: | |
| operationId: v1_products_coupons_create | |
| description: |- | |
| GET /api/v1/products/coupons/ | |
| POST /api/v1/products/coupons/ | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/coupons/{coupon_id}/: | |
| delete: | |
| operationId: v1_products_coupons_destroy | |
| description: DELETE /api/v1/products/coupons/<uuid:coupon_id>/ | |
| parameters: | |
| - in: path | |
| name: coupon_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/products/featured/: | |
| get: | |
| operationId: v1_products_featured_retrieve | |
| description: GET /api/v1/products/featured/ — Public. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/shipping-profiles/: | |
| get: | |
| operationId: v1_products_shipping_profiles_retrieve | |
| description: |- | |
| Return shipping profile list scoped by caller role. | |
| Args: | |
| request: DRF request. | |
| Returns: | |
| 200 success_response with list of profile dicts. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| post: | |
| operationId: v1_products_shipping_profiles_create | |
| description: |- | |
| Create a new shipping profile for the calling vendor. | |
| Args: | |
| request: DRF request with JSON body. | |
| Returns: | |
| 201 success_response with created profile id. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/shipping-profiles/{id}/: | |
| get: | |
| operationId: v1_products_shipping_profiles_retrieve_2 | |
| description: Return a single shipping profile. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| patch: | |
| operationId: v1_products_shipping_profiles_partial_update | |
| description: Partially update a shipping profile. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/size-guides/: | |
| get: | |
| operationId: v1_products_size_guides_retrieve | |
| description: |- | |
| Return size guide list scoped by role. | |
| Args: | |
| request: DRF request with authenticated user. | |
| Returns: | |
| 200 success_response with list of guide dicts. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| post: | |
| operationId: v1_products_size_guides_create | |
| description: |- | |
| Create a new size guide template. | |
| Args: | |
| request: DRF request with JSON body. | |
| Returns: | |
| 201 success_response with created guide id. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/size-guides/{id}/: | |
| get: | |
| operationId: v1_products_size_guides_retrieve_2 | |
| description: Return a single size guide row. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| patch: | |
| operationId: v1_products_size_guides_partial_update | |
| description: Partially update a size guide template. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| delete: | |
| operationId: v1_products_size_guides_destroy | |
| description: Soft-delete a size guide template. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/products/vendor/: | |
| get: | |
| operationId: v1_products_vendor_retrieve | |
| description: |- | |
| GET /api/v1/products/vendor/ — List vendor's own products (paginated). | |
| POST /api/v1/products/vendor/ — Create product (idempotency key supported). | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| post: | |
| operationId: v1_products_vendor_create | |
| description: |- | |
| GET /api/v1/products/vendor/ — List vendor's own products (paginated). | |
| POST /api/v1/products/vendor/ — Create product (idempotency key supported). | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/vendor/{slug}/: | |
| get: | |
| operationId: v1_products_vendor_retrieve_2 | |
| description: |- | |
| GET /api/v1/products/vendor/<slug>/ | |
| PATCH /api/v1/products/vendor/<slug>/ | |
| DELETE /api/v1/products/vendor/<slug>/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| patch: | |
| operationId: v1_products_vendor_partial_update | |
| description: |- | |
| GET /api/v1/products/vendor/<slug>/ | |
| PATCH /api/v1/products/vendor/<slug>/ | |
| DELETE /api/v1/products/vendor/<slug>/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| delete: | |
| operationId: v1_products_vendor_destroy | |
| description: |- | |
| GET /api/v1/products/vendor/<slug>/ | |
| PATCH /api/v1/products/vendor/<slug>/ | |
| DELETE /api/v1/products/vendor/<slug>/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/products/vendor/{slug}/inventory/: | |
| get: | |
| operationId: v1_products_vendor_inventory_retrieve | |
| description: |- | |
| GET /api/v1/products/vendor/<slug>/inventory/ | |
| POST /api/v1/products/vendor/<slug>/inventory/ — Manual stock adjustment | |
| Best-practice #5: dedicated inventory log endpoint. | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| post: | |
| operationId: v1_products_vendor_inventory_create | |
| description: |- | |
| GET /api/v1/products/vendor/<slug>/inventory/ | |
| POST /api/v1/products/vendor/<slug>/inventory/ — Manual stock adjustment | |
| Best-practice #5: dedicated inventory log endpoint. | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/vendor/{slug}/media/: | |
| get: | |
| operationId: v1_products_vendor_media_retrieve | |
| description: |- | |
| GET /api/v1/products/vendor/<slug>/media/ | |
| POST /api/v1/products/vendor/<slug>/media/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| post: | |
| operationId: v1_products_vendor_media_create | |
| description: |- | |
| GET /api/v1/products/vendor/<slug>/media/ | |
| POST /api/v1/products/vendor/<slug>/media/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/vendor/{slug}/media/{gid}/: | |
| delete: | |
| operationId: v1_products_vendor_media_destroy | |
| description: DELETE /api/v1/products/vendor/<slug>/media/<gid>/ | |
| parameters: | |
| - in: path | |
| name: gid | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/products/vendor/{slug}/publish/: | |
| post: | |
| operationId: v1_products_vendor_publish_create | |
| description: POST /api/v1/products/vendor/<slug>/publish/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/vendor/reviews/{review_id}/reply/: | |
| post: | |
| operationId: v1_products_vendor_reviews_reply_create | |
| description: POST /api/v1/products/vendor/reviews/<review_id>/reply/ | |
| parameters: | |
| - in: path | |
| name: review_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/wishlist/: | |
| get: | |
| operationId: v1_products_wishlist_retrieve | |
| description: GET /api/v1/products/wishlist/ — Full wishlist with embedded products. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/wishlist/{slug}/toggle/: | |
| post: | |
| operationId: v1_products_wishlist_toggle_create | |
| description: POST /api/v1/products/wishlist/<slug>/toggle/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/products/wishlist/merge/: | |
| post: | |
| operationId: v1_products_wishlist_merge_create | |
| description: |- | |
| POST /api/v1/products/wishlist/merge/ | |
| Promotes anonymous wishlist rows into the authenticated account after login | |
| and before checkout. The view only resolves request identity; all merge | |
| behavior lives in the product service layer. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/profile/me/: | |
| get: | |
| operationId: v1_profile_me_retrieve | |
| description: |- | |
| GET /api/v1/profile/me/ — Return authenticated user's full profile. | |
| PATCH /api/v1/profile/me/ — Partial update of authenticated user profile. | |
| GET uses: UserProfileSerializer (all readable fields) | |
| PATCH uses: update_user_profile() service (guarded, validated writes) | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthUserProfile' | |
| description: '' | |
| put: | |
| operationId: v1_profile_me_update | |
| description: |- | |
| GET /api/v1/profile/me/ — Return authenticated user's full profile. | |
| PATCH /api/v1/profile/me/ — Partial update of authenticated user profile. | |
| GET uses: UserProfileSerializer (all readable fields) | |
| PATCH uses: update_user_profile() service (guarded, validated writes) | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthUserProfileRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/AuthUserProfileRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/AuthUserProfileRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthUserProfile' | |
| description: '' | |
| patch: | |
| operationId: v1_profile_me_partial_update | |
| description: |- | |
| GET /api/v1/profile/me/ — Return authenticated user's full profile. | |
| PATCH /api/v1/profile/me/ — Partial update of authenticated user profile. | |
| GET uses: UserProfileSerializer (all readable fields) | |
| PATCH uses: update_user_profile() service (guarded, validated writes) | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedAuthUserProfileRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedAuthUserProfileRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedAuthUserProfileRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/AuthUserProfile' | |
| description: '' | |
| /api/v1/profile/users/: | |
| get: | |
| operationId: v1_profile_users_list | |
| description: |- | |
| GET /api/v1/profile/users/ — Admin-only list of all registered users. | |
| Returns ProtectedUserSerializer shape — no sensitive fields exposed. | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedAuthProtectedUserList' | |
| description: '' | |
| /api/v1/public/contact/: | |
| post: | |
| operationId: v1_public_contact_create | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CommonContactSubmissionRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CommonContactSubmissionRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CommonContactSubmissionRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CommonContactSubmission' | |
| description: '' | |
| /api/v1/public/newsletter/: | |
| post: | |
| operationId: v1_public_newsletter_create | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CommonNewsletterSignupRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CommonNewsletterSignupRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CommonNewsletterSignupRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CommonNewsletterSignup' | |
| description: '' | |
| /api/v1/public/waitlist/: | |
| post: | |
| operationId: v1_public_waitlist_create | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CommonWaitlistSignupRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CommonWaitlistSignupRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CommonWaitlistSignupRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CommonWaitlistSignup' | |
| description: '' | |
| /api/v1/support/admin/queue/: | |
| get: | |
| operationId: v1_support_admin_queue_retrieve | |
| description: |- | |
| GET /api/v1/support/admin/queue/ | |
| Staff-only: full ticket queue (all open tickets, any user). | |
| Supports ?status=&priority= filters. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/support/tickets/: | |
| get: | |
| operationId: v1_support_tickets_retrieve | |
| description: |- | |
| GET /api/v1/support/tickets/ — Return authenticated user's ticket feed. | |
| POST /api/v1/support/tickets/ — Open a new ticket (idempotent per order_id). | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| post: | |
| operationId: v1_support_tickets_create | |
| description: |- | |
| GET /api/v1/support/tickets/ — Return authenticated user's ticket feed. | |
| POST /api/v1/support/tickets/ — Open a new ticket (idempotent per order_id). | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/support/tickets/{ticket_id}/: | |
| get: | |
| operationId: v1_support_tickets_retrieve_2 | |
| description: |- | |
| GET /api/v1/support/tickets/<ticket_id>/ | |
| Returns full ticket detail including message thread and escalation. | |
| Scoped to the authenticated user (staff sees all via admin queue). | |
| parameters: | |
| - in: path | |
| name: ticket_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/support/tickets/{ticket_id}/escalate/: | |
| post: | |
| operationId: v1_support_tickets_escalate_create | |
| description: |- | |
| POST /api/v1/support/tickets/<ticket_id>/escalate/ | |
| Staff-only endpoint: create or return a TicketEscalation. | |
| Idempotent — safe to call twice. | |
| parameters: | |
| - in: path | |
| name: ticket_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/support/tickets/{ticket_id}/messages/: | |
| post: | |
| operationId: v1_support_tickets_messages_create | |
| description: |- | |
| POST /api/v1/support/tickets/<ticket_id>/messages/ | |
| Add a threaded reply to a ticket. | |
| Staff replies are differentiated via is_staff_reply flag. | |
| parameters: | |
| - in: path | |
| name: ticket_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/support/tickets/{ticket_id}/status/: | |
| patch: | |
| operationId: v1_support_tickets_status_partial_update | |
| description: |- | |
| PATCH /api/v1/support/tickets/<ticket_id>/status/ | |
| Staff-only endpoint: transition ticket status with optional notes. | |
| parameters: | |
| - in: path | |
| name: ticket_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/transactions/: | |
| get: | |
| operationId: v1_transactions_list | |
| description: |- | |
| Retrieves a paginated list of transactions for the authenticated user. | |
| Flow: | |
| 1. Filter transactions where user is either the initiator or recipient. | |
| 2. Order by most recent first. | |
| 3. Return standardized transaction objects. | |
| Status Codes: | |
| 200 OK: Returns transaction list. | |
| parameters: | |
| - name: page | |
| required: false | |
| in: query | |
| description: A page number within the paginated result set. | |
| schema: | |
| type: integer | |
| - name: page_size | |
| required: false | |
| in: query | |
| description: Number of results to return per page. | |
| schema: | |
| type: integer | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PaginatedTransactionList' | |
| description: '' | |
| /api/v1/transactions/{transaction_id}/: | |
| get: | |
| operationId: v1_transactions_retrieve | |
| description: |- | |
| GET /api/v1/transactions/<transaction_id>/ | |
| Retrieve details of a specific transaction. | |
| Retrieves granular details of a specific transaction ID. | |
| Security: | |
| - Enforces ownership check (user must be party to the transaction). | |
| Status Codes: | |
| 200 OK: Returns transaction details. | |
| 404 Not Found: Transaction doesn't exist or user lacks access. | |
| parameters: | |
| - in: path | |
| name: transaction_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Transaction' | |
| description: '' | |
| /api/v1/transactions/{transaction_id}/dispute/: | |
| post: | |
| operationId: v1_transactions_dispute_create | |
| description: |- | |
| Opens a formal dispute case for a specific transaction. | |
| POST /api/v1/transactions/<transaction_id>/refund/ | |
| Initiate a refund for a transaction on escrow hold. | |
| Flow: | |
| 1. Client submits reason and disputed amount. | |
| 2. Backend freezes related escrow funds if applicable. | |
| 3. Notify admin/vendor of the open dispute. | |
| Status Codes: | |
| 201 Created: Dispute case opened. | |
| parameters: | |
| - in: path | |
| name: transaction_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/DisputeCreateRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/DisputeCreateRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/DisputeCreateRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/DisputeCreate' | |
| description: '' | |
| /api/v1/transactions/{transaction_id}/refund/: | |
| post: | |
| operationId: v1_transactions_refund_create | |
| description: |- | |
| Initiates a manual refund for an escrowed payment. | |
| POST /api/v1/transactions/<transaction_id>/refund/ | |
| Initiate a refund for a transaction on escrow hold. | |
| Flow: | |
| 1. Verify the transaction is currently held in Escrow. | |
| 2. Reverse the hold back to the client's available balance. | |
| 3. Log the refund event in the transaction history. | |
| Status Codes: | |
| 200 OK: Refund successfully processed. | |
| 400 Bad Request: Transaction not eligible for refund. | |
| parameters: | |
| - in: path | |
| name: transaction_id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/RefundRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/RefundRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/RefundRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Refund' | |
| description: '' | |
| /api/v1/transactions/summary/: | |
| get: | |
| operationId: v1_transactions_summary_retrieve | |
| description: |- | |
| Aggregates financial performance statistics for the user's wallet. | |
| GET /api/v1/transactions/summary/ | |
| Get a summary of transactions (inflow, outflow, count). | |
| Flow: | |
| 1. Sum all credits (inflow). | |
| 2. Sum all debits (outflow). | |
| 3. Count total volume of transactions. | |
| Status Codes: | |
| 200 OK: Returns summary statistics. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/TransactionSummary' | |
| description: '' | |
| /api/v1/upload/presign/: | |
| post: | |
| operationId: v1_upload_presign_create | |
| description: |- | |
| POST /api/v1/upload/presign/ | |
| Generate a time-limited, HMAC-SHA256–signed Cloudinary upload token. | |
| The frontend uses this to POST a file DIRECTLY to Cloudinary without | |
| routing the upload data through the Django server. | |
| Authentication: Bearer JWT (IsAuthenticated). | |
| Request body (validated by PresignRequestSerializer): | |
| { "asset_type": "avatar" | "product_image" | "product_video" | "measurement" } | |
| Response 200: | |
| { | |
| "success": true, | |
| "cloud_name": "your_cloud", | |
| "api_key": "...", | |
| "signature": "hex-sha256", | |
| "timestamp": 1712345678, | |
| "folder": "fashionistar/users/avatars/user_UUID", | |
| "upload_preset": "fashionistar_avatars", | |
| "resource_type": "image", | |
| "eager": [...], | |
| "eager_async": true | |
| } | |
| Response 400 — invalid asset_type (serializer validation error). | |
| Response 500 — signature generation failed. | |
| parameters: | |
| - in: query | |
| name: format | |
| schema: | |
| type: string | |
| enum: | |
| - html | |
| - json | |
| - multipart | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CommonPresignRequestRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/CommonPresignRequestRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CommonPresignRequestRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/CommonPresignRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/CommonPresignRequest' | |
| text/html: | |
| schema: | |
| $ref: '#/components/schemas/CommonPresignRequest' | |
| description: '' | |
| /api/v1/vendor/bank-accounts/: | |
| get: | |
| operationId: v1_vendor_bank_accounts_retrieve | |
| description: |- | |
| GET /api/v1/vendor/bank-accounts/ — list saved bank accounts | |
| POST /api/v1/vendor/bank-accounts/ — create a new bank account | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/BankAccountOutput' | |
| description: '' | |
| post: | |
| operationId: v1_vendor_bank_accounts_create | |
| description: |- | |
| GET /api/v1/vendor/bank-accounts/ — list saved bank accounts | |
| POST /api/v1/vendor/bank-accounts/ — create a new bank account | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/BankAccountCreateRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/BankAccountCreateRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/BankAccountCreateRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/BankAccountCreate' | |
| description: '' | |
| /api/v1/vendor/bank-accounts/{id}/: | |
| delete: | |
| operationId: v1_vendor_bank_accounts_destroy | |
| description: |- | |
| DELETE /api/v1/vendor/bank-accounts/<uuid:pk>/ | |
| Soft-delete the bank account and clean up the Paystack recipient. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/vendor/bank-accounts/{id}/default/: | |
| patch: | |
| operationId: v1_vendor_bank_accounts_default_partial_update | |
| description: |- | |
| PATCH /api/v1/vendor/bank-accounts/<uuid:pk>/default/ | |
| Set the specified bank account as the vendor's default payout account. | |
| parameters: | |
| - in: path | |
| name: id | |
| schema: | |
| type: string | |
| format: uuid | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/vendor/bank-accounts/resolve/: | |
| post: | |
| operationId: v1_vendor_bank_accounts_resolve_create | |
| description: |- | |
| POST /api/v1/vendor/bank-accounts/resolve/ | |
| Proxy Paystack /bank/resolve to retrieve the account holder name. | |
| This endpoint is called by the frontend "Resolve Name" button in the | |
| Add Bank Account modal. | |
| Request body: | |
| account_number (str): 10-digit NUBAN | |
| bank_code (str): Paystack bank code (e.g. "044") | |
| Response (200): | |
| { account_name: str, account_number: str } | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/BankAccountResolveRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/BankAccountResolveRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/BankAccountResolveRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/BankAccountResolve' | |
| description: '' | |
| /api/v1/vendor/orders/{order_id}/status/: | |
| put: | |
| operationId: v1_vendor_orders_status_update | |
| description: |- | |
| PATCH /api/v1/vendor/orders/<int:order_id>/status/ | |
| Update order_status for a vendor's own order. | |
| Allowed values: Pending, Processing, Shipped, Fulfilled, Cancelled. | |
| Payment status (paid/unpaid) is immutable here — managed by payment gateway. | |
| parameters: | |
| - in: path | |
| name: order_id | |
| schema: | |
| type: integer | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorOrderStatusRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/VendorOrderStatusRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/VendorOrderStatusRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorOrderStatus' | |
| description: '' | |
| patch: | |
| operationId: v1_vendor_orders_status_partial_update | |
| description: |- | |
| PATCH /api/v1/vendor/orders/<int:order_id>/status/ | |
| Update order_status for a vendor's own order. | |
| Allowed values: Pending, Processing, Shipped, Fulfilled, Cancelled. | |
| Payment status (paid/unpaid) is immutable here — managed by payment gateway. | |
| parameters: | |
| - in: path | |
| name: order_id | |
| schema: | |
| type: integer | |
| required: true | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedVendorOrderStatusRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedVendorOrderStatusRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedVendorOrderStatusRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorOrderStatus' | |
| description: '' | |
| /api/v1/vendor/payout/: | |
| post: | |
| operationId: v1_vendor_payout_create | |
| description: POST /api/v1/vendor/payout/ — save bank / payout account details | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorPayoutDetailsRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/VendorPayoutDetailsRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/VendorPayoutDetailsRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorPayoutDetails' | |
| description: '' | |
| /api/v1/vendor/payout/request/: | |
| post: | |
| operationId: v1_vendor_payout_request_create | |
| description: |- | |
| POST /api/v1/vendor/payout/request/ | |
| Initiate a bank transfer payout from the vendor's Fashionistar wallet | |
| to one of their saved bank accounts. | |
| Request body: | |
| bank_account_id (UUID): The VendorBankAccount UUID to pay into. | |
| amount (Decimal): Amount in NGN (min ₦1,000). | |
| narration (str, optional): Bank transfer description. | |
| Response (200): | |
| { | |
| "status": "success", | |
| "reference": "PAYOUT-XXXXXXXX-XXXXXXXXXXXXXXXXXXXX", | |
| "transfer_code": "TRF_xxxxx", | |
| "amount": "5000.00", | |
| "currency": "NGN", | |
| "message": "Payout initiated successfully. Funds will arrive within 1–2 business days." | |
| } | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PayoutRequestRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PayoutRequestRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PayoutRequestRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PayoutRequest' | |
| description: '' | |
| /api/v1/vendor/pin/set/: | |
| post: | |
| operationId: v1_vendor_pin_set_create | |
| description: POST /api/v1/vendor/pin/set/ — set 4-digit payout confirmation | |
| PIN | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorTransactionPinRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/VendorTransactionPinRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/VendorTransactionPinRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorTransactionPin' | |
| description: '' | |
| /api/v1/vendor/pin/verify/: | |
| post: | |
| operationId: v1_vendor_pin_verify_create | |
| description: POST /api/v1/vendor/pin/verify/ — verify payout PIN before withdrawal | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorTransactionPinRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/VendorTransactionPinRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/VendorTransactionPinRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorTransactionPin' | |
| description: '' | |
| /api/v1/vendor/products/{slug}/delete/: | |
| get: | |
| operationId: v1_vendor_products_delete_retrieve | |
| description: |- | |
| GET /api/v1/products/vendor/<slug>/ | |
| PATCH /api/v1/products/vendor/<slug>/ | |
| DELETE /api/v1/products/vendor/<slug>/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| patch: | |
| operationId: v1_vendor_products_delete_partial_update | |
| description: |- | |
| GET /api/v1/products/vendor/<slug>/ | |
| PATCH /api/v1/products/vendor/<slug>/ | |
| DELETE /api/v1/products/vendor/<slug>/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| delete: | |
| operationId: v1_vendor_products_delete_destroy | |
| description: |- | |
| GET /api/v1/products/vendor/<slug>/ | |
| PATCH /api/v1/products/vendor/<slug>/ | |
| DELETE /api/v1/products/vendor/<slug>/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/vendor/products/{slug}/edit/: | |
| get: | |
| operationId: v1_vendor_products_edit_retrieve | |
| description: |- | |
| GET /api/v1/products/vendor/<slug>/ | |
| PATCH /api/v1/products/vendor/<slug>/ | |
| DELETE /api/v1/products/vendor/<slug>/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| patch: | |
| operationId: v1_vendor_products_edit_partial_update | |
| description: |- | |
| GET /api/v1/products/vendor/<slug>/ | |
| PATCH /api/v1/products/vendor/<slug>/ | |
| DELETE /api/v1/products/vendor/<slug>/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| delete: | |
| operationId: v1_vendor_products_edit_destroy | |
| description: |- | |
| GET /api/v1/products/vendor/<slug>/ | |
| PATCH /api/v1/products/vendor/<slug>/ | |
| DELETE /api/v1/products/vendor/<slug>/ | |
| parameters: | |
| - in: path | |
| name: slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '204': | |
| description: No response body | |
| /api/v1/vendor/products/create/: | |
| get: | |
| operationId: v1_vendor_products_create_retrieve | |
| description: |- | |
| GET /api/v1/products/vendor/ — List vendor's own products (paginated). | |
| POST /api/v1/products/vendor/ — Create product (idempotency key supported). | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| post: | |
| operationId: v1_vendor_products_create_create | |
| description: |- | |
| GET /api/v1/products/vendor/ — List vendor's own products (paginated). | |
| POST /api/v1/products/vendor/ — Create product (idempotency key supported). | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/vendor/products/filter/: | |
| get: | |
| operationId: v1_vendor_products_filter_retrieve | |
| description: |- | |
| GET /api/v1/products/vendor/ — List vendor's own products (paginated). | |
| POST /api/v1/products/vendor/ — Create product (idempotency key supported). | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| post: | |
| operationId: v1_vendor_products_filter_create | |
| description: |- | |
| GET /api/v1/products/vendor/ — List vendor's own products (paginated). | |
| POST /api/v1/products/vendor/ — Create product (idempotency key supported). | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/vendor/profile/: | |
| get: | |
| operationId: v1_vendor_profile_retrieve | |
| description: |- | |
| GET /api/v1/vendor/profile/ — retrieve vendor store profile | |
| PATCH /api/v1/vendor/profile/ — update store profile | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorProfileOutput' | |
| description: '' | |
| patch: | |
| operationId: v1_vendor_profile_partial_update | |
| description: |- | |
| GET /api/v1/vendor/profile/ — retrieve vendor store profile | |
| PATCH /api/v1/vendor/profile/ — update store profile | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/PatchedVendorProfileUpdateRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/PatchedVendorProfileUpdateRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/PatchedVendorProfileUpdateRequest' | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorProfileUpdate' | |
| description: '' | |
| /api/v1/vendor/public/: | |
| get: | |
| operationId: v1_vendor_public_retrieve | |
| description: |- | |
| GET /api/v1/vendor/public/ | |
| Public listing of active vendors for the home/vendors marketplace page. | |
| Permissions: AllowAny (no auth required — publicly browsable). | |
| Filters (query params): | |
| ?is_featured=true — featured vendors only | |
| ?city=Lagos — filter by city | |
| ?search=bespoke — search store_name / tagline | |
| ?limit=24 — page size (default 24, max 100) | |
| ?offset=0 — pagination offset | |
| Response: { status, count, data: [VendorCard...] } | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/vendor/public/{store_slug}/: | |
| get: | |
| operationId: v1_vendor_public_retrieve_2 | |
| description: |- | |
| GET /api/v1/vendor/public/{store_slug}/ | |
| Public vendor profile detail for the /vendors/[slug] page. | |
| Permissions: AllowAny. | |
| Returns full vendor profile plus top 12 products. | |
| parameters: | |
| - in: path | |
| name: store_slug | |
| schema: | |
| type: string | |
| required: true | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| - {} | |
| responses: | |
| '200': | |
| description: No response body | |
| /api/v1/vendor/setup/: | |
| get: | |
| operationId: v1_vendor_setup_retrieve | |
| description: |- | |
| GET /api/v1/vendor/setup/ — retrieve onboarding setup state | |
| POST /api/v1/vendor/setup/ — create/update the first vendor setup record | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorSetupState' | |
| description: '' | |
| post: | |
| operationId: v1_vendor_setup_create | |
| description: |- | |
| GET /api/v1/vendor/setup/ — retrieve onboarding setup state | |
| POST /api/v1/vendor/setup/ — create/update the first vendor setup record | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorSetupRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/VendorSetupRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/VendorSetupRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/VendorSetup' | |
| description: '' | |
| /api/v1/wallet/balance/: | |
| get: | |
| operationId: v1_wallet_balance_retrieve | |
| description: |- | |
| Alias for MyWalletView, specifically focusing on the current balance state. | |
| Legacy Context: | |
| Previously served as a simple balance-only endpoint. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Wallet' | |
| description: '' | |
| /api/v1/wallet/escrow/hold/: | |
| post: | |
| operationId: v1_wallet_escrow_hold_create | |
| description: |- | |
| Places funds on escrow hold when a new order is initialized. | |
| Flow: | |
| 1. Verify user has sufficient balance. | |
| 2. Deduct amount from available balance. | |
| 3. Create a Hold record with PENDING status. | |
| 4. Increment 'held_balance'. | |
| Status Codes: | |
| 201 Created: Funds successfully locked in escrow. | |
| 400 Bad Request: Insufficient balance. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/EscrowHoldRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/EscrowHoldRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/EscrowHoldRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/EscrowHold' | |
| description: '' | |
| /api/v1/wallet/escrow/release/: | |
| post: | |
| operationId: v1_wallet_escrow_release_create | |
| description: |- | |
| Releases escrowed funds to the vendor after order completion. | |
| Flow: | |
| 1. Locate the Hold record by reference. | |
| 2. Verify client authorization (or automated release trigger). | |
| 3. Calculate and deduct platform commission. | |
| 4. Credit vendor's available balance. | |
| 5. Mark Hold as RELEASED. | |
| Status Codes: | |
| 200 OK: Vendor successfully credited. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/EscrowReleaseRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/EscrowReleaseRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/EscrowReleaseRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/EscrowRelease' | |
| description: '' | |
| /api/v1/wallet/me/: | |
| get: | |
| operationId: v1_wallet_me_retrieve | |
| description: |- | |
| Retrieves the authenticated user's digital wallet profile. | |
| Flow: | |
| 1. Check if wallet exists for the user. | |
| 2. If not, provision a new wallet with zero balance. | |
| 3. Return balance and hold statistics. | |
| Status Codes: | |
| 200 OK: Returns wallet details. | |
| tags: | |
| - v1 | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Wallet' | |
| description: '' | |
| /api/v1/wallet/pin/change/: | |
| post: | |
| operationId: v1_wallet_pin_change_create | |
| description: |- | |
| Updates an existing transaction PIN after verifying the current one. | |
| Security: | |
| Requires 'current_pin' to prevent unauthorized changes. | |
| Status Codes: | |
| 200 OK: PIN updated. | |
| 400 Bad Request: Invalid current PIN or weak new PIN. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WalletPinChangeRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/WalletPinChangeRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/WalletPinChangeRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WalletPinChange' | |
| description: '' | |
| /api/v1/wallet/pin/set/: | |
| post: | |
| operationId: v1_wallet_pin_set_create | |
| description: |- | |
| Establishes a 4-digit transaction PIN for wallet authorization. | |
| Flow: | |
| 1. User provides a 4-digit numeric string. | |
| 2. Service hashes the PIN for secure storage. | |
| 3. Enables transaction capabilities for the wallet. | |
| Status Codes: | |
| 200 OK: PIN established. | |
| 400 Bad Request: Invalid format or PIN already set. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WalletPinSetRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/WalletPinSetRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/WalletPinSetRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WalletPinSet' | |
| description: '' | |
| /api/v1/wallet/pin/verify/: | |
| post: | |
| operationId: v1_wallet_pin_verify_create | |
| description: |- | |
| Validates a transaction PIN without performing a financial operation. | |
| Use Case: | |
| Frontend checks PIN before showing "Confirm Transfer" buttons. | |
| Status Codes: | |
| 200 OK: returns {"valid": bool} | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WalletPinVerifyRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/WalletPinVerifyRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/WalletPinVerifyRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WalletPinVerify' | |
| description: '' | |
| /api/v1/wallet/refund/: | |
| post: | |
| operationId: v1_wallet_refund_create | |
| description: |- | |
| Refunds escrowed funds back to the client available balance. | |
| Use Case: | |
| Order cancellation or dispute resolution in favor of the client. | |
| Flow: | |
| 1. Move funds from held_balance back to available_balance. | |
| 2. Mark Hold as REFUNDED. | |
| Status Codes: | |
| 200 OK: Client successfully refunded. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/EscrowRefundRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/EscrowRefundRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/EscrowRefundRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/EscrowRefund' | |
| description: '' | |
| /api/v1/wallet/withdraw/: | |
| post: | |
| operationId: v1_wallet_withdraw_create | |
| description: |- | |
| Create a KYC-gated wallet withdrawal request. | |
| The service blocks before debit if KYC is incomplete, then moves funds from | |
| available to pending balance and writes a processing payout ledger row. | |
| tags: | |
| - v1 | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WalletWithdrawalRequest' | |
| application/x-www-form-urlencoded: | |
| schema: | |
| $ref: '#/components/schemas/WalletWithdrawalRequest' | |
| multipart/form-data: | |
| schema: | |
| $ref: '#/components/schemas/WalletWithdrawalRequest' | |
| required: true | |
| security: | |
| - jwtAuth: [] | |
| - tokenAuth: [] | |
| - cookieAuth: [] | |
| - basicAuth: [] | |
| - BearerAuth: [] | |
| responses: | |
| '200': | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/WalletWithdrawal' | |
| description: '' | |
| components: | |
| schemas: | |
| AddressCreate: | |
| type: object | |
| description: Input serializer for POST /addresses/. | |
| properties: | |
| label: | |
| type: string | |
| description: 'Short label: ''Home'', ''Office'', or ''Mum\''s place''.' | |
| maxLength: 80 | |
| full_name: | |
| type: string | |
| maxLength: 150 | |
| phone: | |
| type: string | |
| maxLength: 30 | |
| street_address: | |
| type: string | |
| description: Street, house number, landmark. | |
| city: | |
| type: string | |
| maxLength: 100 | |
| state: | |
| type: string | |
| maxLength: 100 | |
| country: | |
| type: string | |
| maxLength: 100 | |
| postal_code: | |
| type: string | |
| maxLength: 20 | |
| is_default: | |
| type: boolean | |
| description: True if this is the primary address shown at checkout. | |
| required: | |
| - city | |
| - state | |
| - street_address | |
| AddressCreateRequest: | |
| type: object | |
| description: Input serializer for POST /addresses/. | |
| properties: | |
| label: | |
| type: string | |
| description: 'Short label: ''Home'', ''Office'', or ''Mum\''s place''.' | |
| maxLength: 80 | |
| full_name: | |
| type: string | |
| maxLength: 150 | |
| phone: | |
| type: string | |
| maxLength: 30 | |
| street_address: | |
| type: string | |
| minLength: 1 | |
| description: Street, house number, landmark. | |
| city: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| state: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| country: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| postal_code: | |
| type: string | |
| maxLength: 20 | |
| is_default: | |
| type: boolean | |
| description: True if this is the primary address shown at checkout. | |
| required: | |
| - city | |
| - state | |
| - street_address | |
| Alert: | |
| type: object | |
| properties: | |
| id: | |
| type: integer | |
| readOnly: true | |
| rule: | |
| type: integer | |
| title: Alert Rule | |
| rule_name: | |
| type: string | |
| readOnly: true | |
| rule_severity: | |
| type: string | |
| readOnly: true | |
| status: | |
| $ref: '#/components/schemas/AlertStatusEnum' | |
| metric_value: | |
| type: number | |
| format: double | |
| title: Current Value | |
| message: | |
| type: string | |
| title: Alert Message | |
| metadata: {} | |
| fired_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| title: Triggered At | |
| resolved_at: | |
| type: string | |
| format: date-time | |
| nullable: true | |
| required: | |
| - fired_at | |
| - id | |
| - message | |
| - metric_value | |
| - rule | |
| - rule_name | |
| - rule_severity | |
| AlertRequest: | |
| type: object | |
| properties: | |
| rule: | |
| type: integer | |
| title: Alert Rule | |
| status: | |
| $ref: '#/components/schemas/AlertStatusEnum' | |
| metric_value: | |
| type: number | |
| format: double | |
| title: Current Value | |
| message: | |
| type: string | |
| minLength: 1 | |
| title: Alert Message | |
| metadata: {} | |
| resolved_at: | |
| type: string | |
| format: date-time | |
| nullable: true | |
| required: | |
| - message | |
| - metric_value | |
| - rule | |
| AlertRule: | |
| type: object | |
| properties: | |
| id: | |
| type: integer | |
| readOnly: true | |
| name: | |
| type: string | |
| title: Rule Name | |
| maxLength: 100 | |
| metric_name: | |
| type: string | |
| maxLength: 255 | |
| operator: | |
| allOf: | |
| - $ref: '#/components/schemas/OperatorEnum' | |
| title: Comparison Operator | |
| threshold: | |
| type: number | |
| format: double | |
| severity: | |
| $ref: '#/components/schemas/SeverityEnum' | |
| is_active: | |
| type: boolean | |
| description: | |
| type: string | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - created_at | |
| - id | |
| - metric_name | |
| - name | |
| - operator | |
| - threshold | |
| - updated_at | |
| AlertRuleRequest: | |
| type: object | |
| properties: | |
| name: | |
| type: string | |
| minLength: 1 | |
| title: Rule Name | |
| maxLength: 100 | |
| metric_name: | |
| type: string | |
| minLength: 1 | |
| maxLength: 255 | |
| operator: | |
| allOf: | |
| - $ref: '#/components/schemas/OperatorEnum' | |
| title: Comparison Operator | |
| threshold: | |
| type: number | |
| format: double | |
| severity: | |
| $ref: '#/components/schemas/SeverityEnum' | |
| is_active: | |
| type: boolean | |
| description: | |
| type: string | |
| required: | |
| - metric_name | |
| - name | |
| - operator | |
| - threshold | |
| AlertStatusEnum: | |
| enum: | |
| - firing | |
| - resolved | |
| - suppressed | |
| type: string | |
| AssetTypeEnum: | |
| enum: | |
| - avatar | |
| - blog | |
| - brand | |
| - category | |
| - chat_file | |
| - collection | |
| - generic_image | |
| - generic_video | |
| - kyc_document | |
| - measurement | |
| - product_color | |
| - product_gallery | |
| - product_image | |
| - product_video | |
| - profile | |
| - vendor_shop | |
| type: string | |
| AuthGoogleAuth: | |
| type: object | |
| description: |- | |
| Serializer for Google ID Token authentication. | |
| Flow: | |
| Login (existing user): { id_token } — role is optional, ignored | |
| Register (new user): { id_token, role: 'vendor'|'client' } | |
| properties: | |
| id_token: | |
| type: string | |
| description: Google ID Token (JWT) returned by @react-oauth/google on the | |
| frontend. | |
| role: | |
| default: client | |
| description: User's role — required for new registrations, ignored for existing | |
| users. | |
| oneOf: | |
| - $ref: '#/components/schemas/RoleC2fEnum' | |
| - $ref: '#/components/schemas/BlankEnum' | |
| required: | |
| - id_token | |
| AuthGoogleAuthRequest: | |
| type: object | |
| description: |- | |
| Serializer for Google ID Token authentication. | |
| Flow: | |
| Login (existing user): { id_token } — role is optional, ignored | |
| Register (new user): { id_token, role: 'vendor'|'client' } | |
| properties: | |
| id_token: | |
| type: string | |
| minLength: 1 | |
| description: Google ID Token (JWT) returned by @react-oauth/google on the | |
| frontend. | |
| role: | |
| default: client | |
| description: User's role — required for new registrations, ignored for existing | |
| users. | |
| oneOf: | |
| - $ref: '#/components/schemas/RoleC2fEnum' | |
| - $ref: '#/components/schemas/BlankEnum' | |
| required: | |
| - id_token | |
| AuthLoginRequest: | |
| type: object | |
| description: |- | |
| Serializer for authenticating users with either email or phone. | |
| Enterprise-grade auth flow (priority order): | |
| 1. Alive-only lookup (is_deleted=False) | |
| 2. Soft-deleted pool check → SoftDeletedUserError (403) | |
| 3. Password check → InvalidCredentialsError (401) | |
| 4a. is_verified check FIRST → AccountNotVerifiedError (403) with OTP URLs | |
| 4b. is_active check SECOND → AccountDeactivatedError (403) with support URL | |
| Serializer for user authentication via Email or Phone. | |
| Validation Logic: | |
| 1. Normalise input identifier (email to lowercase). | |
| 2. Verify user exists and is not soft-deleted. | |
| 3. Verify password hash matches. | |
| 4. Check account lifecycle status (verified, active). | |
| Security: | |
| - Uses Django's `check_password` for constant-time comparison. | |
| - Throttled at the View level to prevent brute-force. | |
| properties: | |
| email_or_phone: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: User's email or phone for login | |
| password: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: User's password | |
| required: | |
| - email_or_phone | |
| - password | |
| AuthLogout: | |
| type: object | |
| description: Accepts the refresh token to blacklist on logout. | |
| properties: | |
| refresh: | |
| type: string | |
| description: Refresh token to blacklist on logout. | |
| required: | |
| - refresh | |
| AuthLogoutRequest: | |
| type: object | |
| description: Accepts the refresh token to blacklist on logout. | |
| properties: | |
| refresh: | |
| type: string | |
| minLength: 1 | |
| description: Refresh token to blacklist on logout. | |
| required: | |
| - refresh | |
| AuthMe: | |
| type: object | |
| description: |- | |
| Serializes the authenticated user's profile for the /auth/me/ endpoint. | |
| This serializer's output shape is the authoritative contract between | |
| the backend and the frontend Zustand auth store (useAuthHydration). | |
| Field-by-field null/blank behaviour: | |
| user_id → str (UUID) | |
| identifying_info → str (email or phone or fallback string) | |
| member_id → str | null (null only before first save race, practically never) | |
| email → str | null (null for phone-only accounts) | |
| phone → str | null (null for email-only accounts, E.164 format) | |
| first_name → str (empty string "" when not set — model blank=True) | |
| last_name → str (empty string "" when not set — model blank=True) | |
| role → str (choices: client | vendor | staff | admin | …) | |
| auth_provider → str (choices: email | phone | google) | |
| is_verified → bool | |
| is_active → bool | |
| is_staff → bool | |
| avatar → str | null (full Cloudinary HTTPS URL or null) | |
| bio → str (empty string "" when not set) | |
| country → str (empty string "" when not set) | |
| state → str (empty string "" when not set) | |
| city → str (empty string "" when not set) | |
| address → str (empty string "" when not set) | |
| date_joined → str | null (ISO-8601 datetime string or null) | |
| last_login → str | null (ISO-8601 datetime string or null) | |
| properties: | |
| user_id: | |
| type: string | |
| readOnly: true | |
| identifying_info: | |
| type: string | |
| readOnly: true | |
| member_id: | |
| type: string | |
| readOnly: true | |
| nullable: true | |
| description: Unique human-readable brand ID (e.g. FASTAR000062). Auto-generated | |
| on user creation. Cannot be changed. | |
| email: | |
| type: string | |
| format: email | |
| readOnly: true | |
| nullable: true | |
| title: Email address | |
| description: Primary unique identifier for email-based auth. | |
| phone: | |
| type: string | |
| readOnly: true | |
| first_name: | |
| type: string | |
| readOnly: true | |
| default: '' | |
| last_name: | |
| type: string | |
| readOnly: true | |
| default: '' | |
| role: | |
| allOf: | |
| - $ref: '#/components/schemas/RoleC2fEnum' | |
| readOnly: true | |
| description: RBAC Role. Cannot be changed after creation. | |
| auth_provider: | |
| allOf: | |
| - $ref: '#/components/schemas/AuthProviderEnum' | |
| readOnly: true | |
| description: Authentication provider used at signup. | |
| is_verified: | |
| type: boolean | |
| readOnly: true | |
| description: True if email/phone OTP is verified. | |
| is_active: | |
| type: boolean | |
| readOnly: true | |
| description: True if user account is active. | |
| is_staff: | |
| type: boolean | |
| readOnly: true | |
| title: Staff status | |
| description: Designates whether the user can log into this admin site. | |
| has_client_profile: | |
| type: string | |
| readOnly: true | |
| has_vendor_profile: | |
| type: string | |
| readOnly: true | |
| vendor_onboarding_status: | |
| type: string | |
| readOnly: true | |
| dashboard_entrypoint: | |
| type: string | |
| readOnly: true | |
| avatar: | |
| type: string | |
| readOnly: true | |
| bio: | |
| type: string | |
| readOnly: true | |
| description: User's biography. | |
| country: | |
| type: string | |
| readOnly: true | |
| description: User's country. | |
| state: | |
| type: string | |
| readOnly: true | |
| description: User's state or province. | |
| city: | |
| type: string | |
| readOnly: true | |
| description: User's city. | |
| address: | |
| type: string | |
| readOnly: true | |
| description: User's street address. | |
| date_joined: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| last_login: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - address | |
| - auth_provider | |
| - avatar | |
| - bio | |
| - city | |
| - country | |
| - dashboard_entrypoint | |
| - date_joined | |
| - first_name | |
| - has_client_profile | |
| - has_vendor_profile | |
| - identifying_info | |
| - is_active | |
| - is_staff | |
| - is_verified | |
| - last_login | |
| - last_name | |
| - member_id | |
| - phone | |
| - role | |
| - state | |
| - user_id | |
| - vendor_onboarding_status | |
| AuthMethodEnum: | |
| enum: | |
| - phone | |
| - biometric | |
| type: string | |
| AuthOTP: | |
| type: object | |
| description: |- | |
| Serializer for OTP verification. | |
| Validation Logic: | |
| - Required: 6-digit string. | |
| - Numeric only. | |
| Security: | |
| - Max length enforced to prevent buffer/memory attacks. | |
| properties: | |
| otp: | |
| type: string | |
| description: One-Time Password (OTP) for verification. | |
| maxLength: 6 | |
| required: | |
| - otp | |
| AuthOTPRequest: | |
| type: object | |
| description: |- | |
| Serializer for OTP verification. | |
| Validation Logic: | |
| - Required: 6-digit string. | |
| - Numeric only. | |
| Security: | |
| - Max length enforced to prevent buffer/memory attacks. | |
| properties: | |
| otp: | |
| type: string | |
| minLength: 1 | |
| description: One-Time Password (OTP) for verification. | |
| maxLength: 6 | |
| required: | |
| - otp | |
| AuthPasswordResetConfirmEmailRequest: | |
| type: object | |
| description: |- | |
| Serializer for confirming password reset via email magic link. | |
| Validates the new password and confirmation match. | |
| The uidb64 + token URL params are merged in by the view. | |
| properties: | |
| password: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: New password | |
| password2: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: Confirm new password | |
| required: | |
| - password | |
| - password2 | |
| AuthPasswordResetConfirmPhone: | |
| type: object | |
| description: |- | |
| Serializer for confirming password reset via phone OTP. | |
| OTP-ONLY design (mirrors VerifyOTPView pattern exactly): | |
| - Client sends ONLY: otp + new_password + new_password_confirm. | |
| - phone is NOT required in the body — the service discovers the user | |
| via OTPService.verify_by_otp_sync(otp, purpose='password_reset'), | |
| which uses an O(1) SHA-256 hash index lookup in Redis: | |
| otp_hash:{sha256(otp)} → otp:{user_id}:password_reset:{snippet} | |
| - This prevents account enumeration: an attacker cannot test whether | |
| a phone number has an account by observing different error responses. | |
| Redis key schema (written during reset-request): | |
| Primary : otp:{user_id}:password_reset:{snippet} | |
| Value = "{encrypted_otp}|{sha256_hex}" | |
| Secondary: otp_hash:{sha256_hex} → primary_key (TTL = 300 s) | |
| Field names match Zod PasswordResetConfirmPhoneSchema exactly: | |
| Frontend sends: { otp, new_password, new_password_confirm } | |
| properties: | |
| otp: | |
| type: string | |
| description: 6-digit OTP received via SMS | |
| maxLength: 6 | |
| required: | |
| - otp | |
| AuthPasswordResetConfirmPhoneRequest: | |
| type: object | |
| description: |- | |
| Serializer for confirming password reset via phone OTP. | |
| OTP-ONLY design (mirrors VerifyOTPView pattern exactly): | |
| - Client sends ONLY: otp + new_password + new_password_confirm. | |
| - phone is NOT required in the body — the service discovers the user | |
| via OTPService.verify_by_otp_sync(otp, purpose='password_reset'), | |
| which uses an O(1) SHA-256 hash index lookup in Redis: | |
| otp_hash:{sha256(otp)} → otp:{user_id}:password_reset:{snippet} | |
| - This prevents account enumeration: an attacker cannot test whether | |
| a phone number has an account by observing different error responses. | |
| Redis key schema (written during reset-request): | |
| Primary : otp:{user_id}:password_reset:{snippet} | |
| Value = "{encrypted_otp}|{sha256_hex}" | |
| Secondary: otp_hash:{sha256_hex} → primary_key (TTL = 300 s) | |
| Field names match Zod PasswordResetConfirmPhoneSchema exactly: | |
| Frontend sends: { otp, new_password, new_password_confirm } | |
| properties: | |
| otp: | |
| type: string | |
| minLength: 1 | |
| description: 6-digit OTP received via SMS | |
| maxLength: 6 | |
| new_password: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: New password | |
| new_password_confirm: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: Confirm new password | |
| required: | |
| - new_password | |
| - new_password_confirm | |
| - otp | |
| AuthPasswordResetRequestRequest: | |
| type: object | |
| description: |- | |
| Serializer for requesting password reset. | |
| Uses all_with_deleted() so soft-deleted users can still trigger a reset. | |
| Anti-enumeration: always returns 200 regardless of whether user exists. | |
| properties: | |
| email_or_phone: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: User's email or phone for password reset | |
| required: | |
| - email_or_phone | |
| AuthProtectedUser: | |
| type: object | |
| description: |- | |
| Expose safe, non-sensitive user information for authenticated profile reads. | |
| Used by endpoints that share user data with other users or services. | |
| Never exposes: password, groups, permissions, auth_provider, is_staff, | |
| internal timestamps, or any security-sensitive field. | |
| Fields returned: | |
| user_id → str (UUID) | |
| member_id → str | null | |
| email → str | null | |
| phone → str | null (E.164) | |
| first_name → str | |
| last_name → str | |
| role → str | |
| is_verified → bool | |
| is_active → bool | |
| avatar → str | null (Cloudinary URL) | |
| bio → str | |
| country → str | |
| state → str | |
| city → str | |
| address → str | |
| date_joined → ISO-8601 | null | |
| properties: | |
| user_id: | |
| type: string | |
| readOnly: true | |
| member_id: | |
| type: string | |
| readOnly: true | |
| nullable: true | |
| description: Unique human-readable brand ID (e.g. FASTAR000062). Auto-generated | |
| on user creation. Cannot be changed. | |
| email: | |
| type: string | |
| format: email | |
| readOnly: true | |
| nullable: true | |
| title: Email address | |
| description: Primary unique identifier for email-based auth. | |
| phone: | |
| type: string | |
| readOnly: true | |
| first_name: | |
| type: string | |
| readOnly: true | |
| default: '' | |
| last_name: | |
| type: string | |
| readOnly: true | |
| default: '' | |
| role: | |
| allOf: | |
| - $ref: '#/components/schemas/RoleC2fEnum' | |
| readOnly: true | |
| description: RBAC Role. Cannot be changed after creation. | |
| is_verified: | |
| type: boolean | |
| readOnly: true | |
| description: True if email/phone OTP is verified. | |
| is_active: | |
| type: boolean | |
| readOnly: true | |
| description: True if user account is active. | |
| avatar: | |
| type: string | |
| readOnly: true | |
| bio: | |
| type: string | |
| readOnly: true | |
| description: User's biography. | |
| country: | |
| type: string | |
| readOnly: true | |
| description: User's country. | |
| state: | |
| type: string | |
| readOnly: true | |
| description: User's state or province. | |
| city: | |
| type: string | |
| readOnly: true | |
| description: User's city. | |
| address: | |
| type: string | |
| readOnly: true | |
| description: User's street address. | |
| date_joined: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - address | |
| - avatar | |
| - bio | |
| - city | |
| - country | |
| - date_joined | |
| - first_name | |
| - is_active | |
| - is_verified | |
| - last_name | |
| - member_id | |
| - phone | |
| - role | |
| - state | |
| - user_id | |
| AuthProviderEnum: | |
| enum: | |
| - phone | |
| type: string | |
| AuthResendOTPRequestRequest: | |
| type: object | |
| description: |- | |
| Serializer for requesting OTP resend by email or phone. | |
| CRITICAL FIX: Uses ``all_with_deleted()`` manager so that users who | |
| just registered (is_active=False, is_verified=False) are found. | |
| A newly-registered unverified user IS alive — they just haven't | |
| been activated yet. | |
| properties: | |
| email_or_phone: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: User's email or phone for resend OTP | |
| required: | |
| - email_or_phone | |
| AuthTokenRefresh: | |
| type: object | |
| description: Wraps SimpleJWT token refresh for drf-yasg Swagger schema generation. | |
| properties: | |
| refresh: | |
| type: string | |
| description: A valid refresh token previously issued by the login endpoint. | |
| required: | |
| - refresh | |
| AuthTokenRefreshRequest: | |
| type: object | |
| description: Wraps SimpleJWT token refresh for drf-yasg Swagger schema generation. | |
| properties: | |
| refresh: | |
| type: string | |
| minLength: 1 | |
| description: A valid refresh token previously issued by the login endpoint. | |
| required: | |
| - refresh | |
| AuthUserProfile: | |
| type: object | |
| description: |- | |
| Full profile serializer for self-update (PATCH /api/v1/profile/me/). | |
| Read-only fields: | |
| id, member_id, email, phone, role, auth_provider, | |
| is_verified, is_active, is_staff, is_superuser, | |
| date_joined, last_login, password, groups, user_permissions | |
| Writable fields (matches PROFILE_EDITABLE_FIELDS in profile_service): | |
| first_name, last_name, bio, country, state, city, address, avatar | |
| Extra output fields (computed): | |
| user_id → str(uuid) | |
| identifying_info → str | |
| phone_display → E.164 string | null (read-only convenience field) | |
| avatar_url → Cloudinary URL string | null | |
| properties: | |
| user_id: | |
| type: string | |
| readOnly: true | |
| identifying_info: | |
| type: string | |
| readOnly: true | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| member_id: | |
| type: string | |
| readOnly: true | |
| nullable: true | |
| description: Unique human-readable brand ID (e.g. FASTAR000062). Auto-generated | |
| on user creation. Cannot be changed. | |
| email: | |
| type: string | |
| format: email | |
| readOnly: true | |
| nullable: true | |
| title: Email address | |
| description: Primary unique identifier for email-based auth. | |
| phone_display: | |
| type: string | |
| readOnly: true | |
| role: | |
| allOf: | |
| - $ref: '#/components/schemas/RoleC2fEnum' | |
| readOnly: true | |
| description: RBAC Role. Cannot be changed after creation. | |
| auth_provider: | |
| allOf: | |
| - $ref: '#/components/schemas/AuthProviderEnum' | |
| readOnly: true | |
| description: Authentication provider used at signup. | |
| is_verified: | |
| type: boolean | |
| readOnly: true | |
| description: True if email/phone OTP is verified. | |
| is_active: | |
| type: boolean | |
| readOnly: true | |
| description: True if user account is active. | |
| is_staff: | |
| type: boolean | |
| readOnly: true | |
| title: Staff status | |
| description: Designates whether the user can log into this admin site. | |
| first_name: | |
| type: string | |
| nullable: true | |
| last_name: | |
| type: string | |
| nullable: true | |
| bio: | |
| type: string | |
| description: User's biography. | |
| country: | |
| type: string | |
| description: User's country. | |
| maxLength: 100 | |
| state: | |
| type: string | |
| description: User's state or province. | |
| maxLength: 100 | |
| city: | |
| type: string | |
| description: User's city. | |
| maxLength: 100 | |
| address: | |
| type: string | |
| description: User's street address. | |
| maxLength: 255 | |
| avatar: | |
| type: string | |
| nullable: true | |
| description: 'Cloudinary image public_id. Set via the /api/v1/upload/presign/ | |
| → direct upload → webhook flow. Use .url in serializers to retrieve the | |
| full HTTPS secure_url. In admin: use the file picker widget to upload | |
| directly to Cloudinary.' | |
| avatar_url: | |
| type: string | |
| readOnly: true | |
| date_joined: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| last_login: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - auth_provider | |
| - avatar_url | |
| - date_joined | |
| - id | |
| - identifying_info | |
| - is_active | |
| - is_staff | |
| - is_verified | |
| - last_login | |
| - member_id | |
| - phone_display | |
| - role | |
| - user_id | |
| AuthUserProfileRequest: | |
| type: object | |
| description: |- | |
| Full profile serializer for self-update (PATCH /api/v1/profile/me/). | |
| Read-only fields: | |
| id, member_id, email, phone, role, auth_provider, | |
| is_verified, is_active, is_staff, is_superuser, | |
| date_joined, last_login, password, groups, user_permissions | |
| Writable fields (matches PROFILE_EDITABLE_FIELDS in profile_service): | |
| first_name, last_name, bio, country, state, city, address, avatar | |
| Extra output fields (computed): | |
| user_id → str(uuid) | |
| identifying_info → str | |
| phone_display → E.164 string | null (read-only convenience field) | |
| avatar_url → Cloudinary URL string | null | |
| properties: | |
| first_name: | |
| type: string | |
| nullable: true | |
| last_name: | |
| type: string | |
| nullable: true | |
| bio: | |
| type: string | |
| description: User's biography. | |
| country: | |
| type: string | |
| description: User's country. | |
| maxLength: 100 | |
| state: | |
| type: string | |
| description: User's state or province. | |
| maxLength: 100 | |
| city: | |
| type: string | |
| description: User's city. | |
| maxLength: 100 | |
| address: | |
| type: string | |
| description: User's street address. | |
| maxLength: 255 | |
| avatar: | |
| type: string | |
| minLength: 1 | |
| nullable: true | |
| description: 'Cloudinary image public_id. Set via the /api/v1/upload/presign/ | |
| → direct upload → webhook flow. Use .url in serializers to retrieve the | |
| full HTTPS secure_url. In admin: use the file picker widget to upload | |
| directly to Cloudinary.' | |
| AuthUserRegistration: | |
| type: object | |
| description: |- | |
| Serializer for creating a new user account. | |
| Validation Logic: | |
| - Enforces One-of-Email-or-Phone. | |
| - Password strength validation via Django standard. | |
| - Duplicate check against active and soft-deleted pools. | |
| Security: | |
| - Atomic transaction check to prevent race-condition duplicates. | |
| properties: | |
| email: | |
| type: string | |
| format: email | |
| description: User's email address | |
| phone: | |
| type: string | |
| description: User's phone number | |
| role: | |
| allOf: | |
| - $ref: '#/components/schemas/Role09fEnum' | |
| description: 'User''s role: ''vendor'' or ''client''' | |
| first_name: | |
| type: string | |
| description: User's first name | |
| maxLength: 150 | |
| last_name: | |
| type: string | |
| description: User's last name | |
| maxLength: 150 | |
| required: | |
| - role | |
| AuthUserRegistrationRequest: | |
| type: object | |
| description: |- | |
| Serializer for creating a new user account. | |
| Validation Logic: | |
| - Enforces One-of-Email-or-Phone. | |
| - Password strength validation via Django standard. | |
| - Duplicate check against active and soft-deleted pools. | |
| Security: | |
| - Atomic transaction check to prevent race-condition duplicates. | |
| properties: | |
| email: | |
| type: string | |
| format: email | |
| description: User's email address | |
| phone: | |
| type: string | |
| description: User's phone number | |
| role: | |
| allOf: | |
| - $ref: '#/components/schemas/Role09fEnum' | |
| description: 'User''s role: ''vendor'' or ''client''' | |
| first_name: | |
| type: string | |
| description: User's first name | |
| maxLength: 150 | |
| last_name: | |
| type: string | |
| description: User's last name | |
| maxLength: 150 | |
| password: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: User's password | |
| password2: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: Confirm user's password | |
| required: | |
| - password | |
| - password2 | |
| - role | |
| BankAccountCreate: | |
| type: object | |
| properties: | |
| account_number: | |
| type: string | |
| pattern: ^\d{10}$ | |
| bank_code: | |
| type: string | |
| maxLength: 10 | |
| bank_name: | |
| type: string | |
| maxLength: 150 | |
| account_name: | |
| type: string | |
| description: Account holder name as resolved by Paystack. | |
| maxLength: 200 | |
| required: | |
| - account_name | |
| - account_number | |
| - bank_code | |
| - bank_name | |
| BankAccountCreateRequest: | |
| type: object | |
| properties: | |
| account_number: | |
| type: string | |
| minLength: 1 | |
| pattern: ^\d{10}$ | |
| bank_code: | |
| type: string | |
| minLength: 1 | |
| maxLength: 10 | |
| bank_name: | |
| type: string | |
| minLength: 1 | |
| maxLength: 150 | |
| account_name: | |
| type: string | |
| minLength: 1 | |
| description: Account holder name as resolved by Paystack. | |
| maxLength: 200 | |
| required: | |
| - account_name | |
| - account_number | |
| - bank_code | |
| - bank_name | |
| BankAccountOutput: | |
| type: object | |
| description: Safe serializer — never returns full account_number or enc bytes. | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| bank_name: | |
| type: string | |
| bank_code: | |
| type: string | |
| account_name: | |
| type: string | |
| account_last4: | |
| type: string | |
| masked_account: | |
| type: string | |
| paystack_recipient_code: | |
| type: string | |
| kyc_name_matched: | |
| type: boolean | |
| is_default: | |
| type: boolean | |
| verification_status: | |
| type: string | |
| is_verified: | |
| type: boolean | |
| created_at: | |
| type: string | |
| format: date-time | |
| required: | |
| - account_last4 | |
| - account_name | |
| - bank_code | |
| - bank_name | |
| - created_at | |
| - id | |
| - is_default | |
| - is_verified | |
| - kyc_name_matched | |
| - masked_account | |
| - paystack_recipient_code | |
| - verification_status | |
| BankAccountResolve: | |
| type: object | |
| properties: | |
| account_number: | |
| type: string | |
| pattern: ^\d{10}$ | |
| bank_code: | |
| type: string | |
| pattern: ^\d{3,10}$ | |
| required: | |
| - account_number | |
| - bank_code | |
| BankAccountResolveRequest: | |
| type: object | |
| properties: | |
| account_number: | |
| type: string | |
| minLength: 1 | |
| pattern: ^\d{10}$ | |
| bank_code: | |
| type: string | |
| minLength: 1 | |
| pattern: ^\d{3,10}$ | |
| required: | |
| - account_number | |
| - bank_code | |
| BespokeConsultationRequestRequest: | |
| type: object | |
| description: Serializer for booking bespoke tailoring consultation. | |
| properties: | |
| tailoring_type: | |
| type: string | |
| minLength: 1 | |
| description: Required bespoke item type (e.g. suit, gown, coat) | |
| preferred_date: | |
| type: string | |
| format: date | |
| description: Preferred date | |
| preferred_time: | |
| type: string | |
| minLength: 1 | |
| description: Preferred time slot | |
| urgency: | |
| allOf: | |
| - $ref: '#/components/schemas/UrgencyEnum' | |
| default: medium | |
| description: Urgency level | |
| design_details: | |
| type: string | |
| minLength: 1 | |
| description: Details of design ideas or reference requests | |
| BlankEnum: | |
| enum: | |
| - '' | |
| BusinessMetric: | |
| type: object | |
| properties: | |
| id: | |
| type: integer | |
| readOnly: true | |
| metric_name: | |
| type: string | |
| title: Business Metric Name | |
| maxLength: 100 | |
| value: | |
| type: number | |
| format: double | |
| period_start: | |
| type: string | |
| format: date-time | |
| period_end: | |
| type: string | |
| format: date-time | |
| metadata: {} | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - created_at | |
| - id | |
| - metric_name | |
| - period_end | |
| - period_start | |
| - value | |
| CashConfirmationConfirm: | |
| type: object | |
| properties: | |
| order_id: | |
| type: string | |
| maxLength: 120 | |
| client_token: | |
| type: string | |
| maxLength: 255 | |
| required: | |
| - client_token | |
| - order_id | |
| CashConfirmationConfirmRequest: | |
| type: object | |
| properties: | |
| order_id: | |
| type: string | |
| minLength: 1 | |
| maxLength: 120 | |
| client_token: | |
| type: string | |
| minLength: 1 | |
| maxLength: 255 | |
| required: | |
| - client_token | |
| - order_id | |
| CashConfirmationCreate: | |
| type: object | |
| properties: | |
| order_id: | |
| type: string | |
| maxLength: 120 | |
| required: | |
| - order_id | |
| CashConfirmationCreateRequest: | |
| type: object | |
| properties: | |
| order_id: | |
| type: string | |
| minLength: 1 | |
| maxLength: 120 | |
| required: | |
| - order_id | |
| CashConfirmationResend: | |
| type: object | |
| properties: | |
| order_id: | |
| type: string | |
| maxLength: 120 | |
| required: | |
| - order_id | |
| CashConfirmationResendRequest: | |
| type: object | |
| properties: | |
| order_id: | |
| type: string | |
| minLength: 1 | |
| maxLength: 120 | |
| required: | |
| - order_id | |
| CashPaymentModeEnum: | |
| enum: | |
| - disabled | |
| - cod | |
| - pay_at_shop | |
| - both | |
| type: string | |
| CatalogBlogMedia: | |
| type: object | |
| description: |- | |
| Read-optimised serialiser for BlogMedia gallery items. | |
| Exposes derived `public_id` and `image_url` fields sourced from | |
| the Cloudinary CloudinaryField. The raw `image` (CloudinaryField) | |
| is intentionally omitted from `fields` to avoid the DRF assertion | |
| that fires when a model property shares a name with a declared | |
| SerializerMethodField (image_url). | |
| Architecture note: | |
| ─ Uploads use the two-phase direct-upload pattern: | |
| 1. Frontend → POST /api/v1/upload/presign/ → signed token | |
| 2. Frontend POSTs file directly to Cloudinary (bypasses Django) | |
| 3. Cloudinary webhook → Celery task reconciles public_id here | |
| ─ `image_url` returns the full HTTPS secure_url from Cloudinary. | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| public_id: | |
| type: string | |
| readOnly: true | |
| image_url: | |
| type: string | |
| readOnly: true | |
| alt_text: | |
| type: string | |
| maxLength: 180 | |
| sort_order: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: 0 | |
| format: int64 | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was created. | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was last updated. | |
| required: | |
| - created_at | |
| - id | |
| - image_url | |
| - public_id | |
| - updated_at | |
| CatalogBlogMediaRequest: | |
| type: object | |
| description: |- | |
| Read-optimised serialiser for BlogMedia gallery items. | |
| Exposes derived `public_id` and `image_url` fields sourced from | |
| the Cloudinary CloudinaryField. The raw `image` (CloudinaryField) | |
| is intentionally omitted from `fields` to avoid the DRF assertion | |
| that fires when a model property shares a name with a declared | |
| SerializerMethodField (image_url). | |
| Architecture note: | |
| ─ Uploads use the two-phase direct-upload pattern: | |
| 1. Frontend → POST /api/v1/upload/presign/ → signed token | |
| 2. Frontend POSTs file directly to Cloudinary (bypasses Django) | |
| 3. Cloudinary webhook → Celery task reconciles public_id here | |
| ─ `image_url` returns the full HTTPS secure_url from Cloudinary. | |
| properties: | |
| alt_text: | |
| type: string | |
| maxLength: 180 | |
| sort_order: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: 0 | |
| format: int64 | |
| CatalogBlogPost: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| author: | |
| type: string | |
| format: uuid | |
| description: Author is retained as nullable to preserve published history. | |
| readOnly: true | |
| nullable: true | |
| author_name: | |
| type: string | |
| readOnly: true | |
| category: | |
| type: string | |
| format: uuid | |
| description: Optional catalog category used for discovery and SEO. | |
| nullable: true | |
| category_name: | |
| type: string | |
| readOnly: true | |
| title: | |
| type: string | |
| maxLength: 255 | |
| slug: | |
| type: string | |
| readOnly: true | |
| pattern: ^[-a-zA-Z0-9_]+$ | |
| excerpt: | |
| type: string | |
| content: | |
| type: string | |
| featured_image: | |
| type: string | |
| nullable: true | |
| description: Featured post image (public_id). | |
| featured_image_url: | |
| type: string | |
| readOnly: true | |
| image_url: | |
| type: string | |
| readOnly: true | |
| gallery_media: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/CatalogBlogMedia' | |
| readOnly: true | |
| status: | |
| $ref: '#/components/schemas/CatalogBlogPostStatusEnum' | |
| tags: {} | |
| seo_title: | |
| type: string | |
| maxLength: 180 | |
| seo_description: | |
| type: string | |
| maxLength: 320 | |
| is_featured: | |
| type: boolean | |
| published_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| nullable: true | |
| view_count: | |
| type: integer | |
| readOnly: true | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was created. | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was last updated. | |
| required: | |
| - author | |
| - author_name | |
| - category_name | |
| - content | |
| - created_at | |
| - featured_image_url | |
| - gallery_media | |
| - id | |
| - image_url | |
| - published_at | |
| - slug | |
| - title | |
| - updated_at | |
| - view_count | |
| CatalogBlogPostRequest: | |
| type: object | |
| properties: | |
| category: | |
| type: string | |
| format: uuid | |
| description: Optional catalog category used for discovery and SEO. | |
| nullable: true | |
| title: | |
| type: string | |
| minLength: 1 | |
| maxLength: 255 | |
| excerpt: | |
| type: string | |
| content: | |
| type: string | |
| minLength: 1 | |
| featured_image: | |
| type: string | |
| minLength: 1 | |
| nullable: true | |
| description: Featured post image (public_id). | |
| status: | |
| $ref: '#/components/schemas/CatalogBlogPostStatusEnum' | |
| tags: {} | |
| seo_title: | |
| type: string | |
| maxLength: 180 | |
| seo_description: | |
| type: string | |
| maxLength: 320 | |
| is_featured: | |
| type: boolean | |
| required: | |
| - content | |
| - title | |
| CatalogBlogPostStatusEnum: | |
| enum: | |
| - draft | |
| - review | |
| - published | |
| - archived | |
| type: string | |
| CatalogBrand: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| name: | |
| type: string | |
| readOnly: true | |
| title: | |
| type: string | |
| maxLength: 100 | |
| slug: | |
| type: string | |
| readOnly: true | |
| nullable: true | |
| pattern: ^[-a-zA-Z0-9_]+$ | |
| description: | |
| type: string | |
| nullable: true | |
| image: | |
| type: string | |
| nullable: true | |
| description: Cloudinary image public_id. Set via the /api/v1/upload/presign/ | |
| → direct upload → webhook flow. Use .url in serializers to retrieve the | |
| full HTTPS secure_url. | |
| image_url: | |
| type: string | |
| readOnly: true | |
| active: | |
| type: boolean | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was created. | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was last updated. | |
| required: | |
| - created_at | |
| - id | |
| - image_url | |
| - name | |
| - slug | |
| - title | |
| - updated_at | |
| CatalogBrandRequest: | |
| type: object | |
| properties: | |
| title: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| description: | |
| type: string | |
| nullable: true | |
| image: | |
| type: string | |
| minLength: 1 | |
| nullable: true | |
| description: Cloudinary image public_id. Set via the /api/v1/upload/presign/ | |
| → direct upload → webhook flow. Use .url in serializers to retrieve the | |
| full HTTPS secure_url. | |
| active: | |
| type: boolean | |
| required: | |
| - title | |
| CatalogCategory: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| name: | |
| type: string | |
| maxLength: 100 | |
| title: | |
| type: string | |
| readOnly: true | |
| slug: | |
| type: string | |
| readOnly: true | |
| nullable: true | |
| pattern: ^[-a-zA-Z0-9_]+$ | |
| image: | |
| type: string | |
| nullable: true | |
| description: Cloudinary image public_id. Set via the /api/v1/upload/presign/ | |
| → direct upload → webhook flow. Use .url in serializers to retrieve the | |
| full HTTPS secure_url. | |
| image_url: | |
| type: string | |
| readOnly: true | |
| is_deleted: | |
| type: boolean | |
| description: Flag indicating if the record is soft-deleted. | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was created. | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was last updated. | |
| required: | |
| - created_at | |
| - id | |
| - image_url | |
| - name | |
| - slug | |
| - title | |
| - updated_at | |
| CatalogCategoryRequest: | |
| type: object | |
| properties: | |
| name: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| image: | |
| type: string | |
| minLength: 1 | |
| nullable: true | |
| description: Cloudinary image public_id. Set via the /api/v1/upload/presign/ | |
| → direct upload → webhook flow. Use .url in serializers to retrieve the | |
| full HTTPS secure_url. | |
| is_deleted: | |
| type: boolean | |
| description: Flag indicating if the record is soft-deleted. | |
| required: | |
| - name | |
| CatalogCollection: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| name: | |
| type: string | |
| readOnly: true | |
| title: | |
| type: string | |
| nullable: true | |
| maxLength: 255 | |
| slug: | |
| type: string | |
| readOnly: true | |
| nullable: true | |
| pattern: ^[-a-zA-Z0-9_]+$ | |
| sub_title: | |
| type: string | |
| nullable: true | |
| maxLength: 255 | |
| description: | |
| type: string | |
| nullable: true | |
| image: | |
| type: string | |
| nullable: true | |
| description: Main collection thumbnail image (public_id). | |
| image_url: | |
| type: string | |
| readOnly: true | |
| background_image: | |
| type: string | |
| nullable: true | |
| description: Hero background image (public_id). | |
| background_image_url: | |
| type: string | |
| readOnly: true | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was created. | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was last updated. | |
| required: | |
| - background_image_url | |
| - created_at | |
| - id | |
| - image_url | |
| - name | |
| - slug | |
| - updated_at | |
| CatalogCollectionRequest: | |
| type: object | |
| properties: | |
| title: | |
| type: string | |
| nullable: true | |
| maxLength: 255 | |
| sub_title: | |
| type: string | |
| nullable: true | |
| maxLength: 255 | |
| description: | |
| type: string | |
| nullable: true | |
| image: | |
| type: string | |
| minLength: 1 | |
| nullable: true | |
| description: Main collection thumbnail image (public_id). | |
| background_image: | |
| type: string | |
| minLength: 1 | |
| nullable: true | |
| description: Hero background image (public_id). | |
| ChatbotResponseData: | |
| type: object | |
| description: Serializer for formatted chatbot responses. | |
| properties: | |
| content: | |
| type: string | |
| description: Response content | |
| message_type: | |
| type: string | |
| description: Message type | |
| response_data: | |
| description: Structured response data | |
| ai_confidence: | |
| type: number | |
| format: double | |
| description: AI confidence score | |
| processing_time: | |
| type: number | |
| format: double | |
| description: Processing time in seconds | |
| quick_replies: | |
| type: array | |
| items: | |
| type: object | |
| additionalProperties: {} | |
| description: Suggested quick replies | |
| required: | |
| - content | |
| - message_type | |
| ChatbotSession: | |
| type: object | |
| description: Serializer for chatbot sessions. | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| user: | |
| allOf: | |
| - $ref: '#/components/schemas/UserBasic' | |
| readOnly: true | |
| session_type: | |
| $ref: '#/components/schemas/SessionTypeEnum' | |
| status: | |
| $ref: '#/components/schemas/ChatbotSessionStatusEnum' | |
| context_data: | |
| description: Contextual info to maintain conversation state | |
| started_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| last_activity: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| ended_at: | |
| type: string | |
| format: date-time | |
| nullable: true | |
| expires_at: | |
| type: string | |
| format: date-time | |
| nullable: true | |
| duration: | |
| type: string | |
| readOnly: true | |
| is_active: | |
| type: string | |
| readOnly: true | |
| conversation_count: | |
| type: string | |
| readOnly: true | |
| metadata: {} | |
| required: | |
| - conversation_count | |
| - duration | |
| - id | |
| - is_active | |
| - last_activity | |
| - session_type | |
| - started_at | |
| - user | |
| ChatbotSessionRequest: | |
| type: object | |
| description: Serializer for chatbot sessions. | |
| properties: | |
| session_type: | |
| $ref: '#/components/schemas/SessionTypeEnum' | |
| status: | |
| $ref: '#/components/schemas/ChatbotSessionStatusEnum' | |
| context_data: | |
| description: Contextual info to maintain conversation state | |
| ended_at: | |
| type: string | |
| format: date-time | |
| nullable: true | |
| expires_at: | |
| type: string | |
| format: date-time | |
| nullable: true | |
| metadata: {} | |
| required: | |
| - session_type | |
| ChatbotSessionStatusEnum: | |
| enum: | |
| - active | |
| - paused | |
| - completed | |
| - expired | |
| type: string | |
| ClientAddress: | |
| type: object | |
| description: Read/Write serializer for ClientAddress. | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| label: | |
| type: string | |
| description: 'Short label: ''Home'', ''Office'', or ''Mum\''s place''.' | |
| maxLength: 80 | |
| full_name: | |
| type: string | |
| maxLength: 150 | |
| phone: | |
| type: string | |
| maxLength: 30 | |
| street_address: | |
| type: string | |
| description: Street, house number, landmark. | |
| city: | |
| type: string | |
| maxLength: 100 | |
| state: | |
| type: string | |
| maxLength: 100 | |
| country: | |
| type: string | |
| maxLength: 100 | |
| postal_code: | |
| type: string | |
| maxLength: 20 | |
| is_default: | |
| type: boolean | |
| description: True if this is the primary address shown at checkout. | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was created. | |
| required: | |
| - city | |
| - created_at | |
| - id | |
| - state | |
| - street_address | |
| ClientAddressRequest: | |
| type: object | |
| description: Read/Write serializer for ClientAddress. | |
| properties: | |
| label: | |
| type: string | |
| description: 'Short label: ''Home'', ''Office'', or ''Mum\''s place''.' | |
| maxLength: 80 | |
| full_name: | |
| type: string | |
| maxLength: 150 | |
| phone: | |
| type: string | |
| maxLength: 30 | |
| street_address: | |
| type: string | |
| minLength: 1 | |
| description: Street, house number, landmark. | |
| city: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| state: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| country: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| postal_code: | |
| type: string | |
| maxLength: 20 | |
| is_default: | |
| type: boolean | |
| description: True if this is the primary address shown at checkout. | |
| required: | |
| - city | |
| - state | |
| - street_address | |
| ClientCartOrder: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| readOnly: true | |
| oid: | |
| type: string | |
| readOnly: true | |
| sub_total: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,10}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| shipping_amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,10}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| service_fee: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,10}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| total: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,10}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| payment_status: | |
| type: string | |
| readOnly: true | |
| order_status: | |
| type: string | |
| readOnly: true | |
| delivery_status: | |
| type: string | |
| readOnly: true | |
| tracking_id: | |
| type: string | |
| readOnly: true | |
| date: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| orderitem: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/ClientOrderItem' | |
| readOnly: true | |
| required: | |
| - date | |
| - delivery_status | |
| - id | |
| - oid | |
| - order_status | |
| - orderitem | |
| - payment_status | |
| - service_fee | |
| - shipping_amount | |
| - sub_total | |
| - total | |
| - tracking_id | |
| ClientOrderItem: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| readOnly: true | |
| product: | |
| type: string | |
| readOnly: true | |
| product_title: | |
| type: string | |
| readOnly: true | |
| product_image: | |
| type: string | |
| readOnly: true | |
| qty: | |
| type: integer | |
| readOnly: true | |
| price: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,10}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| sub_total: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,10}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| shipping_amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,10}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| service_fee: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,10}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| total: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,10}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| date: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - date | |
| - id | |
| - price | |
| - product | |
| - product_image | |
| - product_title | |
| - qty | |
| - service_fee | |
| - shipping_amount | |
| - sub_total | |
| - total | |
| ClientProfileOutput: | |
| type: object | |
| description: Full read-only profile serializer — used in GET /profile/ responses. | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| user_id: | |
| type: string | |
| readOnly: true | |
| user_email: | |
| type: string | |
| readOnly: true | |
| bio: | |
| type: string | |
| readOnly: true | |
| description: Short personal bio (max 500 chars). | |
| default_shipping_address: | |
| type: string | |
| readOnly: true | |
| description: Default shipping address for checkout. | |
| state: | |
| type: string | |
| readOnly: true | |
| country: | |
| type: string | |
| readOnly: true | |
| preferred_size: | |
| allOf: | |
| - $ref: '#/components/schemas/PreferredSizeEnum' | |
| readOnly: true | |
| description: Preferred clothing size. | |
| style_preferences: | |
| readOnly: true | |
| description: 'Style tags: ["casual", "afrocentric", "formal"]. Used by AI | |
| engine.' | |
| favourite_colours: | |
| readOnly: true | |
| description: Favourite colour hex codes or names. | |
| total_orders: | |
| type: integer | |
| readOnly: true | |
| total_spent_ngn: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,12}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| is_profile_complete: | |
| type: boolean | |
| readOnly: true | |
| description: True once size, address, and style preferences are filled in. | |
| email_notifications_enabled: | |
| type: boolean | |
| readOnly: true | |
| description: Receive order and promo email notifications. | |
| sms_notifications_enabled: | |
| type: boolean | |
| readOnly: true | |
| description: Receive SMS alerts for order updates. | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was created. | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was last updated. | |
| addresses: | |
| type: array | |
| items: {} | |
| readOnly: true | |
| required: | |
| - addresses | |
| - bio | |
| - country | |
| - created_at | |
| - default_shipping_address | |
| - email_notifications_enabled | |
| - favourite_colours | |
| - id | |
| - is_profile_complete | |
| - preferred_size | |
| - sms_notifications_enabled | |
| - state | |
| - style_preferences | |
| - total_orders | |
| - total_spent_ngn | |
| - updated_at | |
| - user_email | |
| - user_id | |
| ClientProfileUpdate: | |
| type: object | |
| description: |- | |
| Input-only serializer for PATCH /profile/ requests. | |
| All fields are optional — clients send only what they want to change. | |
| properties: | |
| bio: | |
| type: string | |
| maxLength: 500 | |
| default_shipping_address: | |
| type: string | |
| state: | |
| type: string | |
| maxLength: 100 | |
| country: | |
| type: string | |
| maxLength: 100 | |
| preferred_size: | |
| oneOf: | |
| - $ref: '#/components/schemas/PreferredSizeEnum' | |
| - $ref: '#/components/schemas/BlankEnum' | |
| style_preferences: | |
| type: array | |
| items: | |
| type: string | |
| favourite_colours: | |
| type: array | |
| items: | |
| type: string | |
| email_notifications_enabled: | |
| type: boolean | |
| sms_notifications_enabled: | |
| type: boolean | |
| ClientProfileUpdateRequest: | |
| type: object | |
| description: |- | |
| Input-only serializer for PATCH /profile/ requests. | |
| All fields are optional — clients send only what they want to change. | |
| properties: | |
| bio: | |
| type: string | |
| maxLength: 500 | |
| default_shipping_address: | |
| type: string | |
| state: | |
| type: string | |
| maxLength: 100 | |
| country: | |
| type: string | |
| maxLength: 100 | |
| preferred_size: | |
| oneOf: | |
| - $ref: '#/components/schemas/PreferredSizeEnum' | |
| - $ref: '#/components/schemas/BlankEnum' | |
| style_preferences: | |
| type: array | |
| items: | |
| type: string | |
| minLength: 1 | |
| favourite_colours: | |
| type: array | |
| items: | |
| type: string | |
| minLength: 1 | |
| email_notifications_enabled: | |
| type: boolean | |
| sms_notifications_enabled: | |
| type: boolean | |
| ClientReview: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| readOnly: true | |
| user: | |
| type: string | |
| readOnly: true | |
| user_full_name: | |
| type: string | |
| readOnly: true | |
| user_avatar: | |
| type: string | |
| readOnly: true | |
| product: | |
| type: string | |
| readOnly: true | |
| product_title: | |
| type: string | |
| readOnly: true | |
| review: | |
| type: string | |
| maxLength: 2000 | |
| rating: | |
| type: integer | |
| maximum: 5 | |
| minimum: 1 | |
| active: | |
| type: boolean | |
| readOnly: true | |
| date: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - active | |
| - date | |
| - id | |
| - product | |
| - product_title | |
| - rating | |
| - review | |
| - user | |
| - user_avatar | |
| - user_full_name | |
| ClientReviewRequest: | |
| type: object | |
| properties: | |
| product_id: | |
| type: string | |
| format: uuid | |
| writeOnly: true | |
| review: | |
| type: string | |
| minLength: 1 | |
| maxLength: 2000 | |
| rating: | |
| type: integer | |
| maximum: 5 | |
| minimum: 1 | |
| required: | |
| - rating | |
| - review | |
| ClientWishlist: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| readOnly: true | |
| product: | |
| allOf: | |
| - $ref: '#/components/schemas/WishlistProduct' | |
| readOnly: true | |
| date: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - date | |
| - id | |
| - product | |
| CommonContactSubmission: | |
| type: object | |
| description: Input serializer for POST /api/v1/public/contact/. | |
| properties: | |
| full_name: | |
| type: string | |
| maxLength: 120 | |
| minLength: 2 | |
| email: | |
| type: string | |
| format: email | |
| phone: | |
| type: string | |
| maxLength: 40 | |
| subject: | |
| type: string | |
| maxLength: 120 | |
| message: | |
| type: string | |
| maxLength: 5000 | |
| minLength: 10 | |
| vendor: | |
| type: string | |
| maxLength: 120 | |
| inquiry_type: | |
| type: string | |
| maxLength: 60 | |
| page_url: | |
| type: string | |
| format: uri | |
| maxLength: 500 | |
| required: | |
| - full_name | |
| - message | |
| CommonContactSubmissionRequest: | |
| type: object | |
| description: Input serializer for POST /api/v1/public/contact/. | |
| properties: | |
| full_name: | |
| type: string | |
| minLength: 2 | |
| maxLength: 120 | |
| email: | |
| type: string | |
| format: email | |
| minLength: 1 | |
| phone: | |
| type: string | |
| maxLength: 40 | |
| subject: | |
| type: string | |
| maxLength: 120 | |
| message: | |
| type: string | |
| minLength: 10 | |
| maxLength: 5000 | |
| vendor: | |
| type: string | |
| maxLength: 120 | |
| inquiry_type: | |
| type: string | |
| maxLength: 60 | |
| page_url: | |
| type: string | |
| format: uri | |
| maxLength: 500 | |
| required: | |
| - full_name | |
| - message | |
| CommonNewsletterSignup: | |
| type: object | |
| description: Input serializer for POST /api/v1/public/newsletter/. | |
| properties: | |
| email: | |
| type: string | |
| format: email | |
| source: | |
| type: string | |
| default: newsletter | |
| maxLength: 80 | |
| required: | |
| CommonNewsletterSignupRequest: | |
| type: object | |
| description: Input serializer for POST /api/v1/public/newsletter/. | |
| properties: | |
| email: | |
| type: string | |
| format: email | |
| minLength: 1 | |
| source: | |
| type: string | |
| default: newsletter | |
| maxLength: 80 | |
| required: | |
| CommonPresignRequest: | |
| type: object | |
| description: |- | |
| Input serializer for POST /api/v1/upload/presign/ | |
| Validates the ``asset_type`` field before passing to | |
| ``generate_cloudinary_upload_params()``. Replaces the previous raw | |
| ``request.data.get("asset_type", "avatar")`` pattern with typed DRF | |
| validation that surfaces a proper 400 with field-level errors. | |
| Valid asset_types are derived dynamically from _ASSET_CONFIGS so the | |
| serializer stays in sync if new asset types are added. | |
| properties: | |
| asset_type: | |
| allOf: | |
| - $ref: '#/components/schemas/AssetTypeEnum' | |
| default: avatar | |
| description: 'Type of Cloudinary asset to upload. One of: avatar, product_image, | |
| product_video, measurement.' | |
| CommonPresignRequestRequest: | |
| type: object | |
| description: |- | |
| Input serializer for POST /api/v1/upload/presign/ | |
| Validates the ``asset_type`` field before passing to | |
| ``generate_cloudinary_upload_params()``. Replaces the previous raw | |
| ``request.data.get("asset_type", "avatar")`` pattern with typed DRF | |
| validation that surfaces a proper 400 with field-level errors. | |
| Valid asset_types are derived dynamically from _ASSET_CONFIGS so the | |
| serializer stays in sync if new asset types are added. | |
| properties: | |
| asset_type: | |
| allOf: | |
| - $ref: '#/components/schemas/AssetTypeEnum' | |
| default: avatar | |
| description: 'Type of Cloudinary asset to upload. One of: avatar, product_image, | |
| product_video, measurement.' | |
| CommonWaitlistSignup: | |
| type: object | |
| description: Input serializer for POST /api/v1/public/waitlist/. | |
| properties: | |
| email: | |
| type: string | |
| format: email | |
| source: | |
| type: string | |
| default: waitlist | |
| maxLength: 80 | |
| required: | |
| CommonWaitlistSignupRequest: | |
| type: object | |
| description: Input serializer for POST /api/v1/public/waitlist/. | |
| properties: | |
| email: | |
| type: string | |
| format: email | |
| minLength: 1 | |
| source: | |
| type: string | |
| default: waitlist | |
| maxLength: 80 | |
| required: | |
| Conversation: | |
| type: object | |
| description: Serializer for conversations including message history. | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| session: | |
| allOf: | |
| - $ref: '#/components/schemas/ChatbotSession' | |
| readOnly: true | |
| conversation_type: | |
| $ref: '#/components/schemas/ConversationTypeEnum' | |
| title: | |
| type: string | |
| maxLength: 200 | |
| is_active: | |
| type: boolean | |
| started_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| summary: | |
| type: string | |
| tags: {} | |
| messages: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/Message' | |
| readOnly: true | |
| message_count: | |
| type: string | |
| readOnly: true | |
| last_message_time: | |
| type: string | |
| readOnly: true | |
| metadata: {} | |
| required: | |
| - id | |
| - last_message_time | |
| - message_count | |
| - messages | |
| - session | |
| - started_at | |
| - updated_at | |
| ConversationRequest: | |
| type: object | |
| description: Serializer for conversations including message history. | |
| properties: | |
| conversation_type: | |
| $ref: '#/components/schemas/ConversationTypeEnum' | |
| title: | |
| type: string | |
| maxLength: 200 | |
| is_active: | |
| type: boolean | |
| summary: | |
| type: string | |
| tags: {} | |
| metadata: {} | |
| ConversationTypeEnum: | |
| enum: | |
| - style_advice | |
| - size_recommendation | |
| - product_search | |
| - order_inquiry | |
| - general_support | |
| - general | |
| type: string | |
| DeliveryStatusEnum: | |
| enum: | |
| - pending | |
| - processing | |
| - shipped | |
| - fulfilled | |
| - cancelled | |
| type: string | |
| DeliveryStatusUpdate: | |
| type: object | |
| properties: | |
| delivery_status: | |
| type: string | |
| maxLength: 100 | |
| tracking_id: | |
| type: string | |
| maxLength: 255 | |
| DeliveryStatusUpdateRequest: | |
| type: object | |
| properties: | |
| delivery_status: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| tracking_id: | |
| type: string | |
| minLength: 1 | |
| maxLength: 255 | |
| DirectionEnum: | |
| enum: | |
| - inbound | |
| - outbound | |
| - internal | |
| type: string | |
| DisputeCreate: | |
| type: object | |
| properties: | |
| reason: | |
| type: string | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| required: | |
| - amount | |
| - reason | |
| DisputeCreateRequest: | |
| type: object | |
| properties: | |
| reason: | |
| type: string | |
| minLength: 1 | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| required: | |
| - amount | |
| - reason | |
| DocumentTypeEnum: | |
| enum: | |
| - nin_card | |
| - bvn_slip | |
| - passport | |
| - drivers_license | |
| - voters_card | |
| - selfie | |
| - cac_certificate | |
| - utility_bill | |
| type: string | |
| EnvironmentEnum: | |
| enum: | |
| - development | |
| - staging | |
| - production | |
| type: string | |
| EscrowHold: | |
| type: object | |
| properties: | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| reference: | |
| type: string | |
| maxLength: 120 | |
| order_id: | |
| type: string | |
| maxLength: 120 | |
| provider_reference: | |
| type: string | |
| maxLength: 120 | |
| required: | |
| - amount | |
| - reference | |
| EscrowHoldRequest: | |
| type: object | |
| properties: | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| reference: | |
| type: string | |
| minLength: 1 | |
| maxLength: 120 | |
| order_id: | |
| type: string | |
| maxLength: 120 | |
| provider_reference: | |
| type: string | |
| maxLength: 120 | |
| required: | |
| - amount | |
| - reference | |
| EscrowRefund: | |
| type: object | |
| properties: | |
| hold_reference: | |
| type: string | |
| maxLength: 120 | |
| required: | |
| - hold_reference | |
| EscrowRefundRequest: | |
| type: object | |
| properties: | |
| hold_reference: | |
| type: string | |
| minLength: 1 | |
| maxLength: 120 | |
| required: | |
| - hold_reference | |
| EscrowRelease: | |
| type: object | |
| properties: | |
| hold_reference: | |
| type: string | |
| maxLength: 120 | |
| vendor_user_id: | |
| type: string | |
| format: uuid | |
| commission_rate: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,1}(?:\.\d{0,4})?$ | |
| default: '0.1000' | |
| required: | |
| - hold_reference | |
| EscrowReleaseRequest: | |
| type: object | |
| properties: | |
| hold_reference: | |
| type: string | |
| minLength: 1 | |
| maxLength: 120 | |
| vendor_user_id: | |
| type: string | |
| format: uuid | |
| commission_rate: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,1}(?:\.\d{0,4})?$ | |
| default: '0.1000' | |
| required: | |
| - hold_reference | |
| GenderEnum: | |
| enum: | |
| - M | |
| - F | |
| - O | |
| type: string | |
| IntegrationCredential: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| provider: | |
| type: string | |
| format: uuid | |
| provider_name: | |
| type: string | |
| readOnly: true | |
| key_name: | |
| type: string | |
| maxLength: 100 | |
| masked_value: | |
| type: string | |
| readOnly: true | |
| is_encrypted: | |
| type: boolean | |
| environment: | |
| allOf: | |
| - $ref: '#/components/schemas/EnvironmentEnum' | |
| default: production | |
| is_active: | |
| type: boolean | |
| is_valid: | |
| type: boolean | |
| readOnly: true | |
| expires_at: | |
| type: string | |
| format: date-time | |
| nullable: true | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| created_by: | |
| type: string | |
| format: uuid | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| readOnly: true | |
| nullable: true | |
| required: | |
| - created_at | |
| - created_by | |
| - id | |
| - is_valid | |
| - key_name | |
| - masked_value | |
| - provider | |
| - provider_name | |
| - updated_at | |
| IntegrationCredentialRequest: | |
| type: object | |
| properties: | |
| provider: | |
| type: string | |
| format: uuid | |
| key_name: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| key_value: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: Stored in encrypted format. | |
| is_encrypted: | |
| type: boolean | |
| environment: | |
| allOf: | |
| - $ref: '#/components/schemas/EnvironmentEnum' | |
| default: production | |
| is_active: | |
| type: boolean | |
| expires_at: | |
| type: string | |
| format: date-time | |
| nullable: true | |
| required: | |
| - key_name | |
| - key_value | |
| - provider | |
| IntegrationLog: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| provider: | |
| type: string | |
| format: uuid | |
| provider_name: | |
| type: string | |
| readOnly: true | |
| log_level: | |
| $ref: '#/components/schemas/LogLevelEnum' | |
| service_name: | |
| type: string | |
| maxLength: 100 | |
| action: | |
| type: string | |
| maxLength: 100 | |
| request_data: {} | |
| response_data: {} | |
| error_message: | |
| type: string | |
| status_code: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| nullable: true | |
| duration_ms: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| nullable: true | |
| title: Duration (ms) | |
| user: | |
| type: string | |
| format: uuid | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| nullable: true | |
| user_name: | |
| type: string | |
| nullable: true | |
| readOnly: true | |
| ip_address: | |
| type: string | |
| nullable: true | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| title: Logged At | |
| required: | |
| - action | |
| - created_at | |
| - id | |
| - provider | |
| - provider_name | |
| - service_name | |
| - user_name | |
| IntegrationProvider: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| name: | |
| type: string | |
| title: Provider Name | |
| maxLength: 100 | |
| slug: | |
| type: string | |
| title: Unique Slug | |
| maxLength: 50 | |
| pattern: ^[-a-zA-Z0-9_]+$ | |
| provider_type: | |
| allOf: | |
| - $ref: '#/components/schemas/ProviderTypeEnum' | |
| title: Service Type | |
| status: | |
| $ref: '#/components/schemas/IntegrationProviderStatusEnum' | |
| description: | |
| type: string | |
| api_base_url: | |
| type: string | |
| format: uri | |
| maxLength: 200 | |
| documentation_url: | |
| type: string | |
| format: uri | |
| maxLength: 200 | |
| credentials_count: | |
| type: integer | |
| readOnly: true | |
| logs_count: | |
| type: integer | |
| readOnly: true | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - created_at | |
| - credentials_count | |
| - id | |
| - logs_count | |
| - name | |
| - provider_type | |
| - slug | |
| - updated_at | |
| IntegrationProviderRequest: | |
| type: object | |
| properties: | |
| name: | |
| type: string | |
| minLength: 1 | |
| title: Provider Name | |
| maxLength: 100 | |
| slug: | |
| type: string | |
| minLength: 1 | |
| title: Unique Slug | |
| maxLength: 50 | |
| pattern: ^[-a-zA-Z0-9_]+$ | |
| provider_type: | |
| allOf: | |
| - $ref: '#/components/schemas/ProviderTypeEnum' | |
| title: Service Type | |
| status: | |
| $ref: '#/components/schemas/IntegrationProviderStatusEnum' | |
| description: | |
| type: string | |
| api_base_url: | |
| type: string | |
| format: uri | |
| maxLength: 200 | |
| documentation_url: | |
| type: string | |
| format: uri | |
| maxLength: 200 | |
| required: | |
| - name | |
| - provider_type | |
| - slug | |
| IntegrationProviderStatusEnum: | |
| enum: | |
| - active | |
| - inactive | |
| - maintenance | |
| type: string | |
| KycDocument: | |
| type: object | |
| description: Read serializer for a single KYC document. | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| document_type: | |
| allOf: | |
| - $ref: '#/components/schemas/DocumentTypeEnum' | |
| readOnly: true | |
| document_number: | |
| type: string | |
| readOnly: true | |
| description: The actual document number, e.g. NIN (11 digits), BVN, passport | |
| number. Encrypt at-rest in production. | |
| secure_url: | |
| type: string | |
| format: uri | |
| readOnly: true | |
| description: Cloudinary secure_url returned after client-side upload. | |
| public_id: | |
| type: string | |
| readOnly: true | |
| description: Cloudinary public_id returned after client-side upload. | |
| provider_verified: | |
| type: boolean | |
| readOnly: true | |
| description: True if the external KYC provider confirms this document is | |
| valid. | |
| provider_response: | |
| readOnly: true | |
| description: Raw JSON result from external KYC provider for this document. | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was created. | |
| required: | |
| - created_at | |
| - document_number | |
| - document_type | |
| - id | |
| - provider_response | |
| - provider_verified | |
| - public_id | |
| - secure_url | |
| KycSubmission: | |
| type: object | |
| description: |- | |
| Read serializer for a KycSubmission including nested documents. | |
| Used for GET /api/v1/kyc/status/ and detail views. | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| user: | |
| type: string | |
| readOnly: true | |
| status: | |
| allOf: | |
| - $ref: '#/components/schemas/KycSubmissionStatusEnum' | |
| readOnly: true | |
| is_approved: | |
| type: boolean | |
| readOnly: true | |
| is_pending: | |
| type: boolean | |
| readOnly: true | |
| is_rejected: | |
| type: boolean | |
| readOnly: true | |
| can_resubmit: | |
| type: boolean | |
| readOnly: true | |
| review_notes: | |
| type: string | |
| readOnly: true | |
| provider_reference: | |
| type: string | |
| readOnly: true | |
| description: External KYC provider job/session reference ID. | |
| submitted_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| reviewed_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| nullable: true | |
| documents: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/KycDocument' | |
| readOnly: true | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was created. | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was last updated. | |
| required: | |
| - can_resubmit | |
| - created_at | |
| - documents | |
| - id | |
| - is_approved | |
| - is_pending | |
| - is_rejected | |
| - provider_reference | |
| - review_notes | |
| - reviewed_at | |
| - status | |
| - submitted_at | |
| - updated_at | |
| - user | |
| KycSubmissionStatusEnum: | |
| enum: | |
| - pending | |
| - in_review | |
| - approved | |
| - rejected | |
| - resubmit | |
| type: string | |
| LogLevelEnum: | |
| enum: | |
| - debug | |
| - info | |
| - warning | |
| - error | |
| - critical | |
| type: string | |
| LoginEvent: | |
| type: object | |
| description: |- | |
| Read serializer for LoginEvent — used by the login activity list. | |
| Analogous to Binance's "Login Activity" or Google's | |
| "Recent Security Events" dashboard panel. | |
| All UUID7 primary keys are serialized as strings. | |
| ``timestamp`` is an alias for ``created_at`` (audit-log convention). | |
| properties: | |
| id: | |
| type: string | |
| readOnly: true | |
| outcome: | |
| allOf: | |
| - $ref: '#/components/schemas/OutcomeEnum' | |
| readOnly: true | |
| description: Result of the login attempt. | |
| is_successful: | |
| type: boolean | |
| readOnly: true | |
| description: True iff the login attempt succeeded and tokens were issued. | |
| failure_reason: | |
| type: string | |
| readOnly: true | |
| description: 'Short machine-readable failure code: ''invalid_credentials'', | |
| ''account_inactive'', ''account_deleted'', ''rate_limited'', ''mfa_required'', | |
| etc.' | |
| auth_method: | |
| allOf: | |
| - $ref: '#/components/schemas/AuthMethodEnum' | |
| readOnly: true | |
| description: Authentication method used for this attempt. | |
| ip_address: | |
| type: string | |
| readOnly: true | |
| description: Client IP address (supports IPv4 and IPv6). | |
| country: | |
| type: string | |
| readOnly: true | |
| description: Country name derived from IP (via MaxMind / ipapi). | |
| country_code: | |
| type: string | |
| readOnly: true | |
| description: ISO 3166-1 alpha-2 country code (e.g. 'NG', 'US'). | |
| city: | |
| type: string | |
| readOnly: true | |
| description: City name (e.g. 'Lagos', 'San Francisco'). | |
| client_type: | |
| allOf: | |
| - $ref: '#/components/schemas/LoginEventClientTypeEnum' | |
| readOnly: true | |
| description: 'Derived from User-Agent: web / mobile / api / curl.' | |
| browser: | |
| type: string | |
| readOnly: true | |
| os: | |
| type: string | |
| readOnly: true | |
| device_type: | |
| type: string | |
| readOnly: true | |
| description: 'Device category: desktop, mobile, tablet, bot, etc.' | |
| risk_score: | |
| type: integer | |
| readOnly: true | |
| description: Risk score 0-100. ≥70 triggers a security alert. | |
| is_new_device: | |
| type: boolean | |
| readOnly: true | |
| description: True if this is the first time this device fingerprint was | |
| seen. | |
| is_new_country: | |
| type: boolean | |
| readOnly: true | |
| description: True if the login country is new for this user. | |
| is_tor_exit_node: | |
| type: boolean | |
| readOnly: true | |
| description: True if the IP is a known Tor exit node. | |
| timestamp: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - auth_method | |
| - browser | |
| - city | |
| - client_type | |
| - country | |
| - country_code | |
| - device_type | |
| - failure_reason | |
| - id | |
| - ip_address | |
| - is_new_country | |
| - is_new_device | |
| - is_successful | |
| - is_tor_exit_node | |
| - os | |
| - outcome | |
| - risk_score | |
| - timestamp | |
| LoginEventClientTypeEnum: | |
| enum: | |
| - web | |
| - mobile | |
| - api | |
| - curl | |
| - unknown | |
| type: string | |
| Message: | |
| type: object | |
| description: Serializer for messages. | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| sender_type: | |
| $ref: '#/components/schemas/SenderTypeEnum' | |
| message_type: | |
| $ref: '#/components/schemas/MessageTypeEnum' | |
| content: | |
| type: string | |
| minLength: 1 | |
| response_data: | |
| description: Structured options or response details | |
| ai_confidence: | |
| type: number | |
| format: double | |
| nullable: true | |
| description: Confidence score of AI response (0.0 to 1.0) | |
| processing_time: | |
| type: number | |
| format: double | |
| nullable: true | |
| description: Processing time in seconds | |
| is_sensitive: | |
| type: boolean | |
| description: Does the message contain sensitive info? | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| edited_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| nullable: true | |
| is_from_user: | |
| type: string | |
| readOnly: true | |
| is_from_bot: | |
| type: string | |
| readOnly: true | |
| metadata: {} | |
| required: | |
| - content | |
| - created_at | |
| - edited_at | |
| - id | |
| - is_from_bot | |
| - is_from_user | |
| - sender_type | |
| MessageRequest: | |
| type: object | |
| description: Serializer for messages. | |
| properties: | |
| sender_type: | |
| $ref: '#/components/schemas/SenderTypeEnum' | |
| message_type: | |
| $ref: '#/components/schemas/MessageTypeEnum' | |
| content: | |
| type: string | |
| minLength: 1 | |
| response_data: | |
| description: Structured options or response details | |
| ai_confidence: | |
| type: number | |
| format: double | |
| nullable: true | |
| description: Confidence score of AI response (0.0 to 1.0) | |
| processing_time: | |
| type: number | |
| format: double | |
| nullable: true | |
| description: Processing time in seconds | |
| is_sensitive: | |
| type: boolean | |
| description: Does the message contain sensitive info? | |
| metadata: {} | |
| required: | |
| - content | |
| - sender_type | |
| MessageTypeEnum: | |
| enum: | |
| - text | |
| - quick_reply | |
| - attachment | |
| - card | |
| - carousel | |
| - typing | |
| type: string | |
| Metric: | |
| type: object | |
| properties: | |
| id: | |
| type: integer | |
| readOnly: true | |
| name: | |
| type: string | |
| title: Metric Name | |
| description: Name identifier of the metric. | |
| maxLength: 255 | |
| metric_type: | |
| $ref: '#/components/schemas/MetricTypeEnum' | |
| value: | |
| type: number | |
| format: double | |
| description: Numeric value of the metric. | |
| tags: | |
| description: Categorization tags. | |
| timestamp: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - id | |
| - name | |
| - timestamp | |
| - value | |
| MetricTypeEnum: | |
| enum: | |
| - counter | |
| - gauge | |
| - histogram | |
| - timer | |
| type: string | |
| OperatorEnum: | |
| enum: | |
| - gt | |
| - gte | |
| - lt | |
| - lte | |
| - eq | |
| - ne | |
| type: string | |
| OutcomeEnum: | |
| enum: | |
| - success | |
| - failed | |
| - blocked | |
| - suspicious | |
| type: string | |
| OwnerTypeEnum: | |
| enum: | |
| - client | |
| - vendor | |
| - support | |
| - editor | |
| - moderator | |
| - admin | |
| - company | |
| type: string | |
| PaginatedAlertList: | |
| type: object | |
| required: | |
| - count | |
| - results | |
| properties: | |
| count: | |
| type: integer | |
| example: 123 | |
| next: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=4 | |
| previous: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=2 | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/Alert' | |
| PaginatedAlertRuleList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/AlertRule' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedAuthProtectedUserList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/AuthProtectedUser' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedBusinessMetricList: | |
| type: object | |
| required: | |
| - count | |
| - results | |
| properties: | |
| count: | |
| type: integer | |
| example: 123 | |
| next: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=4 | |
| previous: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=2 | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/BusinessMetric' | |
| PaginatedChatbotSessionList: | |
| type: object | |
| required: | |
| - count | |
| - results | |
| properties: | |
| count: | |
| type: integer | |
| example: 123 | |
| next: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=4 | |
| previous: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=2 | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/ChatbotSession' | |
| PaginatedClientAddressList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/ClientAddress' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedClientCartOrderList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/ClientCartOrder' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedConversationList: | |
| type: object | |
| required: | |
| - count | |
| - results | |
| properties: | |
| count: | |
| type: integer | |
| example: 123 | |
| next: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=4 | |
| previous: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=2 | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/Conversation' | |
| PaginatedIntegrationCredentialList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/IntegrationCredential' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedIntegrationLogList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/IntegrationLog' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedIntegrationProviderList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/IntegrationProvider' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedKycSubmissionList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/KycSubmission' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedLoginEventList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/LoginEvent' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedMessageList: | |
| type: object | |
| required: | |
| - count | |
| - results | |
| properties: | |
| count: | |
| type: integer | |
| example: 123 | |
| next: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=4 | |
| previous: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=2 | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/Message' | |
| PaginatedMetricList: | |
| type: object | |
| required: | |
| - count | |
| - results | |
| properties: | |
| count: | |
| type: integer | |
| example: 123 | |
| next: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=4 | |
| previous: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=2 | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/Metric' | |
| PaginatedPerformanceMetricList: | |
| type: object | |
| required: | |
| - count | |
| - results | |
| properties: | |
| count: | |
| type: integer | |
| example: 123 | |
| next: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=4 | |
| previous: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=2 | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/PerformanceMetric' | |
| PaginatedRateLimitRuleList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/RateLimitRule' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedReferenceBankList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/ReferenceBank' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedReferenceCityList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/ReferenceCity' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedReferenceCountryList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/ReferenceCountry' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedReferenceLgaList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/ReferenceLga' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedReferenceStateList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/ReferenceState' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedTransactionList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/Transaction' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedUserActivityList: | |
| type: object | |
| required: | |
| - count | |
| - results | |
| properties: | |
| count: | |
| type: integer | |
| example: 123 | |
| next: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=4 | |
| previous: | |
| type: string | |
| nullable: true | |
| format: uri | |
| example: http://api.example.org/accounts/?page=2 | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/UserActivity' | |
| PaginatedUserSessionList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/UserSession' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedWebhookEndpointList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/WebhookEndpoint' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PaginatedWebhookEventList: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| example: true | |
| count: | |
| type: integer | |
| nullable: true | |
| pages: | |
| type: integer | |
| nullable: true | |
| page: | |
| type: integer | |
| nullable: true | |
| page_size: | |
| type: integer | |
| next: | |
| type: string | |
| format: uri | |
| nullable: true | |
| previous: | |
| type: string | |
| format: uri | |
| nullable: true | |
| results: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/WebhookEvent' | |
| required: | |
| - success | |
| - count | |
| - next | |
| - previous | |
| - results | |
| PasswordChangeRequest: | |
| type: object | |
| description: |- | |
| Serializer for authenticated password change from the dashboard. | |
| Validates old password + new password match. | |
| properties: | |
| old_password: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: Current password | |
| new_password: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: New password | |
| confirm_password: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: Confirm new password | |
| required: | |
| - confirm_password | |
| - new_password | |
| - old_password | |
| PatchedAlertRuleRequest: | |
| type: object | |
| properties: | |
| name: | |
| type: string | |
| minLength: 1 | |
| title: Rule Name | |
| maxLength: 100 | |
| metric_name: | |
| type: string | |
| minLength: 1 | |
| maxLength: 255 | |
| operator: | |
| allOf: | |
| - $ref: '#/components/schemas/OperatorEnum' | |
| title: Comparison Operator | |
| threshold: | |
| type: number | |
| format: double | |
| severity: | |
| $ref: '#/components/schemas/SeverityEnum' | |
| is_active: | |
| type: boolean | |
| description: | |
| type: string | |
| PatchedAuthUserProfileRequest: | |
| type: object | |
| description: |- | |
| Full profile serializer for self-update (PATCH /api/v1/profile/me/). | |
| Read-only fields: | |
| id, member_id, email, phone, role, auth_provider, | |
| is_verified, is_active, is_staff, is_superuser, | |
| date_joined, last_login, password, groups, user_permissions | |
| Writable fields (matches PROFILE_EDITABLE_FIELDS in profile_service): | |
| first_name, last_name, bio, country, state, city, address, avatar | |
| Extra output fields (computed): | |
| user_id → str(uuid) | |
| identifying_info → str | |
| phone_display → E.164 string | null (read-only convenience field) | |
| avatar_url → Cloudinary URL string | null | |
| properties: | |
| first_name: | |
| type: string | |
| nullable: true | |
| last_name: | |
| type: string | |
| nullable: true | |
| bio: | |
| type: string | |
| description: User's biography. | |
| country: | |
| type: string | |
| description: User's country. | |
| maxLength: 100 | |
| state: | |
| type: string | |
| description: User's state or province. | |
| maxLength: 100 | |
| city: | |
| type: string | |
| description: User's city. | |
| maxLength: 100 | |
| address: | |
| type: string | |
| description: User's street address. | |
| maxLength: 255 | |
| avatar: | |
| type: string | |
| minLength: 1 | |
| nullable: true | |
| description: 'Cloudinary image public_id. Set via the /api/v1/upload/presign/ | |
| → direct upload → webhook flow. Use .url in serializers to retrieve the | |
| full HTTPS secure_url. In admin: use the file picker widget to upload | |
| directly to Cloudinary.' | |
| PatchedCatalogBlogPostRequest: | |
| type: object | |
| properties: | |
| category: | |
| type: string | |
| format: uuid | |
| description: Optional catalog category used for discovery and SEO. | |
| nullable: true | |
| title: | |
| type: string | |
| minLength: 1 | |
| maxLength: 255 | |
| excerpt: | |
| type: string | |
| content: | |
| type: string | |
| minLength: 1 | |
| featured_image: | |
| type: string | |
| minLength: 1 | |
| nullable: true | |
| description: Featured post image (public_id). | |
| status: | |
| $ref: '#/components/schemas/CatalogBlogPostStatusEnum' | |
| tags: {} | |
| seo_title: | |
| type: string | |
| maxLength: 180 | |
| seo_description: | |
| type: string | |
| maxLength: 320 | |
| is_featured: | |
| type: boolean | |
| PatchedCatalogBrandRequest: | |
| type: object | |
| properties: | |
| title: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| description: | |
| type: string | |
| nullable: true | |
| image: | |
| type: string | |
| minLength: 1 | |
| nullable: true | |
| description: Cloudinary image public_id. Set via the /api/v1/upload/presign/ | |
| → direct upload → webhook flow. Use .url in serializers to retrieve the | |
| full HTTPS secure_url. | |
| active: | |
| type: boolean | |
| PatchedCatalogCategoryRequest: | |
| type: object | |
| properties: | |
| name: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| image: | |
| type: string | |
| minLength: 1 | |
| nullable: true | |
| description: Cloudinary image public_id. Set via the /api/v1/upload/presign/ | |
| → direct upload → webhook flow. Use .url in serializers to retrieve the | |
| full HTTPS secure_url. | |
| is_deleted: | |
| type: boolean | |
| description: Flag indicating if the record is soft-deleted. | |
| PatchedCatalogCollectionRequest: | |
| type: object | |
| properties: | |
| title: | |
| type: string | |
| nullable: true | |
| maxLength: 255 | |
| sub_title: | |
| type: string | |
| nullable: true | |
| maxLength: 255 | |
| description: | |
| type: string | |
| nullable: true | |
| image: | |
| type: string | |
| minLength: 1 | |
| nullable: true | |
| description: Main collection thumbnail image (public_id). | |
| background_image: | |
| type: string | |
| minLength: 1 | |
| nullable: true | |
| description: Hero background image (public_id). | |
| PatchedChatbotSessionRequest: | |
| type: object | |
| description: Serializer for chatbot sessions. | |
| properties: | |
| session_type: | |
| $ref: '#/components/schemas/SessionTypeEnum' | |
| status: | |
| $ref: '#/components/schemas/ChatbotSessionStatusEnum' | |
| context_data: | |
| description: Contextual info to maintain conversation state | |
| ended_at: | |
| type: string | |
| format: date-time | |
| nullable: true | |
| expires_at: | |
| type: string | |
| format: date-time | |
| nullable: true | |
| metadata: {} | |
| PatchedClientProfileUpdateRequest: | |
| type: object | |
| description: |- | |
| Input-only serializer for PATCH /profile/ requests. | |
| All fields are optional — clients send only what they want to change. | |
| properties: | |
| bio: | |
| type: string | |
| maxLength: 500 | |
| default_shipping_address: | |
| type: string | |
| state: | |
| type: string | |
| maxLength: 100 | |
| country: | |
| type: string | |
| maxLength: 100 | |
| preferred_size: | |
| oneOf: | |
| - $ref: '#/components/schemas/PreferredSizeEnum' | |
| - $ref: '#/components/schemas/BlankEnum' | |
| style_preferences: | |
| type: array | |
| items: | |
| type: string | |
| minLength: 1 | |
| favourite_colours: | |
| type: array | |
| items: | |
| type: string | |
| minLength: 1 | |
| email_notifications_enabled: | |
| type: boolean | |
| sms_notifications_enabled: | |
| type: boolean | |
| PatchedConversationRequest: | |
| type: object | |
| description: Serializer for conversations including message history. | |
| properties: | |
| conversation_type: | |
| $ref: '#/components/schemas/ConversationTypeEnum' | |
| title: | |
| type: string | |
| maxLength: 200 | |
| is_active: | |
| type: boolean | |
| summary: | |
| type: string | |
| tags: {} | |
| metadata: {} | |
| PatchedIntegrationCredentialRequest: | |
| type: object | |
| properties: | |
| provider: | |
| type: string | |
| format: uuid | |
| key_name: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| key_value: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: Stored in encrypted format. | |
| is_encrypted: | |
| type: boolean | |
| environment: | |
| allOf: | |
| - $ref: '#/components/schemas/EnvironmentEnum' | |
| default: production | |
| is_active: | |
| type: boolean | |
| expires_at: | |
| type: string | |
| format: date-time | |
| nullable: true | |
| PatchedIntegrationProviderRequest: | |
| type: object | |
| properties: | |
| name: | |
| type: string | |
| minLength: 1 | |
| title: Provider Name | |
| maxLength: 100 | |
| slug: | |
| type: string | |
| minLength: 1 | |
| title: Unique Slug | |
| maxLength: 50 | |
| pattern: ^[-a-zA-Z0-9_]+$ | |
| provider_type: | |
| allOf: | |
| - $ref: '#/components/schemas/ProviderTypeEnum' | |
| title: Service Type | |
| status: | |
| $ref: '#/components/schemas/IntegrationProviderStatusEnum' | |
| description: | |
| type: string | |
| api_base_url: | |
| type: string | |
| format: uri | |
| maxLength: 200 | |
| documentation_url: | |
| type: string | |
| format: uri | |
| maxLength: 200 | |
| PatchedMessageRequest: | |
| type: object | |
| description: Serializer for messages. | |
| properties: | |
| sender_type: | |
| $ref: '#/components/schemas/SenderTypeEnum' | |
| message_type: | |
| $ref: '#/components/schemas/MessageTypeEnum' | |
| content: | |
| type: string | |
| minLength: 1 | |
| response_data: | |
| description: Structured options or response details | |
| ai_confidence: | |
| type: number | |
| format: double | |
| nullable: true | |
| description: Confidence score of AI response (0.0 to 1.0) | |
| processing_time: | |
| type: number | |
| format: double | |
| nullable: true | |
| description: Processing time in seconds | |
| is_sensitive: | |
| type: boolean | |
| description: Does the message contain sensitive info? | |
| metadata: {} | |
| PatchedRateLimitRuleRequest: | |
| type: object | |
| properties: | |
| provider: | |
| type: string | |
| format: uuid | |
| name: | |
| type: string | |
| minLength: 1 | |
| title: Rule Name | |
| maxLength: 100 | |
| endpoint_pattern: | |
| type: string | |
| minLength: 1 | |
| description: Supports wildcards like * | |
| maxLength: 255 | |
| max_requests: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| time_window_seconds: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| title: Time Window (Seconds) | |
| scope: | |
| $ref: '#/components/schemas/ScopeEnum' | |
| is_active: | |
| type: boolean | |
| PatchedVendorOrderStatusRequest: | |
| type: object | |
| properties: | |
| delivery_status: | |
| $ref: '#/components/schemas/DeliveryStatusEnum' | |
| tracking_id: | |
| type: string | |
| PatchedVendorProfileUpdateRequest: | |
| type: object | |
| description: Input-only serializer for PATCH /vendor/profile/. | |
| properties: | |
| store_name: | |
| type: string | |
| maxLength: 150 | |
| tagline: | |
| type: string | |
| maxLength: 200 | |
| description: | |
| type: string | |
| maxLength: 2000 | |
| logo_url: | |
| type: string | |
| format: uri | |
| cover_url: | |
| type: string | |
| format: uri | |
| city: | |
| type: string | |
| maxLength: 100 | |
| state: | |
| type: string | |
| maxLength: 100 | |
| country: | |
| type: string | |
| maxLength: 100 | |
| whatsapp: | |
| type: string | |
| maxLength: 20 | |
| opening_time: | |
| type: string | |
| format: time | |
| nullable: true | |
| closing_time: | |
| type: string | |
| format: time | |
| nullable: true | |
| business_hours: {} | |
| instagram_url: | |
| type: string | |
| format: uri | |
| tiktok_url: | |
| type: string | |
| format: uri | |
| twitter_url: | |
| type: string | |
| format: uri | |
| website_url: | |
| type: string | |
| format: uri | |
| cash_payment_mode: | |
| $ref: '#/components/schemas/CashPaymentModeEnum' | |
| collection_ids: | |
| type: array | |
| items: | |
| type: string | |
| minLength: 1 | |
| description: 1-15 Collection IDs this store specialises in. | |
| maxItems: 15 | |
| PatchedWebhookEndpointRequest: | |
| type: object | |
| properties: | |
| provider: | |
| type: string | |
| format: uuid | |
| name: | |
| type: string | |
| minLength: 1 | |
| title: Webhook Name | |
| maxLength: 100 | |
| endpoint_url: | |
| type: string | |
| minLength: 1 | |
| pattern: ^[a-zA-Z0-9-_/]+$ | |
| maxLength: 255 | |
| secret_key: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: Used to verify webhook payload signatures. | |
| maxLength: 255 | |
| events: | |
| title: Subscribed Events | |
| description: List of event slugs this webhook processes. | |
| is_active: | |
| type: boolean | |
| retry_count: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| timeout_seconds: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| title: Timeout (Seconds) | |
| PaymentPathEnum: | |
| enum: | |
| - wallet | |
| - gateway | |
| - cod | |
| - pay_at_shop | |
| type: string | |
| PayoutRequest: | |
| type: object | |
| properties: | |
| bank_account_id: | |
| type: string | |
| format: uuid | |
| description: UUID of the saved VendorBankAccount to pay into. | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| description: Payout amount in NGN. Minimum determined by platform settings. | |
| narration: | |
| type: string | |
| default: Fashionistar Vendor Payout | |
| description: Bank transfer narration / description. | |
| maxLength: 255 | |
| required: | |
| - amount | |
| - bank_account_id | |
| PayoutRequestRequest: | |
| type: object | |
| properties: | |
| bank_account_id: | |
| type: string | |
| format: uuid | |
| description: UUID of the saved VendorBankAccount to pay into. | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| description: Payout amount in NGN. Minimum determined by platform settings. | |
| narration: | |
| type: string | |
| minLength: 1 | |
| default: Fashionistar Vendor Payout | |
| description: Bank transfer narration / description. | |
| maxLength: 255 | |
| required: | |
| - amount | |
| - bank_account_id | |
| PaystackBank: | |
| type: object | |
| properties: | |
| name: | |
| type: string | |
| slug: | |
| type: string | |
| code: | |
| type: string | |
| longcode: | |
| type: string | |
| nullable: true | |
| gateway: | |
| type: string | |
| nullable: true | |
| pay_with_bank: | |
| type: boolean | |
| active: | |
| type: boolean | |
| is_deleted: | |
| type: boolean | |
| nullable: true | |
| country: | |
| type: string | |
| currency: | |
| type: string | |
| type: | |
| type: string | |
| id: | |
| type: integer | |
| createdAt: | |
| type: string | |
| format: date-time | |
| updatedAt: | |
| type: string | |
| format: date-time | |
| required: | |
| - active | |
| - code | |
| - country | |
| - createdAt | |
| - currency | |
| - id | |
| - name | |
| - pay_with_bank | |
| - slug | |
| - type | |
| - updatedAt | |
| PaystackBanksResponse: | |
| type: object | |
| properties: | |
| status: | |
| type: boolean | |
| message: | |
| type: string | |
| data: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/PaystackBank' | |
| required: | |
| - data | |
| - message | |
| - status | |
| PaystackInitialize: | |
| type: object | |
| properties: | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| purpose: | |
| $ref: '#/components/schemas/PurposeEnum' | |
| currency: | |
| type: string | |
| default: NGN | |
| maxLength: 10 | |
| order_id: | |
| type: string | |
| maxLength: 120 | |
| measurement_request_id: | |
| type: string | |
| maxLength: 120 | |
| metadata: {} | |
| required: | |
| - amount | |
| - purpose | |
| PaystackInitializeRequest: | |
| type: object | |
| properties: | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| purpose: | |
| $ref: '#/components/schemas/PurposeEnum' | |
| currency: | |
| type: string | |
| minLength: 1 | |
| default: NGN | |
| maxLength: 10 | |
| order_id: | |
| type: string | |
| maxLength: 120 | |
| measurement_request_id: | |
| type: string | |
| maxLength: 120 | |
| metadata: {} | |
| required: | |
| - amount | |
| - purpose | |
| PaystackVerify: | |
| type: object | |
| properties: | |
| reference: | |
| type: string | |
| maxLength: 120 | |
| required: | |
| - reference | |
| PaystackWebhook: | |
| type: object | |
| properties: | |
| event: | |
| type: string | |
| data: {} | |
| required: | |
| - data | |
| - event | |
| PaystackWebhookRequest: | |
| type: object | |
| properties: | |
| event: | |
| type: string | |
| minLength: 1 | |
| data: {} | |
| required: | |
| - data | |
| - event | |
| PerformanceMetric: | |
| type: object | |
| properties: | |
| id: | |
| type: integer | |
| readOnly: true | |
| endpoint: | |
| type: string | |
| title: Endpoint Route | |
| description: Request URL pathway. | |
| maxLength: 255 | |
| method: | |
| type: string | |
| title: HTTP Method | |
| description: HTTP verb used in the request. | |
| maxLength: 10 | |
| response_time_ms: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: 0 | |
| format: int64 | |
| title: Response Time (ms) | |
| status_code: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: 0 | |
| format: int64 | |
| title: HTTP Status Code | |
| user: | |
| type: string | |
| format: uuid | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| nullable: true | |
| user_username: | |
| type: string | |
| readOnly: true | |
| error_message: | |
| type: string | |
| metadata: {} | |
| timestamp: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - endpoint | |
| - id | |
| - method | |
| - response_time_ms | |
| - status_code | |
| - timestamp | |
| - user_username | |
| PreferredSizeEnum: | |
| enum: | |
| - XS | |
| - S | |
| - M | |
| - L | |
| - XL | |
| - XXL | |
| - XXXL | |
| type: string | |
| ProductInquiryRequestRequest: | |
| type: object | |
| description: Serializer for specific product inquiries. | |
| properties: | |
| product_sku: | |
| type: string | |
| minLength: 1 | |
| description: Product SKU or Identifier | |
| client_size: | |
| type: string | |
| minLength: 1 | |
| description: Preferred size | |
| client_height: | |
| type: number | |
| format: double | |
| description: Client height (cm) | |
| fabric_preferences: | |
| type: array | |
| items: | |
| type: string | |
| minLength: 1 | |
| description: Preferred materials or material warnings (e.g. wool allergy) | |
| similar_products: | |
| type: array | |
| items: | |
| type: string | |
| minLength: 1 | |
| description: Similar SKUs of interest | |
| required: | |
| - product_sku | |
| ProviderEnum: | |
| enum: | |
| - wallet | |
| - paystack | |
| - flutterwave | |
| - olive_pay | |
| type: string | |
| ProviderTypeEnum: | |
| enum: | |
| - sms | |
| - payment | |
| - ai | |
| - storage | |
| - notification | |
| - analytics | |
| - other | |
| type: string | |
| PurposeEnum: | |
| enum: | |
| - wallet_topup | |
| - order_payment | |
| - measurement_fee | |
| - vendor_service | |
| - advertisement_fee | |
| type: string | |
| RateLimitRule: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| provider: | |
| type: string | |
| format: uuid | |
| provider_name: | |
| type: string | |
| readOnly: true | |
| name: | |
| type: string | |
| title: Rule Name | |
| maxLength: 100 | |
| endpoint_pattern: | |
| type: string | |
| description: Supports wildcards like * | |
| maxLength: 255 | |
| max_requests: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| time_window_seconds: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| title: Time Window (Seconds) | |
| scope: | |
| $ref: '#/components/schemas/ScopeEnum' | |
| is_active: | |
| type: boolean | |
| rate_description: | |
| type: string | |
| readOnly: true | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - created_at | |
| - endpoint_pattern | |
| - id | |
| - max_requests | |
| - name | |
| - provider | |
| - provider_name | |
| - rate_description | |
| - time_window_seconds | |
| - updated_at | |
| RateLimitRuleRequest: | |
| type: object | |
| properties: | |
| provider: | |
| type: string | |
| format: uuid | |
| name: | |
| type: string | |
| minLength: 1 | |
| title: Rule Name | |
| maxLength: 100 | |
| endpoint_pattern: | |
| type: string | |
| minLength: 1 | |
| description: Supports wildcards like * | |
| maxLength: 255 | |
| max_requests: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| time_window_seconds: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| title: Time Window (Seconds) | |
| scope: | |
| $ref: '#/components/schemas/ScopeEnum' | |
| is_active: | |
| type: boolean | |
| required: | |
| - endpoint_pattern | |
| - max_requests | |
| - name | |
| - provider | |
| - time_window_seconds | |
| ReferenceBank: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| code: | |
| type: string | |
| name: | |
| type: string | |
| country_code: | |
| type: string | |
| currency: | |
| type: string | |
| provider: | |
| type: string | |
| is_active: | |
| type: boolean | |
| required: | |
| - code | |
| - country_code | |
| - currency | |
| - id | |
| - is_active | |
| - name | |
| - provider | |
| ReferenceCity: | |
| type: object | |
| properties: | |
| code: | |
| type: string | |
| name: | |
| type: string | |
| lga_code: | |
| type: string | |
| state_code: | |
| type: string | |
| country_code: | |
| type: string | |
| latitude: | |
| type: number | |
| format: double | |
| nullable: true | |
| longitude: | |
| type: number | |
| format: double | |
| nullable: true | |
| is_active: | |
| type: boolean | |
| required: | |
| - code | |
| - country_code | |
| - is_active | |
| - latitude | |
| - lga_code | |
| - longitude | |
| - name | |
| - state_code | |
| ReferenceCountry: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| code: | |
| type: string | |
| name: | |
| type: string | |
| flag: | |
| type: string | |
| phone_code: | |
| type: string | |
| is_active: | |
| type: boolean | |
| required: | |
| - code | |
| - flag | |
| - id | |
| - is_active | |
| - name | |
| - phone_code | |
| ReferenceLga: | |
| type: object | |
| properties: | |
| code: | |
| type: string | |
| name: | |
| type: string | |
| state_code: | |
| type: string | |
| country_code: | |
| type: string | |
| is_active: | |
| type: boolean | |
| required: | |
| - code | |
| - country_code | |
| - is_active | |
| - name | |
| - state_code | |
| ReferenceState: | |
| type: object | |
| properties: | |
| code: | |
| type: string | |
| name: | |
| type: string | |
| country_code: | |
| type: string | |
| is_active: | |
| type: boolean | |
| required: | |
| - code | |
| - country_code | |
| - is_active | |
| - name | |
| Refund: | |
| type: object | |
| properties: | |
| hold_reference: | |
| type: string | |
| maxLength: 120 | |
| required: | |
| - hold_reference | |
| RefundRequest: | |
| type: object | |
| properties: | |
| hold_reference: | |
| type: string | |
| minLength: 1 | |
| maxLength: 120 | |
| required: | |
| - hold_reference | |
| Role09fEnum: | |
| enum: | |
| - vendor | |
| - client | |
| type: string | |
| RoleC2fEnum: | |
| enum: | |
| - vendor | |
| - client | |
| - staff | |
| - admin | |
| - editor | |
| - support | |
| - assistant | |
| - moderator | |
| - super_admin | |
| - super_vendor | |
| - super_client | |
| - super_staff | |
| - super_editor | |
| - super_support | |
| - super_assistant | |
| - super_moderator | |
| type: string | |
| ScopeEnum: | |
| enum: | |
| - global | |
| - user | |
| - ip | |
| type: string | |
| SendMessageRequestRequest: | |
| type: object | |
| description: Serializer to validate sending a message. | |
| properties: | |
| message: | |
| type: string | |
| minLength: 1 | |
| description: User message content | |
| maxLength: 4000 | |
| message_type: | |
| allOf: | |
| - $ref: '#/components/schemas/MessageTypeEnum' | |
| default: text | |
| description: Message type | |
| context: | |
| description: Additional context for message processing | |
| required: | |
| - message | |
| SendMessageResponse: | |
| type: object | |
| description: Serializer for the response of sending a message. | |
| properties: | |
| response: | |
| allOf: | |
| - $ref: '#/components/schemas/ChatbotResponseData' | |
| description: Chatbot response | |
| user_message_id: | |
| type: string | |
| format: uuid | |
| description: User message UUID | |
| bot_message_id: | |
| type: string | |
| format: uuid | |
| description: Bot message UUID | |
| conversation_id: | |
| type: string | |
| format: uuid | |
| description: Conversation UUID | |
| session_id: | |
| type: string | |
| format: uuid | |
| description: Session UUID | |
| required: | |
| - bot_message_id | |
| - conversation_id | |
| - response | |
| - session_id | |
| - user_message_id | |
| SenderTypeEnum: | |
| enum: | |
| - user | |
| - bot | |
| - system | |
| type: string | |
| SessionTypeEnum: | |
| enum: | |
| - client | |
| - vendor | |
| type: string | |
| SeverityEnum: | |
| enum: | |
| - low | |
| - medium | |
| - high | |
| - critical | |
| type: string | |
| SizeRecommendationRequestRequest: | |
| type: object | |
| description: Serializer for sizing and fit recommendation requests. | |
| properties: | |
| measurements: | |
| type: array | |
| items: | |
| type: string | |
| minLength: 1 | |
| description: List of body measurements | |
| height_cm: | |
| type: integer | |
| maximum: 250 | |
| minimum: 0 | |
| description: Client height in cm | |
| gender: | |
| allOf: | |
| - $ref: '#/components/schemas/GenderEnum' | |
| description: Client gender | |
| fit_preference: | |
| type: string | |
| minLength: 1 | |
| description: Preferred fit profile (e.g. slim, regular, loose) | |
| prior_purchases: | |
| type: array | |
| items: | |
| type: string | |
| minLength: 1 | |
| description: Known comfortable sizing in other brands | |
| required: | |
| - measurements | |
| StartSessionResponse: | |
| type: object | |
| description: Serializer for starting a chatbot session. | |
| properties: | |
| session: | |
| allOf: | |
| - $ref: '#/components/schemas/ChatbotSession' | |
| description: Session info | |
| greeting_message: | |
| allOf: | |
| - $ref: '#/components/schemas/ChatbotResponseData' | |
| description: Greeting message | |
| quick_replies: | |
| type: array | |
| items: | |
| type: object | |
| additionalProperties: {} | |
| description: Initial quick replies | |
| required: | |
| - session | |
| StyleAssessmentRequestRequest: | |
| type: object | |
| description: Serializer for style and aesthetic assessment. | |
| properties: | |
| preferred_style: | |
| type: string | |
| minLength: 1 | |
| description: Primary style or aesthetic preference | |
| budget_range: | |
| type: string | |
| minLength: 1 | |
| description: Estimated budget range | |
| formality_level: | |
| type: integer | |
| maximum: 10 | |
| minimum: 1 | |
| description: Formality level (1-10) | |
| size_preferences: | |
| type: array | |
| items: | |
| type: string | |
| minLength: 1 | |
| description: Preferred sizing guidelines | |
| sizing_notes: | |
| type: string | |
| minLength: 1 | |
| description: Specific details regarding styling/fit history | |
| required: | |
| - budget_range | |
| - formality_level | |
| - preferred_style | |
| Transaction: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| transaction_type: | |
| $ref: '#/components/schemas/TransactionTypeEnum' | |
| status: | |
| $ref: '#/components/schemas/TransactionStatusEnum' | |
| direction: | |
| $ref: '#/components/schemas/DirectionEnum' | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| fee_amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| net_amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| reference: | |
| type: string | |
| maxLength: 120 | |
| external_reference: | |
| type: string | |
| maxLength: 160 | |
| provider_reference: | |
| type: string | |
| maxLength: 160 | |
| order_id: | |
| type: string | |
| maxLength: 120 | |
| measurement_request_id: | |
| type: string | |
| maxLength: 120 | |
| description: | |
| type: string | |
| maxLength: 500 | |
| from_wallet_currency: | |
| type: string | |
| readOnly: true | |
| to_wallet_currency: | |
| type: string | |
| readOnly: true | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was created. | |
| completed_at: | |
| type: string | |
| format: date-time | |
| nullable: true | |
| metadata: {} | |
| required: | |
| - amount | |
| - created_at | |
| - from_wallet_currency | |
| - id | |
| - reference | |
| - to_wallet_currency | |
| - transaction_type | |
| TransactionStatusEnum: | |
| enum: | |
| - pending | |
| - processing | |
| - completed | |
| - failed | |
| - cancelled | |
| - reversed | |
| - disputed | |
| type: string | |
| TransactionSummary: | |
| type: object | |
| properties: | |
| total_inflow: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| total_outflow: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| net_balance: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| count: | |
| type: integer | |
| required: | |
| - count | |
| - net_balance | |
| - total_inflow | |
| - total_outflow | |
| TransactionTypeEnum: | |
| enum: | |
| - order_payment | |
| - escrow_hold | |
| - escrow_release | |
| - commission | |
| - measurement_fee | |
| - vendor_subscription | |
| - platform_usage_fee | |
| - advertisement_fee | |
| - affiliate_revenue | |
| - refund | |
| - payout | |
| - transfer | |
| - reversal | |
| - adjustment | |
| type: string | |
| TransferRecipientCreate: | |
| type: object | |
| properties: | |
| account_number: | |
| type: string | |
| maxLength: 20 | |
| account_name: | |
| type: string | |
| maxLength: 180 | |
| bank_name: | |
| type: string | |
| maxLength: 180 | |
| bank_code: | |
| type: string | |
| maxLength: 20 | |
| required: | |
| - account_name | |
| - account_number | |
| - bank_code | |
| - bank_name | |
| TransferRecipientCreateRequest: | |
| type: object | |
| properties: | |
| account_number: | |
| type: string | |
| minLength: 1 | |
| maxLength: 20 | |
| account_name: | |
| type: string | |
| minLength: 1 | |
| maxLength: 180 | |
| bank_name: | |
| type: string | |
| minLength: 1 | |
| maxLength: 180 | |
| bank_code: | |
| type: string | |
| minLength: 1 | |
| maxLength: 20 | |
| required: | |
| - account_name | |
| - account_number | |
| - bank_code | |
| - bank_name | |
| UrgencyEnum: | |
| enum: | |
| - low | |
| - medium | |
| - high | |
| - rush | |
| type: string | |
| UserActivity: | |
| type: object | |
| properties: | |
| id: | |
| type: integer | |
| readOnly: true | |
| user: | |
| type: string | |
| format: uuid | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| user_username: | |
| type: string | |
| readOnly: true | |
| action: | |
| type: string | |
| title: Action Performed | |
| description: Type of action performed by the user. | |
| maxLength: 100 | |
| resource: | |
| type: string | |
| title: Resource Name | |
| description: Affected resource or area of interaction. | |
| maxLength: 100 | |
| resource_id: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: 0 | |
| format: int64 | |
| nullable: true | |
| ip_address: | |
| type: string | |
| nullable: true | |
| user_agent: | |
| type: string | |
| session_id: | |
| type: string | |
| maxLength: 40 | |
| metadata: {} | |
| timestamp: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| title: Action Time | |
| required: | |
| - action | |
| - id | |
| - timestamp | |
| - user | |
| - user_username | |
| UserBasic: | |
| type: object | |
| description: Serializer for basic user information. | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| first_name: | |
| type: string | |
| nullable: true | |
| maxLength: 150 | |
| last_name: | |
| type: string | |
| nullable: true | |
| maxLength: 150 | |
| phone: | |
| type: string | |
| readOnly: true | |
| nullable: true | |
| description: Primary unique identifier for phone-based auth. | |
| required: | |
| - id | |
| - phone | |
| UserBasicRequest: | |
| type: object | |
| description: Serializer for basic user information. | |
| properties: | |
| first_name: | |
| type: string | |
| nullable: true | |
| maxLength: 150 | |
| last_name: | |
| type: string | |
| nullable: true | |
| maxLength: 150 | |
| UserSession: | |
| type: object | |
| description: |- | |
| Read serializer for UserSession — used by the active sessions list. | |
| All UUID7 primary keys are serialized as strings (required for | |
| JavaScript, which cannot safely handle 128-bit integers). | |
| The ``is_current`` flag is computed dynamically at query time | |
| (via the view injecting the current JTI), so it is read-only here. | |
| The ``is_expired`` flag is a computed property (not stored in DB). | |
| properties: | |
| id: | |
| type: string | |
| readOnly: true | |
| device_name: | |
| type: string | |
| readOnly: true | |
| description: Human-readable label such as 'Chrome on Windows'. | |
| client_type: | |
| allOf: | |
| - $ref: '#/components/schemas/UserSessionClientTypeEnum' | |
| readOnly: true | |
| description: Browser / mobile app / API client. | |
| browser: | |
| type: string | |
| readOnly: true | |
| os: | |
| type: string | |
| readOnly: true | |
| ip_address: | |
| type: string | |
| readOnly: true | |
| nullable: true | |
| description: IP address captured at session creation time. | |
| country: | |
| type: string | |
| readOnly: true | |
| city: | |
| type: string | |
| readOnly: true | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| last_used_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| expires_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| nullable: true | |
| is_current: | |
| type: boolean | |
| description: |- | |
| True when the session's JTI matches the current request's access token JTI. | |
| The view must pass `current_jti` in serializer context: | |
| serializer = UserSessionSerializer( | |
| sessions, many=True, context={"current_jti": current_jti} | |
| ) | |
| readOnly: true | |
| is_expired: | |
| type: boolean | |
| description: True when the session's refresh token has expired. | |
| readOnly: true | |
| required: | |
| - browser | |
| - city | |
| - client_type | |
| - country | |
| - created_at | |
| - device_name | |
| - expires_at | |
| - id | |
| - ip_address | |
| - is_current | |
| - is_expired | |
| - last_used_at | |
| - os | |
| UserSessionClientTypeEnum: | |
| enum: | |
| - web | |
| - mobile | |
| - api | |
| - unknown | |
| type: string | |
| VendorCollection: | |
| type: object | |
| description: Minimal representation of a Collection linked to this vendor. | |
| properties: | |
| id: | |
| type: string | |
| readOnly: true | |
| title: | |
| type: string | |
| readOnly: true | |
| slug: | |
| type: string | |
| readOnly: true | |
| pattern: ^[-a-zA-Z0-9_]+$ | |
| required: | |
| - id | |
| - slug | |
| - title | |
| VendorOrderStatus: | |
| type: object | |
| properties: | |
| delivery_status: | |
| $ref: '#/components/schemas/DeliveryStatusEnum' | |
| tracking_id: | |
| type: string | |
| required: | |
| - delivery_status | |
| VendorOrderStatusRequest: | |
| type: object | |
| properties: | |
| delivery_status: | |
| $ref: '#/components/schemas/DeliveryStatusEnum' | |
| tracking_id: | |
| type: string | |
| required: | |
| - delivery_status | |
| VendorPayoutDetails: | |
| type: object | |
| description: Input serializer for POST /vendor/payout/. | |
| properties: | |
| bank_name: | |
| type: string | |
| maxLength: 150 | |
| bank_code: | |
| type: string | |
| maxLength: 10 | |
| account_name: | |
| type: string | |
| maxLength: 200 | |
| account_number: | |
| type: string | |
| description: Bank account number. Will be encrypted before storage. | |
| maxLength: 20 | |
| paystack_recipient_code: | |
| type: string | |
| maxLength: 100 | |
| required: | |
| - account_name | |
| - account_number | |
| - bank_name | |
| VendorPayoutDetailsRequest: | |
| type: object | |
| description: Input serializer for POST /vendor/payout/. | |
| properties: | |
| bank_name: | |
| type: string | |
| minLength: 1 | |
| maxLength: 150 | |
| bank_code: | |
| type: string | |
| maxLength: 10 | |
| account_name: | |
| type: string | |
| minLength: 1 | |
| maxLength: 200 | |
| account_number: | |
| type: string | |
| minLength: 1 | |
| description: Bank account number. Will be encrypted before storage. | |
| maxLength: 20 | |
| paystack_recipient_code: | |
| type: string | |
| maxLength: 100 | |
| required: | |
| - account_name | |
| - account_number | |
| - bank_name | |
| VendorProfileOutput: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| user_id: | |
| type: string | |
| readOnly: true | |
| user_email: | |
| type: string | |
| readOnly: true | |
| store_name: | |
| type: string | |
| readOnly: true | |
| description: Public-facing store name shown on the marketplace. | |
| store_slug: | |
| type: string | |
| readOnly: true | |
| description: URL-safe unique store identifier. Auto-generated from store_name. | |
| pattern: ^[-a-zA-Z0-9_]+$ | |
| tagline: | |
| type: string | |
| readOnly: true | |
| description: | |
| type: string | |
| readOnly: true | |
| logo_url: | |
| type: string | |
| readOnly: true | |
| description: Cloudinary store logo URL. | |
| cover_url: | |
| type: string | |
| readOnly: true | |
| description: Cloudinary banner URL. | |
| city: | |
| type: string | |
| readOnly: true | |
| state: | |
| type: string | |
| readOnly: true | |
| country: | |
| type: string | |
| readOnly: true | |
| whatsapp: | |
| type: string | |
| readOnly: true | |
| opening_time: | |
| type: string | |
| format: time | |
| readOnly: true | |
| nullable: true | |
| closing_time: | |
| type: string | |
| format: time | |
| readOnly: true | |
| nullable: true | |
| business_hours: | |
| readOnly: true | |
| description: 'e.g. {''Monday'': ''9:00-17:00'', ''Tuesday'': ''9:00-17:00''}' | |
| instagram_url: | |
| type: string | |
| format: uri | |
| readOnly: true | |
| tiktok_url: | |
| type: string | |
| format: uri | |
| readOnly: true | |
| twitter_url: | |
| type: string | |
| format: uri | |
| readOnly: true | |
| website_url: | |
| type: string | |
| format: uri | |
| readOnly: true | |
| cash_payment_mode: | |
| allOf: | |
| - $ref: '#/components/schemas/CashPaymentModeEnum' | |
| readOnly: true | |
| description: Storefront display preference for COD / Pay At Shop availability. | |
| collections: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/VendorCollection' | |
| readOnly: true | |
| total_products: | |
| type: integer | |
| readOnly: true | |
| total_sales: | |
| type: integer | |
| readOnly: true | |
| total_revenue: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,14}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| average_rating: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,1}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| review_count: | |
| type: integer | |
| readOnly: true | |
| wallet_balance: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,12}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| is_verified: | |
| type: boolean | |
| readOnly: true | |
| description: Manually verified by Fashionistar staff. Does NOT gate dashboard | |
| access. | |
| is_active: | |
| type: boolean | |
| readOnly: true | |
| is_featured: | |
| type: boolean | |
| readOnly: true | |
| setup_state: | |
| allOf: | |
| - $ref: '#/components/schemas/VendorSetupState' | |
| readOnly: true | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was created. | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| description: Timestamp when the record was last updated. | |
| required: | |
| - average_rating | |
| - business_hours | |
| - cash_payment_mode | |
| - city | |
| - closing_time | |
| - collections | |
| - country | |
| - cover_url | |
| - created_at | |
| - description | |
| - id | |
| - instagram_url | |
| - is_active | |
| - is_featured | |
| - is_verified | |
| - logo_url | |
| - opening_time | |
| - review_count | |
| - setup_state | |
| - state | |
| - store_name | |
| - store_slug | |
| - tagline | |
| - tiktok_url | |
| - total_products | |
| - total_revenue | |
| - total_sales | |
| - twitter_url | |
| - updated_at | |
| - user_email | |
| - user_id | |
| - wallet_balance | |
| - website_url | |
| VendorProfileUpdate: | |
| type: object | |
| description: Input-only serializer for PATCH /vendor/profile/. | |
| properties: | |
| store_name: | |
| type: string | |
| maxLength: 150 | |
| tagline: | |
| type: string | |
| maxLength: 200 | |
| description: | |
| type: string | |
| maxLength: 2000 | |
| logo_url: | |
| type: string | |
| format: uri | |
| cover_url: | |
| type: string | |
| format: uri | |
| city: | |
| type: string | |
| maxLength: 100 | |
| state: | |
| type: string | |
| maxLength: 100 | |
| country: | |
| type: string | |
| maxLength: 100 | |
| whatsapp: | |
| type: string | |
| maxLength: 20 | |
| opening_time: | |
| type: string | |
| format: time | |
| nullable: true | |
| closing_time: | |
| type: string | |
| format: time | |
| nullable: true | |
| business_hours: {} | |
| instagram_url: | |
| type: string | |
| format: uri | |
| tiktok_url: | |
| type: string | |
| format: uri | |
| twitter_url: | |
| type: string | |
| format: uri | |
| website_url: | |
| type: string | |
| format: uri | |
| cash_payment_mode: | |
| $ref: '#/components/schemas/CashPaymentModeEnum' | |
| collection_ids: | |
| type: array | |
| items: | |
| type: string | |
| description: 1-15 Collection IDs this store specialises in. | |
| maxItems: 15 | |
| VendorSetup: | |
| type: object | |
| description: |- | |
| Minimal setup payload to create the first vendor profile. | |
| Called on the POST /vendor/setup/ endpoint. | |
| properties: | |
| store_name: | |
| type: string | |
| maxLength: 150 | |
| description: | |
| type: string | |
| maxLength: 2000 | |
| tagline: | |
| type: string | |
| maxLength: 200 | |
| logo_url: | |
| type: string | |
| format: uri | |
| cover_url: | |
| type: string | |
| format: uri | |
| city: | |
| type: string | |
| maxLength: 100 | |
| state: | |
| type: string | |
| maxLength: 100 | |
| country: | |
| type: string | |
| default: Nigeria | |
| maxLength: 100 | |
| whatsapp: | |
| type: string | |
| maxLength: 20 | |
| instagram_url: | |
| type: string | |
| format: uri | |
| tiktok_url: | |
| type: string | |
| format: uri | |
| twitter_url: | |
| type: string | |
| format: uri | |
| website_url: | |
| type: string | |
| format: uri | |
| cash_payment_mode: | |
| allOf: | |
| - $ref: '#/components/schemas/CashPaymentModeEnum' | |
| default: disabled | |
| collection_ids: | |
| type: array | |
| items: | |
| type: string | |
| maxItems: 15 | |
| required: | |
| - city | |
| - description | |
| - state | |
| - store_name | |
| VendorSetupRequest: | |
| type: object | |
| description: |- | |
| Minimal setup payload to create the first vendor profile. | |
| Called on the POST /vendor/setup/ endpoint. | |
| properties: | |
| store_name: | |
| type: string | |
| minLength: 1 | |
| maxLength: 150 | |
| description: | |
| type: string | |
| minLength: 1 | |
| maxLength: 2000 | |
| tagline: | |
| type: string | |
| maxLength: 200 | |
| logo_url: | |
| type: string | |
| format: uri | |
| cover_url: | |
| type: string | |
| format: uri | |
| city: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| state: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| country: | |
| type: string | |
| default: Nigeria | |
| maxLength: 100 | |
| whatsapp: | |
| type: string | |
| maxLength: 20 | |
| instagram_url: | |
| type: string | |
| format: uri | |
| tiktok_url: | |
| type: string | |
| format: uri | |
| twitter_url: | |
| type: string | |
| format: uri | |
| website_url: | |
| type: string | |
| format: uri | |
| cash_payment_mode: | |
| allOf: | |
| - $ref: '#/components/schemas/CashPaymentModeEnum' | |
| default: disabled | |
| collection_ids: | |
| type: array | |
| items: | |
| type: string | |
| minLength: 1 | |
| maxItems: 15 | |
| required: | |
| - city | |
| - description | |
| - state | |
| - store_name | |
| VendorSetupState: | |
| type: object | |
| properties: | |
| current_step: | |
| type: integer | |
| readOnly: true | |
| description: Step number (1–4) the vendor is currently on. | |
| profile_complete: | |
| type: boolean | |
| readOnly: true | |
| bank_details: | |
| type: boolean | |
| readOnly: true | |
| id_verified: | |
| type: boolean | |
| readOnly: true | |
| description: 'FUTURE: government ID verified via external KYC API (Youverify/Smile | |
| Identity). Does NOT block dashboard or product creation — informational | |
| only.' | |
| first_product: | |
| type: boolean | |
| readOnly: true | |
| onboarding_done: | |
| type: boolean | |
| readOnly: true | |
| description: True once profile_complete + bank_details + first_product are | |
| all done. Store becomes fully visible on the marketplace. | |
| completion_percentage: | |
| type: integer | |
| description: |- | |
| Return setup completion as an integer percentage 0–100. | |
| Based on the 3 active steps (id_verified excluded from formula). | |
| readOnly: true | |
| required: | |
| - bank_details | |
| - completion_percentage | |
| - current_step | |
| - first_product | |
| - id_verified | |
| - onboarding_done | |
| - profile_complete | |
| VendorTransactionPin: | |
| type: object | |
| description: Input serializer for PIN set/verify endpoints. | |
| properties: | |
| pin: | |
| type: string | |
| description: 4-digit numeric payout confirmation PIN. | |
| maxLength: 4 | |
| minLength: 4 | |
| required: | |
| - pin | |
| VendorTransactionPinRequest: | |
| type: object | |
| description: Input serializer for PIN set/verify endpoints. | |
| properties: | |
| pin: | |
| type: string | |
| minLength: 4 | |
| description: 4-digit numeric payout confirmation PIN. | |
| maxLength: 4 | |
| required: | |
| - pin | |
| Wallet: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| description: UUID7 — globally unique, time-ordered primary key. | |
| owner_type: | |
| $ref: '#/components/schemas/OwnerTypeEnum' | |
| name: | |
| type: string | |
| maxLength: 120 | |
| currency: | |
| type: string | |
| balance: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| available_balance: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| pending_balance: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| escrow_balance: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| status: | |
| $ref: '#/components/schemas/WalletStatusEnum' | |
| has_pin: | |
| type: boolean | |
| readOnly: true | |
| daily_limit: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| nullable: true | |
| monthly_limit: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| nullable: true | |
| last_transaction_at: | |
| type: string | |
| format: date-time | |
| nullable: true | |
| required: | |
| - currency | |
| - has_pin | |
| - id | |
| - name | |
| - owner_type | |
| WalletFundPayment: | |
| type: object | |
| properties: | |
| order_id: | |
| type: string | |
| maxLength: 120 | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| purpose: | |
| $ref: '#/components/schemas/PurposeEnum' | |
| provider: | |
| $ref: '#/components/schemas/ProviderEnum' | |
| currency: | |
| type: string | |
| default: NGN | |
| maxLength: 10 | |
| selected_percent: | |
| type: integer | |
| maximum: 100 | |
| minimum: 1 | |
| default: 100 | |
| cash_payment_mode: | |
| allOf: | |
| - $ref: '#/components/schemas/CashPaymentModeEnum' | |
| default: disabled | |
| payment_path: | |
| allOf: | |
| - $ref: '#/components/schemas/PaymentPathEnum' | |
| default: gateway | |
| metadata: {} | |
| required: | |
| - provider | |
| - purpose | |
| WalletFundPaymentRequest: | |
| type: object | |
| properties: | |
| order_id: | |
| type: string | |
| maxLength: 120 | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| purpose: | |
| $ref: '#/components/schemas/PurposeEnum' | |
| provider: | |
| $ref: '#/components/schemas/ProviderEnum' | |
| currency: | |
| type: string | |
| minLength: 1 | |
| default: NGN | |
| maxLength: 10 | |
| selected_percent: | |
| type: integer | |
| maximum: 100 | |
| minimum: 1 | |
| default: 100 | |
| cash_payment_mode: | |
| allOf: | |
| - $ref: '#/components/schemas/CashPaymentModeEnum' | |
| default: disabled | |
| payment_path: | |
| allOf: | |
| - $ref: '#/components/schemas/PaymentPathEnum' | |
| default: gateway | |
| metadata: {} | |
| required: | |
| - provider | |
| - purpose | |
| WalletPinChange: | |
| type: object | |
| properties: | |
| current_pin: | |
| type: string | |
| maxLength: 4 | |
| minLength: 4 | |
| pattern: ^\d{4}$ | |
| new_pin: | |
| type: string | |
| maxLength: 4 | |
| minLength: 4 | |
| pattern: ^\d{4}$ | |
| required: | |
| - current_pin | |
| - new_pin | |
| WalletPinChangeRequest: | |
| type: object | |
| properties: | |
| current_pin: | |
| type: string | |
| minLength: 4 | |
| maxLength: 4 | |
| pattern: ^\d{4}$ | |
| new_pin: | |
| type: string | |
| minLength: 4 | |
| maxLength: 4 | |
| pattern: ^\d{4}$ | |
| required: | |
| - current_pin | |
| - new_pin | |
| WalletPinSet: | |
| type: object | |
| properties: | |
| pin: | |
| type: string | |
| maxLength: 4 | |
| minLength: 4 | |
| pattern: ^\d{4}$ | |
| required: | |
| - pin | |
| WalletPinSetRequest: | |
| type: object | |
| properties: | |
| pin: | |
| type: string | |
| minLength: 4 | |
| maxLength: 4 | |
| pattern: ^\d{4}$ | |
| required: | |
| - pin | |
| WalletPinVerify: | |
| type: object | |
| properties: | |
| pin: | |
| type: string | |
| maxLength: 4 | |
| minLength: 4 | |
| pattern: ^\d{4}$ | |
| required: | |
| - pin | |
| WalletPinVerifyRequest: | |
| type: object | |
| properties: | |
| pin: | |
| type: string | |
| minLength: 4 | |
| maxLength: 4 | |
| pattern: ^\d{4}$ | |
| required: | |
| - pin | |
| WalletStatusEnum: | |
| enum: | |
| - active | |
| - inactive | |
| - frozen | |
| - suspended | |
| - closed | |
| type: string | |
| WalletTransfer: | |
| type: object | |
| description: |- | |
| Serializer for P2P fund transfers. | |
| Validates receiver existence, positive amount, and PIN format. | |
| properties: | |
| receiver_id: | |
| type: string | |
| format: uuid | |
| description: ID of the user receiving the funds. | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| description: Amount to transfer (min 0.01). | |
| transaction_password: | |
| type: string | |
| description: 4-digit transaction PIN for authorization. | |
| maxLength: 10 | |
| minLength: 4 | |
| required: | |
| - amount | |
| - receiver_id | |
| - transaction_password | |
| WalletTransferRequest: | |
| type: object | |
| description: |- | |
| Serializer for P2P fund transfers. | |
| Validates receiver existence, positive amount, and PIN format. | |
| properties: | |
| receiver_id: | |
| type: string | |
| format: uuid | |
| description: ID of the user receiving the funds. | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| description: Amount to transfer (min 0.01). | |
| transaction_password: | |
| type: string | |
| minLength: 4 | |
| description: 4-digit transaction PIN for authorization. | |
| maxLength: 10 | |
| required: | |
| - amount | |
| - receiver_id | |
| - transaction_password | |
| WalletWithdrawal: | |
| type: object | |
| description: Validate KYC-gated wallet withdrawal requests. | |
| properties: | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| pin: | |
| type: string | |
| maxLength: 4 | |
| minLength: 4 | |
| pattern: ^\d{4}$ | |
| bank_code: | |
| type: string | |
| maxLength: 20 | |
| account_number: | |
| type: string | |
| maxLength: 10 | |
| minLength: 10 | |
| pattern: ^\d{10}$ | |
| account_name: | |
| type: string | |
| maxLength: 160 | |
| required: | |
| - account_name | |
| - account_number | |
| - amount | |
| - bank_code | |
| - pin | |
| WalletWithdrawalRequest: | |
| type: object | |
| description: Validate KYC-gated wallet withdrawal requests. | |
| properties: | |
| amount: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,18}(?:\.\d{0,2})?$ | |
| pin: | |
| type: string | |
| minLength: 4 | |
| maxLength: 4 | |
| pattern: ^\d{4}$ | |
| bank_code: | |
| type: string | |
| minLength: 1 | |
| maxLength: 20 | |
| account_number: | |
| type: string | |
| minLength: 10 | |
| maxLength: 10 | |
| pattern: ^\d{10}$ | |
| account_name: | |
| type: string | |
| minLength: 1 | |
| maxLength: 160 | |
| required: | |
| - account_name | |
| - account_number | |
| - amount | |
| - bank_code | |
| - pin | |
| WebhookEndpoint: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| provider: | |
| type: string | |
| format: uuid | |
| provider_name: | |
| type: string | |
| readOnly: true | |
| name: | |
| type: string | |
| title: Webhook Name | |
| maxLength: 100 | |
| endpoint_url: | |
| type: string | |
| pattern: ^[a-zA-Z0-9-_/]+$ | |
| maxLength: 255 | |
| events: | |
| title: Subscribed Events | |
| description: List of event slugs this webhook processes. | |
| is_active: | |
| type: boolean | |
| retry_count: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| timeout_seconds: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| title: Timeout (Seconds) | |
| events_count: | |
| type: integer | |
| readOnly: true | |
| pending_events: | |
| type: integer | |
| readOnly: true | |
| created_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| updated_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - created_at | |
| - endpoint_url | |
| - events_count | |
| - id | |
| - name | |
| - pending_events | |
| - provider | |
| - provider_name | |
| - updated_at | |
| WebhookEndpointRequest: | |
| type: object | |
| properties: | |
| provider: | |
| type: string | |
| format: uuid | |
| name: | |
| type: string | |
| minLength: 1 | |
| title: Webhook Name | |
| maxLength: 100 | |
| endpoint_url: | |
| type: string | |
| minLength: 1 | |
| pattern: ^[a-zA-Z0-9-_/]+$ | |
| maxLength: 255 | |
| secret_key: | |
| type: string | |
| writeOnly: true | |
| minLength: 1 | |
| description: Used to verify webhook payload signatures. | |
| maxLength: 255 | |
| events: | |
| title: Subscribed Events | |
| description: List of event slugs this webhook processes. | |
| is_active: | |
| type: boolean | |
| retry_count: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| timeout_seconds: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| title: Timeout (Seconds) | |
| required: | |
| - endpoint_url | |
| - name | |
| - provider | |
| - secret_key | |
| WebhookEvent: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| readOnly: true | |
| webhook: | |
| type: string | |
| format: uuid | |
| webhook_name: | |
| type: string | |
| readOnly: true | |
| provider_name: | |
| type: string | |
| readOnly: true | |
| event_type: | |
| type: string | |
| maxLength: 100 | |
| payload: {} | |
| headers: {} | |
| signature: | |
| type: string | |
| maxLength: 255 | |
| is_valid: | |
| type: boolean | |
| readOnly: true | |
| title: Is Signature Valid | |
| is_processed: | |
| type: boolean | |
| readOnly: true | |
| processed_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| nullable: true | |
| error_message: | |
| type: string | |
| retry_count: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| received_at: | |
| type: string | |
| format: date-time | |
| readOnly: true | |
| required: | |
| - event_type | |
| - id | |
| - is_processed | |
| - is_valid | |
| - processed_at | |
| - provider_name | |
| - received_at | |
| - webhook | |
| - webhook_name | |
| WebhookEventRequest: | |
| type: object | |
| properties: | |
| webhook: | |
| type: string | |
| format: uuid | |
| event_type: | |
| type: string | |
| minLength: 1 | |
| maxLength: 100 | |
| payload: {} | |
| headers: {} | |
| signature: | |
| type: string | |
| maxLength: 255 | |
| error_message: | |
| type: string | |
| retry_count: | |
| type: integer | |
| maximum: 9223372036854775807 | |
| minimum: -9223372036854775808 | |
| format: int64 | |
| required: | |
| - event_type | |
| - webhook | |
| WishlistProduct: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| readOnly: true | |
| pid: | |
| type: string | |
| readOnly: true | |
| title: | |
| type: string | |
| readOnly: true | |
| image: | |
| type: string | |
| readOnly: true | |
| price: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,10}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| old_price: | |
| type: string | |
| format: decimal | |
| pattern: ^-?\d{0,10}(?:\.\d{0,2})?$ | |
| readOnly: true | |
| stock_qty: | |
| type: integer | |
| readOnly: true | |
| status: | |
| type: string | |
| readOnly: true | |
| category_name: | |
| type: string | |
| readOnly: true | |
| required: | |
| - category_name | |
| - id | |
| - image | |
| - old_price | |
| - pid | |
| - price | |
| - status | |
| - stock_qty | |
| - title | |
| WishlistToggle: | |
| type: object | |
| properties: | |
| product_id: | |
| type: string | |
| format: uuid | |
| required: | |
| - product_id | |
| WishlistToggleRequest: | |
| type: object | |
| properties: | |
| product_id: | |
| type: string | |
| format: uuid | |
| required: | |
| - product_id | |
| securitySchemes: | |
| basicAuth: | |
| type: http | |
| scheme: basic | |
| cookieAuth: | |
| type: apiKey | |
| in: cookie | |
| name: sessionid | |
| jwtAuth: | |
| type: http | |
| scheme: bearer | |
| bearerFormat: JWT | |
| tokenAuth: | |
| type: apiKey | |
| in: header | |
| name: Authorization | |
| description: Token-based authentication with required prefix "Token" | |
| servers: | |
| - url: http://127.0.0.1:8001 | |
| description: Development (ASGI/Uvicorn) | |