Skip to content

Commit 2e7efca

Browse files
author
Lasim
committed
feat: add user teams management in UserDetail.vue and implement related API tests
- Enhanced UserDetail.vue to fetch and display user teams, including loading and error states. - Introduced new interfaces for Team and TeamsResponse to structure team data. - Added API endpoint to fetch user teams and integrated it into the user detail view. - Created end-to-end tests for admin user access to their own and other users' teams. - Implemented unit tests for role middleware to ensure proper permission checks and error handling.
1 parent e0e3fd0 commit 2e7efca

File tree

10 files changed

+1994
-14
lines changed

10 files changed

+1994
-14
lines changed

services/backend/api-spec.json

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3347,6 +3347,189 @@
33473347
"type": "string",
33483348
"format": "date-time",
33493349
"description": "Team last update date"
3350+
},
3351+
"role": {
3352+
"type": "string",
3353+
"enum": [
3354+
"team_admin",
3355+
"team_user"
3356+
],
3357+
"description": "User role in the team"
3358+
},
3359+
"is_owner": {
3360+
"type": "boolean",
3361+
"description": "Whether the user is the owner of this team"
3362+
}
3363+
},
3364+
"required": [
3365+
"id",
3366+
"name",
3367+
"slug",
3368+
"description",
3369+
"owner_id",
3370+
"created_at",
3371+
"updated_at"
3372+
],
3373+
"additionalProperties": false
3374+
},
3375+
"description": "Array of user teams"
3376+
}
3377+
},
3378+
"required": [
3379+
"success",
3380+
"teams"
3381+
],
3382+
"additionalProperties": false,
3383+
"description": "User teams retrieved successfully"
3384+
}
3385+
}
3386+
}
3387+
},
3388+
"401": {
3389+
"description": "Unauthorized - Authentication required",
3390+
"content": {
3391+
"application/json": {
3392+
"schema": {
3393+
"type": "object",
3394+
"properties": {
3395+
"success": {
3396+
"type": "boolean",
3397+
"description": "Indicates if the operation was successful (false for errors)",
3398+
"default": false
3399+
},
3400+
"error": {
3401+
"type": "string",
3402+
"description": "Error message"
3403+
},
3404+
"details": {
3405+
"type": "array",
3406+
"description": "Additional error details (validation errors)"
3407+
}
3408+
},
3409+
"required": [
3410+
"error"
3411+
],
3412+
"additionalProperties": false,
3413+
"description": "Unauthorized - Authentication required"
3414+
}
3415+
}
3416+
}
3417+
},
3418+
"500": {
3419+
"description": "Internal Server Error",
3420+
"content": {
3421+
"application/json": {
3422+
"schema": {
3423+
"type": "object",
3424+
"properties": {
3425+
"success": {
3426+
"type": "boolean",
3427+
"description": "Indicates if the operation was successful (false for errors)",
3428+
"default": false
3429+
},
3430+
"error": {
3431+
"type": "string",
3432+
"description": "Error message"
3433+
},
3434+
"details": {
3435+
"type": "array",
3436+
"description": "Additional error details (validation errors)"
3437+
}
3438+
},
3439+
"required": [
3440+
"error"
3441+
],
3442+
"additionalProperties": false,
3443+
"description": "Internal Server Error"
3444+
}
3445+
}
3446+
}
3447+
}
3448+
}
3449+
}
3450+
},
3451+
"/api/users/{id}/teams": {
3452+
"get": {
3453+
"summary": "Get user teams by ID",
3454+
"tags": [
3455+
"Users"
3456+
],
3457+
"description": "Retrieves all teams for a specific user. Requires admin permissions to view other users' teams.",
3458+
"parameters": [
3459+
{
3460+
"schema": {
3461+
"type": "string"
3462+
},
3463+
"in": "path",
3464+
"name": "id",
3465+
"required": true,
3466+
"description": "User ID"
3467+
}
3468+
],
3469+
"security": [
3470+
{
3471+
"cookieAuth": []
3472+
}
3473+
],
3474+
"responses": {
3475+
"200": {
3476+
"description": "User teams retrieved successfully",
3477+
"content": {
3478+
"application/json": {
3479+
"schema": {
3480+
"type": "object",
3481+
"properties": {
3482+
"success": {
3483+
"type": "boolean",
3484+
"description": "Indicates if the operation was successful"
3485+
},
3486+
"teams": {
3487+
"type": "array",
3488+
"items": {
3489+
"type": "object",
3490+
"properties": {
3491+
"id": {
3492+
"type": "string",
3493+
"description": "Team ID"
3494+
},
3495+
"name": {
3496+
"type": "string",
3497+
"description": "Team name"
3498+
},
3499+
"slug": {
3500+
"type": "string",
3501+
"description": "Team slug"
3502+
},
3503+
"description": {
3504+
"type": "string",
3505+
"nullable": true,
3506+
"description": "Team description"
3507+
},
3508+
"owner_id": {
3509+
"type": "string",
3510+
"description": "Team owner ID"
3511+
},
3512+
"created_at": {
3513+
"type": "string",
3514+
"format": "date-time",
3515+
"description": "Team creation date"
3516+
},
3517+
"updated_at": {
3518+
"type": "string",
3519+
"format": "date-time",
3520+
"description": "Team last update date"
3521+
},
3522+
"role": {
3523+
"type": "string",
3524+
"enum": [
3525+
"team_admin",
3526+
"team_user"
3527+
],
3528+
"description": "User role in the team"
3529+
},
3530+
"is_owner": {
3531+
"type": "boolean",
3532+
"description": "Whether the user is the owner of this team"
33503533
}
33513534
},
33523535
"required": [
@@ -3403,6 +3586,66 @@
34033586
}
34043587
}
34053588
},
3589+
"403": {
3590+
"description": "Forbidden - Insufficient permissions",
3591+
"content": {
3592+
"application/json": {
3593+
"schema": {
3594+
"type": "object",
3595+
"properties": {
3596+
"success": {
3597+
"type": "boolean",
3598+
"description": "Indicates if the operation was successful (false for errors)",
3599+
"default": false
3600+
},
3601+
"error": {
3602+
"type": "string",
3603+
"description": "Error message"
3604+
},
3605+
"details": {
3606+
"type": "array",
3607+
"description": "Additional error details (validation errors)"
3608+
}
3609+
},
3610+
"required": [
3611+
"error"
3612+
],
3613+
"additionalProperties": false,
3614+
"description": "Forbidden - Insufficient permissions"
3615+
}
3616+
}
3617+
}
3618+
},
3619+
"404": {
3620+
"description": "Not Found - User not found",
3621+
"content": {
3622+
"application/json": {
3623+
"schema": {
3624+
"type": "object",
3625+
"properties": {
3626+
"success": {
3627+
"type": "boolean",
3628+
"description": "Indicates if the operation was successful (false for errors)",
3629+
"default": false
3630+
},
3631+
"error": {
3632+
"type": "string",
3633+
"description": "Error message"
3634+
},
3635+
"details": {
3636+
"type": "array",
3637+
"description": "Additional error details (validation errors)"
3638+
}
3639+
},
3640+
"required": [
3641+
"error"
3642+
],
3643+
"additionalProperties": false,
3644+
"description": "Not Found - User not found"
3645+
}
3646+
}
3647+
}
3648+
},
34063649
"500": {
34073650
"description": "Internal Server Error",
34083651
"content": {

0 commit comments

Comments
 (0)