Add subuser permission templates service and related tests
This commit is contained in:
+439
@@ -1455,6 +1455,183 @@ paths:
|
||||
$ref: '#/components/schemas/BirdFlashCallHangupResponse'
|
||||
|
||||
# Subusers (public registration + setup)
|
||||
/superuser/users/{user_id}/subusers:
|
||||
get:
|
||||
tags:
|
||||
- Subusers
|
||||
summary: List subusers for a superuser customer account
|
||||
description: Returns paginated driver access grants for the customer number resolved from the selected user.
|
||||
operationId: listSuperuserUserSubusers
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: user_id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
- name: page
|
||||
in: query
|
||||
required: false
|
||||
schema: { type: integer, minimum: 1 }
|
||||
- name: limit
|
||||
in: query
|
||||
required: false
|
||||
schema: { type: integer, minimum: 1, maximum: 1000 }
|
||||
- name: search
|
||||
in: query
|
||||
required: false
|
||||
schema: { type: string }
|
||||
- name: include_non_enabled
|
||||
in: query
|
||||
required: false
|
||||
schema: { type: boolean }
|
||||
responses:
|
||||
'200':
|
||||
description: User-scoped subuser list
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/SubuserManagementRow'
|
||||
'400': { $ref: '#/components/responses/BadRequest' }
|
||||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||||
'403': { $ref: '#/components/responses/Forbidden' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
'500': { $ref: '#/components/responses/InternalServerError' }
|
||||
|
||||
/superuser/users/{user_id}/subusers/summary:
|
||||
get:
|
||||
tags:
|
||||
- Subusers
|
||||
summary: Summarize subusers for a superuser customer account
|
||||
operationId: summarizeSuperuserUserSubusers
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: user_id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
responses:
|
||||
'200':
|
||||
description: User-scoped subuser summary
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SubuserManagementSummary'
|
||||
'400': { $ref: '#/components/responses/BadRequest' }
|
||||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||||
'403': { $ref: '#/components/responses/Forbidden' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
'500': { $ref: '#/components/responses/InternalServerError' }
|
||||
|
||||
/superuser/users/{user_id}/subusers/invite:
|
||||
post:
|
||||
tags:
|
||||
- Subusers
|
||||
summary: Invite a subuser for a superuser customer account
|
||||
operationId: inviteSuperuserUserSubuser
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: user_id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [name, phone_country_code, phone]
|
||||
properties:
|
||||
name: { type: string, minLength: 3, maxLength: 255 }
|
||||
phone_country_code: { type: integer }
|
||||
phone: { type: integer }
|
||||
note: { type: string, nullable: true, maxLength: 65535 }
|
||||
enabled: { type: boolean, default: true }
|
||||
permission_template_key:
|
||||
type: string
|
||||
enum: [deactivated, driver, booking_coordinator, fleet_admin]
|
||||
permissions:
|
||||
type: array
|
||||
items: { type: string }
|
||||
responses:
|
||||
'200':
|
||||
description: Driver invited or linked
|
||||
'400': { $ref: '#/components/responses/BadRequest' }
|
||||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||||
'403': { $ref: '#/components/responses/Forbidden' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
'500': { $ref: '#/components/responses/InternalServerError' }
|
||||
|
||||
/superuser/users/{user_id}/subusers/{subuser_id}/invite/resend:
|
||||
post:
|
||||
tags:
|
||||
- Subusers
|
||||
summary: Resend a user-scoped subuser invite
|
||||
operationId: resendSuperuserUserSubuserInvite
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: user_id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: integer, minimum: 1 }
|
||||
- name: subuser_id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: integer, minimum: 1 }
|
||||
responses:
|
||||
'200':
|
||||
description: Invite resent
|
||||
'400': { $ref: '#/components/responses/BadRequest' }
|
||||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||||
'403': { $ref: '#/components/responses/Forbidden' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
'409': { $ref: '#/components/responses/Conflict' }
|
||||
'500': { $ref: '#/components/responses/InternalServerError' }
|
||||
|
||||
/superuser/users/{user_id}/subusers/grants/{grant_id}:
|
||||
patch:
|
||||
tags:
|
||||
- Subusers
|
||||
summary: Update a user-scoped subuser grant
|
||||
operationId: updateSuperuserUserSubuserGrant
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: user_id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: integer, minimum: 1 }
|
||||
- name: grant_id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: integer, minimum: 1 }
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SubuserGrantUpdateRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Grant updated
|
||||
'400': { $ref: '#/components/responses/BadRequest' }
|
||||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||||
'403': { $ref: '#/components/responses/Forbidden' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
'500': { $ref: '#/components/responses/InternalServerError' }
|
||||
|
||||
/subusers:
|
||||
get:
|
||||
tags:
|
||||
@@ -2038,6 +2215,35 @@ paths:
|
||||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||||
'500': { $ref: '#/components/responses/InternalServerError' }
|
||||
|
||||
/subusers/permission-templates:
|
||||
get:
|
||||
tags:
|
||||
- Subusers
|
||||
summary: List simplified subuser permission templates
|
||||
description: Returns backend-owned driver access profiles and grouped capability metadata for subuser grants.
|
||||
operationId: listSubuserPermissionTemplates
|
||||
security:
|
||||
- BearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: Permission templates fetched
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
templates:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/SubuserPermissionTemplate'
|
||||
groups:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/SubuserPermissionGroup'
|
||||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||||
'403': { $ref: '#/components/responses/Forbidden' }
|
||||
'500': { $ref: '#/components/responses/InternalServerError' }
|
||||
|
||||
# Authentication Endpoints
|
||||
/auth/login:
|
||||
post:
|
||||
@@ -7438,6 +7644,139 @@ paths:
|
||||
'403': { $ref: '#/components/responses/Forbidden' }
|
||||
'500': { $ref: '#/components/responses/InternalServerError' }
|
||||
|
||||
/superuser/users/{user_id}/vehicles:
|
||||
get:
|
||||
tags: [Vehicles]
|
||||
summary: List vehicles for a selected superuser user
|
||||
operationId: listSuperuserUserVehicles
|
||||
parameters:
|
||||
- name: user_id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: integer, minimum: 1 }
|
||||
- $ref: '#/components/parameters/PageParam'
|
||||
- $ref: '#/components/parameters/PerPageParam'
|
||||
responses:
|
||||
'200':
|
||||
description: User-scoped vehicles retrieved
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Vehicle'
|
||||
'400': { $ref: '#/components/responses/BadRequest' }
|
||||
'403': { $ref: '#/components/responses/Forbidden' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
post:
|
||||
tags: [Vehicles]
|
||||
summary: Add a vehicle for a selected superuser user
|
||||
operationId: addSuperuserUserVehicle
|
||||
parameters:
|
||||
- name: user_id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: integer, minimum: 1 }
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [reg, type]
|
||||
properties:
|
||||
reg: { type: string, minLength: 2, maxLength: 12 }
|
||||
type: { type: integer }
|
||||
wash_subscription: { type: boolean, default: false }
|
||||
reference: { type: string, nullable: true, maxLength: 255 }
|
||||
customer_id:
|
||||
type: integer
|
||||
description: Optional guard value; must match the selected user's customer number.
|
||||
responses:
|
||||
'200':
|
||||
description: Vehicle created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Vehicle'
|
||||
'400': { $ref: '#/components/responses/BadRequest' }
|
||||
'403': { $ref: '#/components/responses/Forbidden' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
put:
|
||||
tags: [Vehicles]
|
||||
summary: Edit a vehicle for a selected superuser user
|
||||
operationId: editSuperuserUserVehicle
|
||||
parameters:
|
||||
- name: user_id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: integer, minimum: 1 }
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [id]
|
||||
properties:
|
||||
id: { type: integer, minimum: 1 }
|
||||
reg: { type: string, minLength: 2, maxLength: 12 }
|
||||
type: { type: integer }
|
||||
wash_subscription: { type: boolean }
|
||||
reference: { type: string, nullable: true, maxLength: 255 }
|
||||
customer_id:
|
||||
type: integer
|
||||
description: Optional guard value; moving vehicles between customers is not allowed here.
|
||||
responses:
|
||||
'200':
|
||||
description: Vehicle updated
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Vehicle'
|
||||
'400': { $ref: '#/components/responses/BadRequest' }
|
||||
'403': { $ref: '#/components/responses/Forbidden' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
delete:
|
||||
tags: [Vehicles]
|
||||
summary: Delete a vehicle for a selected superuser user
|
||||
operationId: deleteSuperuserUserVehicle
|
||||
parameters:
|
||||
- name: user_id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: integer, minimum: 1 }
|
||||
- name: id
|
||||
in: query
|
||||
required: true
|
||||
schema: { type: integer, minimum: 1 }
|
||||
responses:
|
||||
'200': { description: Vehicle deleted }
|
||||
'400': { $ref: '#/components/responses/BadRequest' }
|
||||
'403': { $ref: '#/components/responses/Forbidden' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
|
||||
/superuser/users/{user_id}/vehicles/summary:
|
||||
get:
|
||||
tags: [Vehicles]
|
||||
summary: Summarize vehicles for a selected superuser user
|
||||
operationId: summarizeSuperuserUserVehicles
|
||||
parameters:
|
||||
- name: user_id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: integer, minimum: 1 }
|
||||
responses:
|
||||
'200':
|
||||
description: User-scoped vehicle summary
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/VehicleManagementSummary'
|
||||
'400': { $ref: '#/components/responses/BadRequest' }
|
||||
'403': { $ref: '#/components/responses/Forbidden' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
|
||||
# Vehicles Endpoints
|
||||
/vehicles:
|
||||
get:
|
||||
@@ -16532,6 +16871,55 @@ components:
|
||||
format: date-time
|
||||
nullable: true
|
||||
|
||||
SubuserManagementRow:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: integer }
|
||||
username: { type: string, nullable: true }
|
||||
name: { type: string, nullable: true }
|
||||
email: { type: string, format: email, nullable: true }
|
||||
phone_country_code: { type: integer, nullable: true }
|
||||
phone: { type: integer, nullable: true }
|
||||
created_at: { type: string, format: date-time, nullable: true }
|
||||
updated_at: { type: string, format: date-time, nullable: true }
|
||||
suspended_at: { type: string, format: date-time, nullable: true }
|
||||
two_factor_enabled: { type: boolean }
|
||||
setup_required: { type: boolean }
|
||||
invite_accepted: { type: boolean }
|
||||
can_resend_invite: { type: boolean }
|
||||
profile_editable_by_manager: { type: boolean }
|
||||
customer_number: { type: integer }
|
||||
customer_name: { type: string, nullable: true }
|
||||
grant_id: { type: integer, nullable: true }
|
||||
grant_enabled: { type: boolean }
|
||||
grant_note: { type: string, nullable: true }
|
||||
grant_permissions:
|
||||
type: array
|
||||
items: { type: string }
|
||||
permissions:
|
||||
type: array
|
||||
items: { type: string }
|
||||
permission_template_key:
|
||||
type: string
|
||||
enum: [deactivated, driver, booking_coordinator, fleet_admin, custom]
|
||||
permission_groups:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/SubuserPermissionGroup'
|
||||
grant_created_at: { type: string, format: date-time, nullable: true }
|
||||
grant_updated_at: { type: string, format: date-time, nullable: true }
|
||||
access_state:
|
||||
type: string
|
||||
enum: [active, pending_setup, disabled, inactive]
|
||||
|
||||
SubuserManagementSummary:
|
||||
type: object
|
||||
properties:
|
||||
total: { type: integer }
|
||||
active: { type: integer }
|
||||
pending_setup: { type: integer }
|
||||
disabled: { type: integer }
|
||||
|
||||
SubuserGrantCreateRequest:
|
||||
type: object
|
||||
required:
|
||||
@@ -16556,6 +16944,9 @@ components:
|
||||
description: Optional list of permission keys; defaults will be applied if omitted
|
||||
items:
|
||||
type: string
|
||||
permission_template_key:
|
||||
type: string
|
||||
enum: [deactivated, driver, booking_coordinator, fleet_admin]
|
||||
|
||||
SubuserGrantUpdateRequest:
|
||||
type: object
|
||||
@@ -16570,6 +16961,40 @@ components:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
permission_template_key:
|
||||
type: string
|
||||
enum: [deactivated, driver, booking_coordinator, fleet_admin]
|
||||
|
||||
SubuserPermissionGroup:
|
||||
type: object
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
capabilities:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
SubuserPermissionTemplate:
|
||||
type: object
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
enum: [deactivated, driver, booking_coordinator, fleet_admin]
|
||||
label:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
enabled:
|
||||
type: boolean
|
||||
permissions:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
permission_groups:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/SubuserPermissionGroup'
|
||||
|
||||
SubuserGrantSummary:
|
||||
type: object
|
||||
@@ -20188,6 +20613,20 @@ components:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
VehicleManagementSummary:
|
||||
type: object
|
||||
required: [total, wash_subscription, self_service]
|
||||
properties:
|
||||
total:
|
||||
type: integer
|
||||
minimum: 0
|
||||
wash_subscription:
|
||||
type: integer
|
||||
minimum: 0
|
||||
self_service:
|
||||
type: integer
|
||||
minimum: 0
|
||||
|
||||
Notification:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
Reference in New Issue
Block a user