Skip to content

Commit 6f5144e

Browse files
Merge pull request #38 from call-0f-code/minor-fixes
Minor fixes
2 parents 5dde58d + 75ab289 commit 6f5144e

5 files changed

Lines changed: 178 additions & 73 deletions

File tree

src/controllers/member.controller.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export const createAMember =
4646
(supabase: SupabaseClient) => async (req: Request, res: Response) => {
4747
const {email, name, password, passoutYear, provider} = req.body;
4848

49-
if (!email || !name || !password || !passoutYear) {
49+
if (!email || !name || !password || !passoutYear || !provider) {
5050
throw new ApiError("Required fields absent", 400);
5151
}
5252

@@ -89,7 +89,8 @@ export const updateAMember =
8989
}
9090
if (imageUrl) parsedBody.profilePhoto = imageUrl;
9191

92-
await memberService.updateMember(memberId, parsedBody);
92+
if(parsedBody.password) await memberService.updatePassword(memberId, parsedBody.password);
93+
else await memberService.updateMember(memberId, parsedBody);
9394

9495
const updatedData = await memberService.getDetails(memberId);
9596
res

src/routes/members.ts

Lines changed: 91 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ export default function membersRouter(
1515
* @apiGroup Member
1616
*
1717
* @apiSuccess {Object[]} unapprovedMembers List of unapproved members.
18+
*
19+
* @apiExample {curl} Example usage:
20+
* curl -X GET http://localhost:3000/members/unapproved
1821
*/
1922
router.get("/unapproved", memberCtrl.getUnapprovedMembers);
2023

@@ -27,6 +30,9 @@ export default function membersRouter(
2730
*
2831
* @apiSuccess {Object} user Member object.
2932
* @apiError (Error 400) BadRequest No memberId provided.
33+
*
34+
* @apiExample {curl} Example usage:
35+
* curl -X GET http://localhost:3000/members/123
3036
*/
3137
router.get("/:memberId", memberCtrl.getUserDetails);
3238

@@ -35,17 +41,23 @@ export default function membersRouter(
3541
* @apiName ListAllApprovedMembers
3642
* @apiGroup Member
3743
*
38-
* @apiDescription
44+
* @apiDescription
3945
* - Returns a list of all approved members if no email query parameter is provided.
4046
* - If `email` query parameter is provided, returns the member associated with that email.
4147
*
42-
* @apiQuery {String} [email] Optional email to fetch a specific member.
48+
* @apiQuery {String} [email] Optional email to fetch a specific member.
4349
*
4450
* @apiSuccess {Object} user Single user object when email provided.
45-
+ * @apiSuccess {Object[]} user Array of approved members when no email provided.
51+
* @apiSuccess {Object[]} user Array of approved members when no email provided.
4652
* @apiSuccess {String} [message] Message in case of full list fetch.
4753
*
4854
* @apiError (400) IncorrectEmail The provided email does not match any user.
55+
*
56+
* @apiExample {curl} Example usage (list all):
57+
* curl -X GET http://localhost:3000/members
58+
*
59+
* @apiExample {curl} Example usage (get by email):
60+
* curl -X GET "http://localhost:3000/members?email=john@example.com"
4961
*/
5062
router.get("/", memberCtrl.listAllApprovedMembers);
5163

@@ -54,14 +66,27 @@ export default function membersRouter(
5466
* @apiName CreateAMember
5567
* @apiGroup Member
5668
*
57-
* @apiBody {String} email Email of the member.
58-
* @apiBody {String} name Full name of the member.
59-
* @apiBody {String} password Member's password.
60-
* @apiBody {String} passoutYear Graduation year.
61-
* @apiBody {String} imageUrl profile photo of the member.
69+
* @apiBody {String} email Email of the member. (Required)
70+
* @apiBody {String} name Full name of the member. (Required)
71+
* @apiBody {String} password Member's password. (Required)
72+
* @apiBody {String} passoutYear Graduation year (Required, e.g., "2026").
73+
* @apiBody {String} provider Authentication provider (Required, e.g., "local", "google").
74+
* @apiBody {File} [file] Profile photo file (field name: "file").
75+
*
76+
* @apiSuccess {Boolean} success Request status.
77+
* @apiSuccess {Object} user Created member object.
6278
*
63-
* @apiSuccess {Object} user Created member object.
64-
* @apiError (Error 402) ValidationError Required fields missing.
79+
* @apiError (Error 400) ApiError Required fields absent.
80+
* @apiError (Error 500) ServerError Error creating user.
81+
*
82+
* @apiExample {curl} Example usage:
83+
* curl -X POST -F "file=@profile.jpg" \
84+
* -F "email=john@example.com" \
85+
* -F "name=John Doe" \
86+
* -F "password=securePass123" \
87+
* -F "passoutYear=2026" \
88+
* -F "provider=local" \
89+
* http://localhost:3000/members
6590
*/
6691
router.post("/", upload.single("file"), memberCtrl.createAMember(supabase));
6792

@@ -72,64 +97,87 @@ export default function membersRouter(
7297
*
7398
* @apiParam {String} memberId Member's unique ID.
7499
*
100+
* @apiBody {String} memberData JSON string containing the member's updated details.
75101
* @apiBody {File} [file] Profile photo file (field name: "file").
76-
* @apiBody {String} [name] Full name of the member.
77-
* @apiBody {String} [email] Email address.
78-
* @apiBody {String} [phone] Phone number.
79-
* @apiBody {String} [bio] Short bio.
80-
* @apiBody {String} [github] GitHub handle.
81-
* @apiBody {String} [linkedin] LinkedIn handle.
82-
* @apiBody {String} [twitter] Twitter handle.
83-
* @apiBody {String} [geeksforgeeks] GeeksforGeeks username.
84-
* @apiBody {String} [leetcode] LeetCode username.
85-
* @apiBody {String} [codechef] CodeChef username.
86-
* @apiBody {String} [codeforces] Codeforces username.
87-
* @apiBody {Date} [passoutYear] Graduation year (ISO string format).
88-
*
89-
* @apiSuccess {Object} member Updated member object.
102+
*
103+
* @apiBody (memberData fields) {String} [name] Full name of the member.
104+
* @apiBody (memberData fields) {String} [email] Email address.
105+
* @apiBody (memberData fields) {String} [phone] Phone number.
106+
* @apiBody (memberData fields) {String} [bio] Short bio.
107+
* @apiBody (memberData fields) {String} [github] GitHub handle.
108+
* @apiBody (memberData fields) {String} [linkedin] LinkedIn handle.
109+
* @apiBody (memberData fields) {String} [twitter] Twitter handle.
110+
* @apiBody (memberData fields) {String} [geeksforgeeks] GeeksforGeeks username.
111+
* @apiBody (memberData fields) {String} [leetcode] LeetCode username.
112+
* @apiBody (memberData fields) {String} [codechef] CodeChef username.
113+
* @apiBody (memberData fields) {String} [codeforces] Codeforces username.
114+
* @apiBody (memberData fields) {Date} [passoutYear] Graduation year (ISO string format).
115+
* @apiBody (memberData fields) {String} [profilePhoto] (Auto-assigned if a new file is uploaded).
116+
*
117+
* @apiSuccess {Boolean} success Request status.
118+
* @apiSuccess {Object} user Updated member object.
119+
*
120+
* @apiError (Error 400) ApiError No memberId provided or invalid request data.
90121
* @apiError (Error 404) NotFound Member not found.
91-
* @apiError (Error 400) ValidationError Invalid or missing fields.
92122
* @apiError (Error 500) ServerError Unexpected error occurred during update.
123+
*
124+
* @apiExample {curl} Example usage:
125+
* curl -X PATCH -F "file=@profile.jpg" \
126+
* -F 'memberData={"name":"John Doe","email":"john@example.com"}' \
127+
* http://localhost:3000/members/123
93128
*/
94129
router.patch(
95130
"/:memberId",
96131
upload.single("file"),
97132
memberCtrl.updateAMember(supabase),
98133
);
99134

100-
/**
101-
* @api {patch} /members/approve/:memberId Approve/reject a member
135+
136+
/**
137+
* @api {patch} /members/approve/:memberId Approve a member
102138
* @apiName UpdateApprovalRequest
103139
* @apiGroup Member
104140
*
105141
* @apiParam (URL Params) {String} memberId Member ID.
106-
* @apiBody {Boolean} isApproved Approval status.
107-
* @apiBody {String} adminId Admin who approved.
142+
* @apiBody {Boolean} isApproved Approval status (true = approved, false = rejected).
143+
* @apiBody {String} adminId ID of the admin who approved/rejected.
108144
*
109-
* @apiSuccess {Object} update Approval status updated.
145+
* @apiSuccess {Object} update Approval status update result.
110146
* @apiError (Error 400) BadRequest Missing required fields.
147+
*
148+
* @apiExample {curl} Example usage:
149+
* curl -X PATCH http://localhost:3000/members/approve/123 \
150+
* -H "Content-Type: application/json" \
151+
* -d '{"isApproved": true, "adminId": "admin123"}'
111152
*/
112153
router.patch("/approve/:memberId", memberCtrl.updateRequest);
113154

114-
/**
115-
* @api {get} /members/:memberId/achievements Get member's achievements
116-
* @apiName GetUserAchievements
117-
* @apiGroup Member
118-
*
119-
* @apiParam (URL Params) {String} memberId Member ID.
120-
*
121-
* @apiSuccess {Object[]} achievements List of achievements.
122-
*/
155+
156+
/**
157+
* @api {get} /members/:memberId/achievements Get member's achievements
158+
* @apiName GetUserAchievements
159+
* @apiGroup Member
160+
*
161+
* @apiParam (URL Params) {String} memberId Member ID.
162+
*
163+
* @apiSuccess {Object[]} achievements List of achievements.
164+
*
165+
* @apiExample {curl} Example usage:
166+
* curl -X GET http://localhost:3000/members/123/achievements
167+
*/
123168
router.get("/:memberId/achievements", memberCtrl.getUserAchievements);
124169

125170
/**
126-
* @api {get} /api/members/:memberId/projects Get member's projects
171+
* @api {get} /members/:memberId/projects Get member's projects
127172
* @apiName GetUserProjects
128173
* @apiGroup Member
129174
*
130175
* @apiParam (URL Params) {String} memberId Member ID.
131176
*
132177
* @apiSuccess {Object[]} projects List of projects.
178+
*
179+
* @apiExample {curl} Example usage:
180+
* curl -X GET http://localhost:3000/members/123/projects
133181
*/
134182
router.get("/:memberId/projects", memberCtrl.getUserProjects);
135183

@@ -141,6 +189,9 @@ export default function membersRouter(
141189
* @apiParam (URL Params) {String} memberId Member ID.
142190
*
143191
* @apiSuccess {Object[]} interviews List of interviews.
192+
*
193+
* @apiExample {curl} Example usage:
194+
* curl -X GET http://localhost:3000/members/123/interviews
144195
*/
145196
router.get("/:memberId/interviews", memberCtrl.getUserInterviews);
146197

src/services/member.service.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,33 +66,35 @@ export const createMember = async (
6666

6767
export const updateMember = async (
6868
id: string,
69-
payload: UpdateMemberPayload,
69+
payload: UpdateMemberPayload
7070
) => {
7171
const { name, ...rest } = payload;
7272

73-
const member = await prisma.member.findUnique({
74-
where: {
75-
id: id,
76-
},
77-
});
78-
79-
if (!member) {
80-
throw new ApiError("Member not found", 404);
81-
}
82-
8373
const dataToUpdate = Object.fromEntries(
84-
Object.entries(rest).filter(([_, v]) => v !== undefined),
74+
Object.entries({ name, ...rest }).filter(([_, v]) => v !== undefined)
8575
);
8676

87-
if (JSON.stringify(dataToUpdate) === "{}")
88-
throw new ApiError("No fields passed", 400);
77+
if (JSON.stringify(dataToUpdate) === "{}") throw new ApiError("No fields passed", 400);
8978

9079
return await prisma.member.update({
9180
where: { id },
9281
data: dataToUpdate,
9382
});
9483
};
9584

85+
export const updatePassword = async(id: string, password: string) => {
86+
const account = await prisma.account.findFirst({
87+
where: { memberId: id },
88+
});
89+
90+
if (!account) throw new ApiError("Associated account not found", 404);
91+
92+
return await prisma.account.update({
93+
where: { id: account.id },
94+
data: { password },
95+
});
96+
}
97+
9698
export const unapprovedMembers = async () => {
9799
return await prisma.member.findMany({
98100
where: { isApproved: false },

src/types/members.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ declare global {
1515
leetcode?: string;
1616
codechef?: string;
1717
codeforces?: string;
18+
password?: string
1819
}
1920
}

0 commit comments

Comments
 (0)