Skip to content

Commit 7e1150e

Browse files
Alwil17mbradioufbradlabtiger-githubb
authored
Hope it would work (#16)
* Typescript api initialzed * Update README * Add license file * Task in progress * Project task completed * Task in progress * Auth management + basic seed task completed * Add middleware with roles guard * Update README file * Update tsconfig * Reproduced entities * improved package.json * just changed name for more flexibility * Fixed datasource to run migrations * Added services * Added class-validator and Dtos * Added controller * Added routes * Pushed router to index.ts * Added and tested seeder * Testing swagger integration * Merging local devs to master (#4) * Dev (#2) * Typescript api initialzed * Update README * Add license file * Task in progress * Project task completed * Task in progress * Auth management + basic seed task completed * Add middleware with roles guard * Update README file * Update tsconfig --------- Co-authored-by: mbradiouf14 <[email protected]> Co-authored-by: bradlab <[email protected]> * Reproduced entities * improved package.json * just changed name for more flexibility * Fixed datasource to run migrations * Added services * Added class-validator and Dtos * Added controller * Added routes * Pushed router to index.ts * Added and tested seeder * Testing swagger integration --------- Co-authored-by: KARBOU Aristide <[email protected]> Co-authored-by: mbradiouf14 <[email protected]> Co-authored-by: bradlab <[email protected]> * Reproduced entities * improved package.json * just changed name for more flexibility # Conflicts: # src/config/data-source.ts # src/controllers/auth.controller.ts # src/controllers/user.controllers.ts # src/dto/user.dto.ts # src/index.ts # src/middleware/authorization.ts # src/routes/user.routes.ts dd * Added services * Added class-validator and Dtos * Added controller * Added routes * Pushed router to index.ts * Added and tested seeder * Init * Merged completely with devmain * User entity rename file * User entity removed * Rename Subject to Course + Add auth and users swagger doc * Add swagger for all models and routes * Add DTO validator on Auth and User routes * Fixed env variables * Added vercel support * Mind delete yarn * Delete yarn.lock * Adapting ts * Testing in local * Fixed vercel.json * servless ready * Testing gpt fix * Desparate fix * Desparate fix * servless ready --------- Co-authored-by: mbradiouf14 <[email protected]> Co-authored-by: bradlab <[email protected]> Co-authored-by: KARBOU Aristide <[email protected]>
1 parent af74c32 commit 7e1150e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+3175
-2210
lines changed

.example.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
PORT = 19200
2-
DB_HOST = localhost
3-
DB_PORT = 5432
2+
DATABASE_URL = localhost
3+
POSTGRES_URL = 5432
44
DB_USERNAME = postgres
55
DB_PASSWORD = 123456789
66
DB_DATABASE = step

.gitignore

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
1-
.idea/
2-
.vscode/
1+
# Node
32
node_modules/
3+
npm-debug.log*
4+
5+
# Build output
46
build/
5-
tmp/
6-
temp/
77

88
# Env
99
.env
10+
.env.*.local
11+
12+
# Vercel
13+
.vercel/
14+
15+
# Logs
16+
logs/
17+
*.log
18+
19+
# MacOS
20+
.DS_Store
21+
22+
# IDE
23+
.vscode/
24+
.idea/

package-lock.json

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

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
"type": "commonjs",
66
"scripts": {
77
"watch": "tsc -w",
8-
"dev": "nodemon",
9-
"start:dev": "concurrently \"tsc -w\" \"nodemon build/index.js\"",
108
"build": "tsc",
11-
"start": "ts-node src/index.ts",
9+
"vercel-build": "npm run build",
10+
"dev": "ts-node src/index.ts",
11+
"start": "node build/index.js",
1212
"typeorm": "typeorm-ts-node-commonjs",
1313
"migration:create": "typeorm migration:create src/migration/MigrationName -- -d src/config/data-source.ts",
1414
"migration:generate": "npm run typeorm migration:generate src/migration/generated -- -d src/config/data-source.ts",
@@ -25,7 +25,7 @@
2525
"concurrently": "^9.1.2",
2626
"nodemon": "^3.1.8",
2727
"ts-node": "10.7.0",
28-
"typescript": "4.5.2"
28+
"typescript": "^5.8.3"
2929
},
3030
"dependencies": {
3131
"@types/cors": "^2.8.15",

resources/schema.puml

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
' *************** Entités de la structure de l'organisation ***************
33

44
class Organisation {
5-
- nom : String
5+
- name : String
66
- universites : List<Universite>
77
}
88

99
class Universite {
10-
- nom : String
10+
- name : String
1111
- departements : List<Departement>
12-
- responsableUniversite : User
12+
- responsable : User
1313
}
1414

1515
class User {
@@ -19,26 +19,27 @@ class User {
1919
- email : String
2020
- password : String
2121
- role : String "USER, ADMIN, TEACHER, DELEGATE, SUPERVISOR"
22-
- subjects : List<Subject>
22+
- subjects : List<Course>
2323
- programme : Programme
2424
}
2525

2626
class Departement {
27-
- nom : String
28-
- programmes : List<Programme>
27+
- name : String
28+
- programs : List<Programme>
2929
}
3030

3131
class Programme {
32-
- nom : String
33-
- subjects : List<Subject>
32+
- name : String
33+
- subjects : List<Course>
3434
}
3535

3636
class AcademicYear {
3737
- periode : String "ex: 2024-2025"
3838
}
3939

40-
class Subject {
41-
- nom : String
40+
' **** Cours ou Matière ****
41+
class Course {
42+
- name : String
4243
- volumeHoraire : int
4344
}
4445

@@ -49,7 +50,7 @@ class ClassSession {
4950
- heureDebut : Time
5051
- heureFin : Time
5152
- academicYear : AcademicYear
52-
- subject : Subject
53+
- subject : Course
5354
- professor : User
5455
- classRepresentative : User
5556
}
@@ -58,15 +59,15 @@ class ClassSession {
5859

5960
class Emargement {
6061
- id : String
61-
- timestamp : DateTime
62+
- createdAt : DateTime
6263
- status : String "En attente, Présent, Signalé absent"
6364
- classSession : ClassSession
6465
- professor : User
6566
}
6667

6768
class Notification {
6869
- id : String
69-
- timestamp : DateTime
70+
- createdAt : DateTime
7071
- message : String
7172
- status : String "Envoyée, Confirmée"
7273
- emargement : Emargement
@@ -78,11 +79,11 @@ class Notification {
7879
Organisation "1" -- "1..*" Universite : contient
7980
Universite "1" -- "1..*" Departement : comprend
8081
Departement "1" -- "1..*" Programme : offre
81-
Programme "1" -- "1..*" Subject : propose
82+
Programme "1" -- "1..*" Course : propose
8283
Universite "1" -- "1" User : gérée_par
8384

8485
ClassSession "1" -- "1" AcademicYear : planifiée_dans
85-
ClassSession "1" -- "1" Subject : concerne
86+
ClassSession "1" -- "1" Course : concerne
8687
ClassSession "1" -- "1" User : donné_par
8788
ClassSession "1" -- "1" User : validée_par
8889

src/config/data-source.ts

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,41 @@
11
import "reflect-metadata"
2-
import { DataSource } from "typeorm"
2+
import { DataSource } from "typeorm";
33
import * as dotenv from "dotenv";
4-
import {AcademicYear} from "../entity/AcademicYear.entity";
5-
import {Organisation} from "../entity/Organisation.entity";
6-
import {Universite} from "../entity/Universite.entity";
7-
import {Departement} from "../entity/Departement.entity";
8-
import {Programme} from "../entity/Programme.entity";
9-
import {ClassSession} from "../entity/ClassSession.entity";
10-
import {Subject} from "../entity/Subject.entity";
11-
import {Emargement} from "../entity/Emargement.entity";
12-
import {Notification} from "../entity/Notification.entity";
13-
import { User } from "../entity/User.entity"
4+
import { AcademicYear } from "../entity/AcademicYear.entity";
5+
import { Organisation } from "../entity/Organisation.entity";
6+
import { Universite } from "../entity/Universite.entity";
7+
import { Departement } from "../entity/Departement.entity";
8+
import { Programme } from "../entity/Programme.entity";
9+
import { ClassSession } from "../entity/ClassSession.entity";
10+
import { Course } from "../entity/Course.entity";
11+
import { Emargement } from "../entity/Emargement.entity";
12+
import { Notification } from "../entity/Notification.entity";
13+
import { User } from "../entity/User.entity";
1414

15-
dotenv.config();
15+
dotenv.config()
16+
17+
const isDev = process.env.NODE_ENV === "dev"
1618

17-
const { DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD, DB_DATABASE, NODE_ENV } =
18-
process.env;
1919

2020
export const AppDataSource = new DataSource({
2121
type: "postgres",
22-
host: DB_HOST,
23-
port: parseInt(DB_PORT || "5432"),
24-
username: DB_USERNAME,
25-
password: DB_PASSWORD,
26-
database: DB_DATABASE,
27-
synchronize: NODE_ENV === "dev" ? true : false,
28-
logging: NODE_ENV === "dev" ? false : false,
29-
entities: [Organisation, Universite,Departement,Programme,AcademicYear, ClassSession, Subject,Emargement, Notification, User],
30-
migrations: ["src/migration/*.ts"],
22+
url: process.env.DATABASE_URL || process.env.POSTGRES_URL,
23+
synchronize: isDev,
24+
logging: isDev,
25+
ssl: !isDev ? { rejectUnauthorized: false } : false, // important pour Neon
26+
entities: [
27+
Organisation,
28+
Universite,
29+
Departement,
30+
Programme,
31+
AcademicYear,
32+
ClassSession,
33+
Course,
34+
Emargement,
35+
Notification,
36+
User,
37+
],
38+
migrations: [__dirname + "/migration/*.ts"],
3139
subscribers: [],
3240
});
3341

@@ -38,4 +46,4 @@ export const connectDB = async () => {
3846
} catch (error) {
3947
console.error("Database connection failed:", error);
4048
}
41-
};
49+
};
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { Request, Response } from "express";
2+
import { CourseService } from "../services/course.service";
3+
4+
const courseService = new CourseService();
5+
6+
export const createCourse = async (req: Request, res: Response) => {
7+
try {
8+
const course = await courseService.createCourse(req.body);
9+
res.status(201).json(course);
10+
} catch (error) {
11+
res.status(500).json({ message: "Erreur lors de la création de la matière", error });
12+
}
13+
};
14+
15+
export const getCourseById = async (req: Request, res: Response) => {
16+
try {
17+
const course = await courseService.getCourseById(req.params.id);
18+
if (!course) return res.status(404).json({ message: "Matière non trouvée" });
19+
res.json(course);
20+
} catch (error) {
21+
res.status(500).json({ message: "Erreur lors de la récupération de la matière", error });
22+
}
23+
};
24+
25+
export const getAllCourses = async (req: Request, res: Response) => {
26+
try {
27+
const courses = await courseService.getAllCourses();
28+
res.json(courses);
29+
} catch (error) {
30+
res.status(500).json({ message: "Erreur lors de la récupération des matières", error });
31+
}
32+
};
33+
34+
export const updateCourse = async (req: Request, res: Response) => {
35+
try {
36+
const course = await courseService.updateCourse(req.params.id, req.body);
37+
if (!course) return res.status(404).json({ message: "Matière non trouvée" });
38+
res.json(course);
39+
} catch (error) {
40+
res.status(500).json({ message: "Erreur lors de la mise à jour de la matière", error });
41+
}
42+
};
43+
44+
export const deleteCourse = async (req: Request, res: Response) => {
45+
try {
46+
await courseService.deleteCourse(req.params.id);
47+
res.status(204).send();
48+
} catch (error) {
49+
res.status(500).json({ message: "Erreur lors de la suppression de la matière", error });
50+
}
51+
};

src/controllers/emargement.controller.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Request, Response } from "express";
22
import { EmargementService } from "../services/emargement.service";
3+
import { EmargementStatus } from "../entity/Emargement.entity";
34

45
const emargementService = new EmargementService();
56

@@ -41,6 +42,16 @@ export const updateEmargement = async (req: Request, res: Response) => {
4142
}
4243
};
4344

45+
export const setEmargementState = async (req: Request, res: Response) => {
46+
try {
47+
const emargement = await emargementService.setStatus(req.params.id, req.params.status as EmargementStatus);
48+
if (!emargement) return res.status(404).json({ message: "Émargement non trouvé" });
49+
res.json(emargement);
50+
} catch (error) {
51+
res.status(500).json({ message: "Erreur lors de la mise à jour de l'état de l'émargement", error });
52+
}
53+
};
54+
4455
export const deleteEmargement = async (req: Request, res: Response) => {
4556
try {
4657
await emargementService.deleteEmargement(req.params.id);

src/controllers/user.controllers.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Request, Response } from "express";
22
import * as cache from "memory-cache";
33
import { UserService } from "../services/user.service";
44
import { CreateUserDto } from "../dto/user.dto";
5-
import {User} from "../entity/User.entity";
5+
import { UserFactory } from "../factory/user.factory";
66

77
const userService = new UserService();
88

@@ -14,7 +14,7 @@ export const createUser = async (req: Request, res: Response) => {
1414
if (existingUser) {
1515
return res.status(409).json({ message: "Email already exists!" });
1616
}
17-
const userData: Partial<User> = {
17+
const userData: CreateUserDto = {
1818
name: data.name,
1919
email: data.email,
2020
phone: data.phone,
@@ -25,7 +25,7 @@ export const createUser = async (req: Request, res: Response) => {
2525
// Créer l'utilisateur
2626
const user = await userService.createUser(userData);
2727
// Renvoie l'utilisateur créé sans le mot de passe
28-
return res.status(201).json({ ...user, password: undefined });
28+
return res.status(201).json(UserFactory.getUser(user));
2929
} catch (error) {
3030
return res.status(500).json({ message: "Erreur lors de la création de l'utilisateur", error });
3131
}
@@ -35,7 +35,7 @@ export const getUserById = async (req: Request, res: Response) => {
3535
try {
3636
const user = await userService.getUserById(req.params.id);
3737
if (!user) return res.status(404).json({ message: "Utilisateur non trouvé" });
38-
return res.json(user);
38+
return res.json(UserFactory.getUserDeeply(user));
3939
} catch (error) {
4040
return res.status(500).json({ message: "Erreur lors de la récupération de l'utilisateur", error });
4141
}
@@ -53,7 +53,7 @@ export const getAllUsers = async (req: Request, res: Response) => {
5353
const users = await userService.getAllUsers();
5454
// Stocke les utilisateurs en cache pour 6000 ms (6 secondes)
5555
cache.put(cacheKey, users, 6000);
56-
return res.status(200).json(users);
56+
return res.status(200).json(UserFactory.getUsers(users));
5757
} catch (error) {
5858
return res.status(500).json({ message: "Erreur lors de la récupération des utilisateurs", error });
5959
}
@@ -78,7 +78,7 @@ export const updateUser = async (req: Request, res: Response) => {
7878
const updatedUser = await userService.updateUser(id, req.body);
7979
// Vider le cache pour forcer l'actualisation
8080
cache.del("users-list");
81-
return res.status(200).json(updatedUser);
81+
return res.status(200).json(UserFactory.getUser(updatedUser));
8282
} catch (error) {
8383
return res.status(500).json({ message: "Erreur lors de la mise à jour de l'utilisateur", error });
8484
}
@@ -105,7 +105,7 @@ export const getUserByEmail = async (req: Request, res: Response) => {
105105
try {
106106
const user = await userService.getUserByEmail(req.params.email);
107107
if (!user) return res.status(404).json({ message: "Utilisateur non trouvé" });
108-
return res.json(user);
108+
return res.json(UserFactory.getUser(user));
109109
} catch (error) {
110110
return res.status(500).json({ message: "Erreur lors de la récupération de l'utilisateur", error });
111111
}

0 commit comments

Comments
 (0)