Mentors
Mentor profiles, administrative mutations, and authenticated like toggling.
Status: complete · Source: content/docs/api-reference/mentors.mdx
Paths follow the reference conventions. A mentor profile contains id, name, expertise, imageUrl, linkedInUrl, and clubId. A mentor belongs to a club but is not linked to a user account; see Data Model.
List mentors
/mentorsPublicReturn mentor profiles with their club and total like count.
No pagination or validated query parameters. HTTP 200:
{
"mentors": [{
"id": "illustrative-mentor-id",
"name": "Alex Morgan",
"expertise": "Web development",
"imageUrl": "https://example.com/mentor.png",
"linkedInUrl": "",
"clubId": "illustrative-club-id",
"club": {"name": "Example Coding Club", "imageUrl": null},
"likeCount": 0
}]
}Profiles are sorted by name ascending. _count is replaced with likeCount, and the controller sets Cache-Control: public, s-maxage=300, stale-while-revalidate=600 on success. Its catch branch also returns 200, with { "mentors": [] }, after logging the error. An empty list therefore does not prove the directory is empty.
Toggle a like
/mentors/:mentorId/likeAuthenticatedLike an unliked mentor or remove the current user's existing like.
No role restriction, request body, or Zod parameter validator. mentorId identifies the mentor; the user comes from the token. The controller checks mentor existence, then the unique (userId, mentorId) pair. The same endpoint performs both operations; there is no separate unlike route.
HTTP 200 returns one of:
{"message":"Mentor liked successfully","liked":true,"likeCount":1}{"message":"Mentor unliked successfully","liked":false,"likeCount":0}liked describes the resulting relationship for this user; likeCount is the mentor's total, counted after the write. Repeating the request toggles again rather than ensuring a fixed liked state. The lookup, write, and count are separate operations; concurrent requests can hit the unique constraint or other caught failures.
Errors: middleware 401; controller 401 Authentication required if no user identifier is available; 404 Mentor not found; 500 Error toggling mentor like.
List the current user's liked mentors
/mentors/likedAuthenticatedReturn mentor profiles liked by the token's user.
No role restriction, validated query, or explicit ordering. HTTP 200 returns { "likedMentors": [...] }. Items have the same profile, selected club, and likeCount fields as public listing. They are flattened mentor objects, not MentorLike records; _count is set to undefined and omitted from JSON. Errors: middleware 401; controller 401 Authentication required; 500 Error fetching liked mentors.
Create a mentor
/mentorsAuthenticated · Role restrictedCreate a mentor profile attached to an existing club.
Authorization: ADMIN. Zod requires name (nonempty string), expertise (string, minimum two characters), and clubId (nonempty string). imageUrl is an optional URL in the schema but required by the controller. Optional linkedInUrl is read from the original body and defaults to "" when null/absent; it has no schema URL/type validation. Send a string for this persisted string field.
POST /mentors
Authorization: Bearer <admin-jwt>
Content-Type: application/json
{"name":"Alex Morgan","expertise":"Web development","imageUrl":"https://example.com/mentor.png","clubId":"illustrative-club-id"}HTTP 201: { "mentor": ... }, containing profile scalars and club: { name }, without a like count. Errors: middleware 401/403; 400 validation or All fields are required; 500 Error creating mentor, including an unknown club foreign key.
Update a mentor
/mentors/:idAuthenticated · Role restrictedUpdate selected profile fields or club association.
Authorization: ADMIN. Zod requires nonempty path id; all body fields are optional: name (nonempty), expertise (minimum two characters), imageUrl (URL), and clubId (nonempty). The controller also reads linkedInUrl without schema validation. Omitted fields are passed as undefined and left unchanged by Prisma. An empty object passes validation; null is not accepted for the schema's string fields.
HTTP 200: { "mentor": ... }, with profile scalars and club: { name }. Errors: middleware 401/403; 400 validation; 500 Error updating mentor, including unknown mentor/club identifiers. There is no dedicated not-found pre-check.
Delete a mentor
/mentors/:idAuthenticated · Role restrictedDelete a mentor and its database-cascaded likes.
Authorization: ADMIN. Zod requires a nonempty id; no body is used. HTTP 200: { "message": "Mentor deleted successfully" }. The like foreign key uses ON DELETE CASCADE. Errors: middleware 401/403; 400 validation; 500 Error deleting mentor, including an unknown ID.
Sourcebackend/src/routes/mentors.ts
Sourcebackend/src/validators/mentors.ts
Sourcebackend/src/controllers/mentorController.ts
Sourcebackend/prisma/migrations/20251025152715_add_mentor_likes/migration.sql
