Skip to content

Commit 8cd4894

Browse files
committed
annotation and test are added
1 parent c916671 commit 8cd4894

10 files changed

Lines changed: 814 additions & 50 deletions

File tree

bun.lock

Lines changed: 216 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
"scripts": {
1010
"test": "jest",
1111
"apidoc": "apidoc -c apidoc.json",
12-
"start" : "bun run src/server.ts",
12+
"start": "bun run src/server.ts",
1313
"lint": "eslint src/",
1414
"format": "prettier --write src/",
1515
"lint:fix": "eslint src/ --fix",
1616
"precommit": "lint-staged",
17-
"migrate:first":"bunx prisma migrate dev --name init",
17+
"migrate:first": "bunx prisma migrate dev --name init",
1818
"migrate": "bunx prisma migrate dev",
1919
"generate": "bunx prisma generate"
2020
},
@@ -32,6 +32,7 @@
3232
"devDependencies": {
3333
"@eslint/js": "^9.31.0",
3434
"@types/bun": "latest",
35+
"@types/jest": "^30.0.0",
3536
"@typescript-eslint/eslint-plugin": "^8.36.0",
3637
"@typescript-eslint/parser": "^8.36.0",
3738
"eslint": "^9.31.0",
@@ -44,14 +45,15 @@
4445
"prisma": "^6.11.1",
4546
"ts-node-dev": "^2.0.0",
4647
"typescript": "^5.8.3",
47-
"@types/jest": "^30.0.0",
48-
"typescript-eslint": "^8.36.0"
48+
"typescript-eslint": "^8.36.0",
49+
"vitest": "^3.2.4"
4950
},
5051
"dependencies": {
5152
"@prisma/client": "^6.11.1",
5253
"@supabase/supabase-js": "^2.50.5",
5354
"@types/cors": "^2.8.19",
5455
"@types/express": "^5.0.3",
56+
"@types/mocha": "^10.0.10",
5557
"@types/multer": "^2.0.0",
5658
"@types/node": "^24.0.13",
5759
"apidoc": "^1.2.0",
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
Warnings:
3+
4+
- Made the column `imageUrl` on table `Project` required. This step will fail if there are existing NULL values in that column.
5+
- Made the column `githubUrl` on table `Project` required. This step will fail if there are existing NULL values in that column.
6+
7+
*/
8+
-- AlterTable
9+
ALTER TABLE "Project" ALTER COLUMN "imageUrl" SET NOT NULL,
10+
ALTER COLUMN "githubUrl" SET NOT NULL;

prisma/schema.prisma

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ model MemberAchievement {
102102
model Project {
103103
id Int @id @default(autoincrement())
104104
name String
105-
imageUrl String?
106-
githubUrl String?
105+
imageUrl String
106+
githubUrl String
107107
deployUrl String?
108108
109109
// Audit fields

src/controllers/project.controller.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const getProjectById = async ( req : Request , res : Response ) => {
1717

1818
try{
1919
const projectId = parseInt( req.params.projectId );
20+
2021
if( !projectId ) throw new ApiError( " Field is missing !!!" , 400);
2122

2223
const project = await projectService.getProjectById( projectId );
@@ -31,10 +32,10 @@ export const createProject = async ( req : Request , res : Response ) => {
3132

3233
try {
3334
const projectContent = req.body;
35+
const AdminId = req.body.AdminId;
36+
if( projectContent.name.length === 0 || !projectContent.githubUrl || !AdminId || !projectContent.imageUrl) throw new ApiError( " Field is missing !!!" , 400);
3437

35-
if( !projectContent.name || !projectContent.githubUrl) throw new ApiError( " Field is missing !!!" , 400);
36-
37-
const project = await projectService.createProject(projectContent);
38+
const project = await projectService.createProject(projectContent , AdminId);
3839
res.status(200).json(project);
3940

4041
} catch (error) {
@@ -47,7 +48,9 @@ export const updateProjects = async ( req : Request , res : Response ) => {
4748
try {
4849
const projectInfo = req.body;
4950
const projectId = parseInt(req.params.projectId);
50-
if( !projectId ) throw new ApiError( " Send The project id " , 400);
51+
const updatedById = req.body.updatedById;
52+
53+
if( !projectId || projectInfo.length === 0 || !updatedById) throw new ApiError( " Send The project id " , 400);
5154

5255
const project = await projectService.updateProjects( projectInfo , projectId );
5356
res.status(200).json(project)
@@ -76,7 +79,7 @@ export const deleteProjects = async ( req : Request , res : Response ) => {
7679
export const getMembersByProjectId = async ( req : Request , res : Response ) => {
7780

7881
try {
79-
const projectId = parseInt( req.params.ProjectId );
82+
const projectId = parseInt( req.params.projectId );
8083
if( !projectId ) throw new ApiError( " Project Id required !!! " , 400);
8184

8285
const members = await projectService.getMembersByProjectId(projectId);
@@ -95,7 +98,7 @@ export const addMembers = async ( req : Request , res : Response ) => {
9598
try {
9699
const projectId = parseInt( req.params.projectId );
97100
const memberData = req.body.memberId;
98-
if( !projectId || memberData.length === 0) throw new ApiError(" field is missing " , 400);
101+
if( !projectId || !memberData || memberData.length === 0) throw new ApiError(" field is missing " , 400);
99102

100103
const data = memberData.map( (memberId: string) => ({
101104
projectId,
@@ -119,6 +122,8 @@ export const removeMembers = async ( req : Request , res : Response ) => {
119122
memberId : req.body.memberId
120123
}
121124

125+
if( !data.projectId || !data.memberId) throw new ApiError(' Field is missing !!!' , 400);
126+
122127
const removedMember = await projectService.removeMembers(data);
123128
res.status(200).json( removedMember );
124129

src/routes/projects.ts

Lines changed: 106 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,133 @@ export default function projectsRouter(
2020
) {
2121
const router = Router()
2222

23-
// Getting all User
23+
// Get all User
24+
/**
25+
* @api {get} /api/v1/projects Get all projects
26+
* @apiName getProjects
27+
* @apiGroup Project
28+
*
29+
* @apiSuccess {Object{}} An array of all projects
30+
*/
2431
router.get('/', getProjects)
2532

2633
// get Project by Id
34+
/**
35+
* @api {get} /api/v1/projects/:projectId Get specific project by its ID
36+
* @apiName getProjectById
37+
* @apiGroup Project
38+
*
39+
* @apiParam {UUID} projectId ID of the project
40+
* @apiSuccess {object{}} Get single project whoes ID -> projectID
41+
*
42+
* @apiError {object{}} No projects with such ID
43+
*/
2744
router.get('/:projectId', getProjectById)
2845

2946
// Create project
47+
/**
48+
* @api {post} /api/v1/projects/create Create the new Project
49+
* @apiName createProject
50+
* @apiGroup Project
51+
*
52+
* @apiParam {Request body} {string} Name of the project
53+
* @apiParam {Request body} {string} Image usrl of project Photo
54+
* @apiParam {Request body} {string} githubUrl of project
55+
* @apiParam {Request body} {string} deploy link of project
56+
* @apiParam { UUID } {string} AdminID ID of the admin who create the project
57+
*
58+
* @apiSuccess {object{}} created project by the admin
59+
*
60+
* @apiError { error 400} some fields are missing
61+
* @apiError { error 500} error related to the db interaction
62+
*/
3063
router.post('/create', createProject )
3164

3265
// Update Project
33-
router.patch('/:projectId', updateProjects )
66+
/**
67+
* @api {patch} /api/v1/projects/:projectId/update Update the projects with given project id
68+
* @apiName updateProjects
69+
* @apiGroup Project
70+
*
71+
* @apiParam {Request body} ? {string} Name of the project
72+
* @apiParam {Request body} ? {string} Image usrl of project Photo
73+
* @apiParam {Request body} ? {string} githubUrl of project
74+
* @apiParam {Request body} ? {string} deploy link of project
75+
* @apiParam { UUID } {string} AdminID ID of the admin who update the project
76+
* @apiParam { projectID } {number} projectID ID of the project
77+
*
78+
* @apiSuccess {object{}} updated project by the admin
79+
*
80+
* @apiError { error 400} some fields are missing
81+
* @apiError { error 500} error related to the db interaction
82+
*/
83+
router.patch('/:projectId/update', updateProjects )
3484

3585
// delete projects
36-
router.delete('/:projectId', deleteProjects )
86+
87+
/**
88+
* @api {delete} /api/v1/projects/:projectId/delete Delete the project
89+
* @apiName deleteProjects
90+
* @apiGroup Project
91+
*
92+
* @apiParam { projectId } { number } projectID ID of the project to be delete
93+
* @apiParam { UUID } {string} AdminID ID of the admin who delete the project
94+
*
95+
* @apiSuccess {Object{}} A deleted project
96+
*
97+
* @apiError {error 400} Some fields are missing
98+
* @apiError {error 500} Internal server error
99+
*/
100+
router.delete('/:projectId/delete', deleteProjects )
37101

38102
// getMember by ProjectId
103+
/**
104+
* @api {get} /api/v1/projects/:projectId/members Get members enroll in projects
105+
* @apiName getMembersBYProjectId
106+
* @apiGroup MemberProject
107+
*
108+
* @apiParam { projectId } { number } projectID ID of the project
109+
*
110+
* @apiSuccess {Object{}} array of member associated with projects
111+
*
112+
* @apiError {error 400} Some fields are missing
113+
* @apiError {error 500} Internal server error
114+
*/
39115

40116
router.get('/:projectId/members', getMembersByProjectId )
41117

42118
// add member to project
119+
/**
120+
* @api {post} /api/v1/projects/:projectId/members add members into projects
121+
* @apiName addmembers
122+
* @apiGroup MemberProject
123+
*
124+
* @apiParam { projectId } { number } projectID ID of the project
125+
* @apiParam { Request body} { array } constains the array of memberId
126+
*
127+
* @apiSuccess {Object{}} array of member added into projects
128+
*
129+
* @apiError {error 400} Some fields are missing
130+
* @apiError {error 500} Internal server error
131+
*/
132+
43133

44134
router.post('/:projectId/members' , addMembers )
45135

46136
// Remover the memnber
137+
/**
138+
* @api {delete} /api/v1/projects/:projectId/members/:memberId add members into projects
139+
* @apiName removeMembers
140+
* @apiGroup MemberProject
141+
*
142+
* @apiParam { projectId } { number } projectID ID of the project
143+
* @apiParam { memberId} { string } memberID ID of the member
144+
*
145+
* @apiSuccess {Object{}} member which are deleted
146+
*
147+
* @apiError {error 400} Some fields are missing
148+
* @apiError {error 500} Internal server error
149+
*/
47150

48151
router.delete( '/:projectId/members/:memberId', removeMembers)
49152

src/services/project.service.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ export const getProjectById = async ( projectId : number ) => {
1616
})
1717
};
1818

19-
export const createProject = async ( projectContent : projectContent ) => {
19+
export const createProject = async ( projectContent : projectContent , AdminId : string) => {
2020

2121
return await prisma.project.create({
2222
data : {
2323
name : projectContent.name,
2424
imageUrl : projectContent.imageUrl,
2525
githubUrl : projectContent.githubUrl,
2626
deployUrl : projectContent.deployUrl,
27+
createdById : AdminId,
2728
},
2829
})
2930
};

src/types/project.d.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ declare global {
66

77
type projectContent = {
88
name: string,
9-
imageUrl: string ?,
9+
imageUrl: string ,
1010
githubUrl: string,
11-
deployUrl: string?,
11+
deployUrl: string?
1212
}
1313

1414
type addMembersData = {
@@ -27,5 +27,7 @@ declare global {
2727
imageUrl : string,
2828
githubUrl : string,
2929
deployUrl : string,
30+
updatedById : string
31+
3032
}
3133
}

0 commit comments

Comments
 (0)