Merge: Intégration des modifications locales et distantes du backend
This commit is contained in:
commit
855d2692c1
@ -1,5 +1,5 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
import { AppController } from './app.controller';
|
||||
import { AppService } from './app.service';
|
||||
|
||||
@ -8,6 +8,12 @@ import databaseConfig from './config/database.config';
|
||||
import jwtConfig from './config/jwt.config';
|
||||
import { configValidationSchema } from './config/validation.schema';
|
||||
import { AuthModule } from './routes/auth/auth.module';
|
||||
import { UserModule } from './routes/user/user.module';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { AllExceptionsFilter } from './common/filters/all_exceptions.filters';
|
||||
import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
|
||||
import { TransformInterceptor } from './common/interceptors/transform.interceptor';
|
||||
import { RolesGuard } from './common/guards/roles.guard';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@ -21,9 +27,30 @@ import { AuthModule } from './routes/auth/auth.module';
|
||||
isGlobal: true,
|
||||
validationSchema: configValidationSchema,
|
||||
}),
|
||||
TypeOrmModule.forRootAsync({
|
||||
imports: [ConfigModule],
|
||||
inject: [ConfigService],
|
||||
useFactory: (config: ConfigService) => ({
|
||||
type: 'postgres',
|
||||
host: config.get('database.host'),
|
||||
port: config.get<number>('database.port'),
|
||||
username: config.get('database.username'),
|
||||
password: config.get('database.password'),
|
||||
database: config.get('database.name'),
|
||||
entities: [__dirname + '/**/*.entity{.ts,.js}'],
|
||||
synchronize: false,
|
||||
migrations: [__dirname + '/migrations/**/*{.ts,.js}'],
|
||||
logging: true,
|
||||
}),
|
||||
}),
|
||||
AuthModule,
|
||||
UserModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
providers: [AppService,
|
||||
{ provide: APP_FILTER, useClass: AllExceptionsFilter },
|
||||
{ provide: APP_INTERCEPTOR, useClass: TransformInterceptor },
|
||||
{ provide: APP_GUARD, useClass: RolesGuard }
|
||||
],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
33
src/common/base.controller.ts
Normal file
33
src/common/base.controller.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { Body, Delete, Get, Param, Patch, Post } from "@nestjs/common";
|
||||
import { BaseService } from "./base.service";
|
||||
import type { DeepPartial, ObjectLiteral } from "typeorm";
|
||||
import type { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity.js";
|
||||
|
||||
export class BaseController<T extends ObjectLiteral> {
|
||||
constructor(protected readonly service: BaseService<T>) { }
|
||||
|
||||
@Get()
|
||||
getAll(relations: string[] = []) {
|
||||
return this.service.findAll(relations);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
getOne(@Param('id') id: string) {
|
||||
return this.service.findOne(id);
|
||||
}
|
||||
|
||||
@Post()
|
||||
create(@Body() data: DeepPartial<T>) {
|
||||
return this.service.create(data);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
update(@Param('id') id: string, @Body() data: QueryDeepPartialEntity<T>) {
|
||||
return this.service.update(id, data);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
delete(@Param('id') id: string) {
|
||||
return this.service.delete(id);
|
||||
}
|
||||
}
|
||||
28
src/common/base.service.ts
Normal file
28
src/common/base.service.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { DeepPartial, ObjectLiteral, Repository } from "typeorm";
|
||||
import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity.js";
|
||||
|
||||
export class BaseService<T extends ObjectLiteral> {
|
||||
constructor(protected readonly repo: Repository<T>) { }
|
||||
|
||||
findAll(relations: string[] = []) {
|
||||
return this.repo.find({ relations });
|
||||
}
|
||||
|
||||
findOne(id: string, relations: string[] = []) {
|
||||
return this.repo.findOne({ where: { id } as any, relations });
|
||||
}
|
||||
|
||||
create(data: DeepPartial<T>) {
|
||||
const entity = this.repo.create(data);
|
||||
return this.repo.save(entity);
|
||||
}
|
||||
|
||||
async update(id: string, data: QueryDeepPartialEntity<T>) {
|
||||
await this.repo.update(id, data);
|
||||
return this.findOne(id);
|
||||
}
|
||||
|
||||
delete(id: string) {
|
||||
return this.repo.delete(id);
|
||||
}
|
||||
}
|
||||
3
src/common/decorators/roles.decorator.ts
Normal file
3
src/common/decorators/roles.decorator.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { SetMetadata } from "@nestjs/common";
|
||||
|
||||
export const Roles = (...roles: string[]) => SetMetadata("roles", roles);
|
||||
7
src/common/decorators/user.decorator.ts
Normal file
7
src/common/decorators/user.decorator.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { createParamDecorator, ExecutionContext } from "@nestjs/common";
|
||||
|
||||
export const User = createParamDecorator((data: string | undefined, ctx: ExecutionContext) => {
|
||||
const request = ctx.switchToHttp().getRequest();
|
||||
const user = request.user;
|
||||
return data ? user?.[data] : user;
|
||||
});
|
||||
11
src/common/dto/date_range_query.dto.ts
Normal file
11
src/common/dto/date_range_query.dto.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { IsDateString, IsOptional } from "class-validator";
|
||||
|
||||
export class DateRangeQueryDto {
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
start?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
end?: string;
|
||||
}
|
||||
6
src/common/dto/id_param.dto.ts
Normal file
6
src/common/dto/id_param.dto.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { IsUUID } from "class-validator";
|
||||
|
||||
export class IdParamDto {
|
||||
@IsUUID()
|
||||
id: string;
|
||||
}
|
||||
11
src/common/dto/pagination.query.ts
Normal file
11
src/common/dto/pagination.query.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { IsOptional, IsPositive } from "class-validator";
|
||||
|
||||
export class PaginationQueryDto {
|
||||
@IsOptional()
|
||||
@IsPositive()
|
||||
offset?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsPositive()
|
||||
limit?: number;
|
||||
}
|
||||
8
src/common/dto/search_query.dto.ts
Normal file
8
src/common/dto/search_query.dto.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { IsOptional, IsString, MinLength } from "class-validator";
|
||||
|
||||
export class SearchQueryDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MinLength(2)
|
||||
q?: string;
|
||||
}
|
||||
27
src/common/filters/all_exceptions.filters.ts
Normal file
27
src/common/filters/all_exceptions.filters.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus } from "@nestjs/common";
|
||||
|
||||
@Catch()
|
||||
export class AllExceptionsFilter implements ExceptionFilter {
|
||||
catch(exception: unknown, host: ArgumentsHost) {
|
||||
const ctx = host.switchToHttp();
|
||||
const response = ctx.getResponse();
|
||||
const request = ctx.getRequest();
|
||||
const status =
|
||||
exception instanceof HttpException
|
||||
? exception.getStatus()
|
||||
: HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
|
||||
const message =
|
||||
exception instanceof HttpException
|
||||
? exception.getResponse()
|
||||
: { message: 'Internal server error' };
|
||||
|
||||
response.status(status).json({
|
||||
success: false,
|
||||
statusCode: status,
|
||||
timestamp: new Date().toISOString(),
|
||||
path: request.url,
|
||||
message,
|
||||
});
|
||||
}
|
||||
}
|
||||
21
src/common/guards/roles.guard.ts
Normal file
21
src/common/guards/roles.guard.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { CanActivate, ExecutionContext, Injectable } from "@nestjs/common";
|
||||
import { Reflector } from "@nestjs/core";
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
@Injectable()
|
||||
export class RolesGuard implements CanActivate {
|
||||
constructor(private readonly reflector: Reflector) {}
|
||||
canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
|
||||
const requiredRoles = this.reflector.get<string[]>('roles', context.getHandler());
|
||||
if (!requiredRoles || requiredRoles.length === 0) {
|
||||
return true; // Si aucun role est requis -> accès autorise
|
||||
}
|
||||
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const user = request.user;
|
||||
if (!user || !user.role) {
|
||||
return false; // Si l'utilisateur est pas authentifie ou a pas de role -> accès refusé
|
||||
}
|
||||
return requiredRoles.includes(user.role);
|
||||
}
|
||||
}
|
||||
15
src/common/interceptors/transform.interceptor.ts
Normal file
15
src/common/interceptors/transform.interceptor.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from "@nestjs/common";
|
||||
import { map, Observable, timestamp } from "rxjs";
|
||||
|
||||
@Injectable()
|
||||
export class TransformInterceptor implements NestInterceptor {
|
||||
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||
return next.handle().pipe(
|
||||
map((data) => ({
|
||||
success: true,
|
||||
timestamp: new Date().toISOString(),
|
||||
data
|
||||
})),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,41 +1,42 @@
|
||||
import { Column, Entity, JoinColumn, OneToOne, PrimaryColumn } from "typeorm";
|
||||
import { Users } from "./user.entity";
|
||||
import {
|
||||
Entity, PrimaryColumn, Column, OneToOne, JoinColumn
|
||||
} from 'typeorm';
|
||||
import { Users } from './users.entity';
|
||||
|
||||
@Entity('assistantes_maternelles')
|
||||
export class AssistanteMaternelle {
|
||||
// Declarer les proprietes ici
|
||||
@PrimaryColumn('uuid')
|
||||
user_id: string;
|
||||
// PK = FK vers utilisateurs.id
|
||||
@PrimaryColumn('uuid', { name: 'id_utilisateur' })
|
||||
user_id: string;
|
||||
|
||||
@OneToOne(() => Users, user => user.assistanteMaternelle, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'user_id' })
|
||||
user: Users;
|
||||
@OneToOne(() => Users, user => user.assistanteMaternelle, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'id_utilisateur', referencedColumnName: 'id' })
|
||||
user: Users;
|
||||
|
||||
@Column({type: 'varchar'})
|
||||
approval_number: string;
|
||||
|
||||
@Column({type: 'date'})
|
||||
birthdate: Date;
|
||||
@Column({ name: 'numero_agrement', length: 50, nullable: true })
|
||||
approval_number?: string;
|
||||
|
||||
@Column({type: 'varchar'})
|
||||
birthplace_city: string;
|
||||
@Column({ name: 'date_naissance', type: 'date', nullable: true })
|
||||
birthdate?: Date;
|
||||
|
||||
@Column({type: 'varchar'})
|
||||
birthplace_country: string;
|
||||
@Column({ name: 'ville_naissance', length: 100, nullable: true })
|
||||
birthplace_city?: string;
|
||||
|
||||
@Column({type: 'text'})
|
||||
nir_encrypted: string;
|
||||
@Column({ name: 'pays_naissance', length: 2, nullable: true })
|
||||
birthplace_country?: string;
|
||||
|
||||
@Column({type: 'int'})
|
||||
max_children: number;
|
||||
@Column({ name: 'nir_chiffre', length: 15, nullable: true })
|
||||
nir?: string;
|
||||
|
||||
@Column({type: 'text'})
|
||||
bio: string;
|
||||
@Column({ name: 'nb_max_enfants', type: 'int', nullable: true })
|
||||
max_children?: number;
|
||||
|
||||
@Column({type: 'boolean', default: true})
|
||||
is_available: boolean;
|
||||
@Column({ name: 'biographie', type: 'text', nullable: true })
|
||||
biography?: string;
|
||||
|
||||
@Column({type: 'varchar'})
|
||||
city: string;
|
||||
@Column({ name: 'disponible', type: 'boolean', default: true })
|
||||
available: boolean;
|
||||
|
||||
}
|
||||
@Column({ name: 'ville_residence', length: 100, nullable: true })
|
||||
city?: string;
|
||||
}
|
||||
|
||||
42
src/entities/avenants_contrats.entity.ts
Normal file
42
src/entities/avenants_contrats.entity.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
|
||||
import { Contrat } from "./contrats.entity";
|
||||
import { Users } from "./users.entity";
|
||||
|
||||
export enum StatutAvenantType {
|
||||
PROPOSE = 'propose',
|
||||
ACCEPTE = 'accepte',
|
||||
REFUSE = 'refuse',
|
||||
}
|
||||
|
||||
@Entity('avenants_contrats')
|
||||
export class AvenantContrat {
|
||||
// Define your columns and relationships here
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@ManyToOne(() => Contrat, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'id_contrat' })
|
||||
contrat: Contrat;
|
||||
|
||||
@Column({ type: 'jsonb', nullable: true, name: 'modifications' })
|
||||
modifications?: any;
|
||||
|
||||
@ManyToOne(() => Users, { nullable: true })
|
||||
@JoinColumn({ name: 'initie_par', referencedColumnName: 'id' })
|
||||
initiator?: Users;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: StatutAvenantType,
|
||||
enumName: 'statut_avenant_type',
|
||||
default: StatutAvenantType.PROPOSE,
|
||||
name: 'statut'
|
||||
})
|
||||
statut: StatutAvenantType;
|
||||
|
||||
@CreateDateColumn({ name: 'cree_le', type: 'timestamptz' })
|
||||
createdAt: Date;
|
||||
|
||||
@UpdateDateColumn({ name: 'modifie_le', type: 'timestamptz' })
|
||||
updatedAt: Date;
|
||||
}
|
||||
@ -1,60 +1,74 @@
|
||||
import { Column, CreateDateColumn, Entity, JoinTable, ManyToMany, ManyToOne, OneToMany, PrimaryColumn, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
|
||||
import { Parents } from "./parents.entity";
|
||||
import { ParentsChildren } from "./parents_children.entity";
|
||||
import { Dossier } from "./dossiers.entity";
|
||||
import {
|
||||
Entity, PrimaryGeneratedColumn, Column,
|
||||
OneToMany, ManyToMany, CreateDateColumn, JoinTable
|
||||
} from 'typeorm';
|
||||
import { Parents } from './parents.entity';
|
||||
import { ParentsChildren } from './parents_children.entity';
|
||||
import { Dossier } from './dossiers.entity';
|
||||
|
||||
export enum ChildStatus {
|
||||
A_NAITRE = 'A_NAÎTRE',
|
||||
ACTIF = 'ACTIF',
|
||||
SCOLARISE = 'SCOLARISE'
|
||||
export enum StatutEnfantType {
|
||||
A_NAITRE = 'a_naitre',
|
||||
ACTIF = 'actif',
|
||||
SCOLARISE = 'scolarise',
|
||||
}
|
||||
|
||||
@Entity('children')
|
||||
export enum GenreType {
|
||||
H = 'H',
|
||||
F = 'F',
|
||||
AUTRE = 'Autre',
|
||||
}
|
||||
|
||||
@Entity('enfants')
|
||||
export class Children {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: StatutEnfantType,
|
||||
enumName: 'statut_enfant_type',
|
||||
name: 'statut'
|
||||
})
|
||||
status: StatutEnfantType;
|
||||
|
||||
@Column({ nullable: true })
|
||||
first_name: string;
|
||||
@Column({ name: 'prenom', length: 100 })
|
||||
first_name: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
last_name: string;
|
||||
@Column({ name: 'nom', length: 100 })
|
||||
last_name: string;
|
||||
|
||||
@Column({ type: 'date', nullable: true })
|
||||
birthdate: Date;
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: GenreType,
|
||||
enumName: 'genre_type',
|
||||
nullable: true,
|
||||
name: 'genre'
|
||||
})
|
||||
gender?: GenreType;
|
||||
|
||||
@Column({ type: 'date', nullable: true })
|
||||
due_date: Date;
|
||||
@Column({ type: 'date', nullable: true, name: 'date_naissance' })
|
||||
birthdate?: Date;
|
||||
|
||||
@Column({ nullable: true })
|
||||
photo_url: string;
|
||||
@Column({ type: 'date', nullable: true, name: 'date_prevue_naissance' })
|
||||
due_date?: Date;
|
||||
|
||||
@Column({ nullable: true })
|
||||
consent_photo: boolean;
|
||||
@Column({ nullable: true, name: 'photo_url' })
|
||||
photo_url?: string;
|
||||
|
||||
@Column({ type: 'timestamp', nullable: true })
|
||||
consent_photo_at: Date;
|
||||
@Column({ default: false, name: 'consentement_photo' })
|
||||
consent_photo: boolean;
|
||||
|
||||
@Column({nullable: true })
|
||||
is_multiple: boolean
|
||||
@Column({ type: 'timestamptz', nullable: true, name: 'date_consentement_photo' })
|
||||
consent_photo_at?: Date;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: ChildStatus,
|
||||
default: ChildStatus.A_NAITRE,
|
||||
})
|
||||
status: ChildStatus;
|
||||
@Column({ default: false, name: 'est_multiple' })
|
||||
is_multiple: boolean;
|
||||
|
||||
@CreateDateColumn()
|
||||
created_at: Date;
|
||||
// Lien via table de jointure enfants_parents
|
||||
@OneToMany(() => ParentsChildren, pc => pc.child)
|
||||
parentLinks: ParentsChildren[];
|
||||
|
||||
@UpdateDateColumn()
|
||||
updated_at: Date;
|
||||
|
||||
@OneToMany(() => ParentsChildren, pc => pc.child, { onDelete: 'CASCADE' })
|
||||
parentChildren: ParentsChildren[];
|
||||
|
||||
@OneToMany(() => Dossier, d => d.child)
|
||||
dossiers: Dossier[];
|
||||
// Relation avec Dossier
|
||||
@OneToMany(() => Dossier, d => d.child)
|
||||
dossiers: Dossier[];
|
||||
}
|
||||
|
||||
53
src/entities/contrats.entity.ts
Normal file
53
src/entities/contrats.entity.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import { Column, CreateDateColumn, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
|
||||
import { Dossier } from "./dossiers.entity";
|
||||
|
||||
export enum StatutContratType {
|
||||
BROUILLON = 'brouillon',
|
||||
EN_ATTENTE_SIGNATURE = 'en_attente_signature',
|
||||
VALIDE = 'valide',
|
||||
RESILIE = 'resilie',
|
||||
}
|
||||
|
||||
@Entity('contrats')
|
||||
export class Contrat {
|
||||
// Define your columns and relationships here
|
||||
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@OneToOne(() => Dossier, {onDelete: 'CASCADE'} )
|
||||
@JoinColumn({ name: 'id_dossier'})
|
||||
dossier: Dossier;
|
||||
|
||||
@Column({type: 'jsonb', nullable: true, name: 'planning'})
|
||||
planning?: any;
|
||||
|
||||
@Column({type: 'numeric', precision: 6, scale: 2, nullable: true, name: 'tarif_horaire'})
|
||||
hourly_rate?: string;
|
||||
|
||||
@Column({type: 'numeric', precision: 6, scale: 2, nullable: true, name: 'indemnites_repas'})
|
||||
meal_indemnity?: string;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: StatutContratType,
|
||||
default: StatutContratType.BROUILLON,
|
||||
name: 'statut'
|
||||
})
|
||||
statut: StatutContratType;
|
||||
|
||||
@Column({type: 'boolean', default: false, name: 'signe_parent'})
|
||||
signed_by_parent: boolean;
|
||||
|
||||
@Column({type: 'boolean', default: false, name: 'signe_am'})
|
||||
signed_by_am: boolean;
|
||||
|
||||
@Column({type: 'timestamptz', nullable: true, name: 'finalise_le'})
|
||||
finalized_at?: Date;
|
||||
|
||||
@CreateDateColumn({ name: 'cree_le', type: 'timestamptz' })
|
||||
created_at: Date;
|
||||
|
||||
@UpdateDateColumn({ name: 'modifie_le', type: 'timestamptz' })
|
||||
updated_at: Date;
|
||||
}
|
||||
@ -1,41 +1,60 @@
|
||||
import { Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
|
||||
import { Parents } from "./parents.entity";
|
||||
import { Children } from "./children.entity";
|
||||
import {
|
||||
Entity, PrimaryGeneratedColumn, Column,
|
||||
ManyToOne, OneToMany, CreateDateColumn, UpdateDateColumn, JoinColumn
|
||||
} from 'typeorm';
|
||||
import { Parents } from './parents.entity';
|
||||
import { Children } from './children.entity';
|
||||
import { Message } from './messages.entity';
|
||||
|
||||
export enum StatutDossierType {
|
||||
ENVOYE = 'envoye',
|
||||
ACCEPTE = 'accepte',
|
||||
REFUSE = 'refuse',
|
||||
}
|
||||
|
||||
@Entity('dossiers')
|
||||
export class Dossier {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@ManyToOne(() => Parents, p => p.dossiers, {onDelete: 'CASCADE'} )
|
||||
@JoinColumn({ name: 'parent_id', referencedColumnName: 'user_id' })
|
||||
parent: Parents;
|
||||
@ManyToOne(() => Parents, p => p.dossiers, { onDelete: 'CASCADE', nullable: false })
|
||||
@JoinColumn({ name: 'id_parent', referencedColumnName: 'user_id' })
|
||||
parent: Parents;
|
||||
|
||||
@ManyToOne(() => Children, c => c.dossiers, {onDelete:'CASCADE'})
|
||||
@JoinColumn({ name: 'child_id', referencedColumnName: 'id' })
|
||||
child: Children;
|
||||
@ManyToOne(() => Children, c => c.dossiers, { onDelete: 'CASCADE', nullable: false })
|
||||
@JoinColumn({ name: 'id_enfant', referencedColumnName: 'id' })
|
||||
child: Children;
|
||||
|
||||
@Column({type: 'text', nullable: true})
|
||||
presentation: string;
|
||||
@Column({ type: 'text', nullable: true, name: 'presentation' })
|
||||
presentation?: string;
|
||||
|
||||
@Column({type: 'varchar', nullable: true})
|
||||
type_contract: string;
|
||||
@Column({ type: 'varchar', length: 50, nullable: true, name: 'type_contrat' })
|
||||
type_contrat?: string;
|
||||
|
||||
@Column({type:'boolean', nullable: true})
|
||||
meals: boolean;
|
||||
@Column({ type: 'boolean', default: false, name: 'repas' })
|
||||
meals: boolean;
|
||||
|
||||
@Column({type: 'decimal', nullable: true})
|
||||
budget: number;
|
||||
@Column({ type: 'numeric', precision: 10, scale: 2, nullable: true, name: 'budget' })
|
||||
budget?: number;
|
||||
|
||||
@Column({type: 'json', nullable: true})
|
||||
desired_schedule: any;
|
||||
@Column({ type: 'jsonb', nullable: true, name: 'planning_souhaite' })
|
||||
desired_schedule?: any;
|
||||
|
||||
@Column({type: 'varchar', default: 'sent'})
|
||||
status: string;
|
||||
|
||||
@CreateDateColumn()
|
||||
created_at: Date;
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: StatutDossierType,
|
||||
enumName: 'statut_dossier_type',
|
||||
default: StatutDossierType.ENVOYE,
|
||||
name: 'statut'
|
||||
})
|
||||
status: StatutDossierType;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updated_at: Date;
|
||||
}
|
||||
@CreateDateColumn({ name: 'cree_le', type: 'timestamptz' })
|
||||
created_at: Date;
|
||||
|
||||
@UpdateDateColumn({ name: 'modifie_le', type: 'timestamptz' })
|
||||
updated_at: Date;
|
||||
|
||||
@OneToMany(() => Message, m => m.dossier)
|
||||
messages: Message[];
|
||||
}
|
||||
79
src/entities/evenements.entity.ts
Normal file
79
src/entities/evenements.entity.ts
Normal file
@ -0,0 +1,79 @@
|
||||
import { Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
|
||||
import { Children } from "./children.entity";
|
||||
import { Users } from "./users.entity";
|
||||
import { Parents } from "./parents.entity";
|
||||
|
||||
export enum TypeEvenementType {
|
||||
ABSENCE_ENFANT = 'absence_enfant',
|
||||
CONGE_AM = 'conge_am',
|
||||
CONGE_PARENT = 'conge_parent',
|
||||
ARRET_MALADIE_AM = 'arret_maladie_am',
|
||||
EVENEMENT_RPE = 'evenement_rpe',
|
||||
}
|
||||
|
||||
export enum StatutEvenementType {
|
||||
PROPOSE = 'propose',
|
||||
VALIDE = 'valide',
|
||||
REFUSE = 'refuse',
|
||||
}
|
||||
|
||||
@Entity('evenements')
|
||||
export class Evenement {
|
||||
// Define your columns and relationships here
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: TypeEvenementType,
|
||||
enumName: 'type_evenement_type',
|
||||
name: 'type'
|
||||
})
|
||||
type: TypeEvenementType;
|
||||
|
||||
@ManyToOne(() => Children, { onDelete: 'CASCADE', nullable: true })
|
||||
@JoinColumn({ name: 'id_enfant', referencedColumnName: 'id' })
|
||||
child?: Children;
|
||||
|
||||
@ManyToOne(() => Users, { nullable: true })
|
||||
@JoinColumn({ name: 'id_am', referencedColumnName: 'id' })
|
||||
assistanteMaternelle?: Users;
|
||||
|
||||
@ManyToOne(() => Parents, { nullable: true })
|
||||
@JoinColumn({ name: 'id_parent', referencedColumnName: 'user_id' })
|
||||
parent?: Parents;
|
||||
|
||||
@ManyToOne(() => Users, { nullable: true })
|
||||
@JoinColumn({ name: 'cree_par', referencedColumnName: 'id' })
|
||||
created_by?: Users;
|
||||
|
||||
@Column({ type: 'timestamptz', nullable: true, name: 'date_debut' })
|
||||
start_date?: Date;
|
||||
|
||||
@Column({ type: 'timestamptz', nullable: true, name: 'date_fin' })
|
||||
end_date?: Date;
|
||||
|
||||
@Column({ type: 'text', nullable: true, name: 'commentaires' })
|
||||
comments?: string;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: StatutEvenementType,
|
||||
enumName: 'statut_evenement_type',
|
||||
name: 'statut',
|
||||
default: StatutEvenementType.PROPOSE
|
||||
})
|
||||
status: StatutEvenementType;
|
||||
|
||||
@Column({type: 'timestamptz', nullable: true, name: 'delai_grace'})
|
||||
grace_deadline?: Date;
|
||||
|
||||
@Column({type: 'boolean', default: false, name: 'urgent'})
|
||||
urgent: boolean;
|
||||
|
||||
@CreateDateColumn({ name: 'cree_le', type: 'timestamptz' })
|
||||
created_at: Date;
|
||||
|
||||
@UpdateDateColumn({ name: 'modifie_le', type: 'timestamptz' })
|
||||
updated_at: Date;
|
||||
}
|
||||
29
src/entities/messages.entity.ts
Normal file
29
src/entities/messages.entity.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import {
|
||||
Entity, PrimaryGeneratedColumn, Column,
|
||||
ManyToOne, JoinColumn, CreateDateColumn
|
||||
} from 'typeorm';
|
||||
import { Dossier } from './dossiers.entity';
|
||||
import { Users } from './users.entity';
|
||||
|
||||
@Entity('messages')
|
||||
export class Message {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@ManyToOne(() => Dossier, d => d.messages, { onDelete: 'CASCADE', nullable: false })
|
||||
@JoinColumn({ name: 'id_dossier' })
|
||||
dossier: Dossier;
|
||||
|
||||
@ManyToOne(() => Users, u => u.messages, { onDelete: 'CASCADE', nullable: false })
|
||||
@JoinColumn({ name: 'id_expediteur' })
|
||||
sender: Users;
|
||||
|
||||
@Column({ type: 'text', name: 'contenu' })
|
||||
content: string;
|
||||
|
||||
@Column({ type: 'boolean', name: 're_redige_par_ia', default: false })
|
||||
reRedigeParIA: boolean;
|
||||
|
||||
@CreateDateColumn({ name: 'cree_le', type: 'timestamptz' })
|
||||
created_at: Date;
|
||||
}
|
||||
23
src/entities/notifications.entity.ts
Normal file
23
src/entities/notifications.entity.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
|
||||
import { Users } from "./users.entity";
|
||||
|
||||
@Entity('notifications')
|
||||
export class Notification {
|
||||
// Define your columns and relationships here
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@ManyToOne(() => Users, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'id_utilisateur', referencedColumnName: 'id' })
|
||||
user: Users;
|
||||
|
||||
@Column({ type: 'text', name: 'contenu' })
|
||||
content: string;
|
||||
|
||||
@Column({type: 'boolean', name: 'lu', default: false})
|
||||
read: boolean;
|
||||
|
||||
@CreateDateColumn({ name: 'cree_le', type: 'timestamptz' })
|
||||
created_at: Date;
|
||||
|
||||
}
|
||||
@ -1,28 +1,31 @@
|
||||
import { Column, Entity, JoinColumn, OneToMany, OneToOne, PrimaryColumn } from "typeorm";
|
||||
import { Users } from "./user.entity";
|
||||
import { ParentsChildren } from "./parents_children.entity";
|
||||
import { Dossier } from "./dossiers.entity";
|
||||
import {
|
||||
Entity, PrimaryColumn, OneToOne, JoinColumn,
|
||||
ManyToOne, OneToMany
|
||||
} from 'typeorm';
|
||||
import { Users } from './users.entity';
|
||||
import { ParentsChildren } from './parents_children.entity';
|
||||
import { Dossier } from './dossiers.entity';
|
||||
|
||||
@Entity('parents')
|
||||
export class Parents {
|
||||
// PK = FK vers utilisateurs.id
|
||||
@PrimaryColumn('uuid', { name: 'id_utilisateur' })
|
||||
user_id: string;
|
||||
|
||||
@PrimaryColumn('uuid')
|
||||
user_id: string;
|
||||
@OneToOne(() => Users, user => user.parent, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'id_utilisateur', referencedColumnName: 'id' })
|
||||
user: Users;
|
||||
|
||||
@OneToOne(() => Users, user => user.parent, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'user_id' })
|
||||
user: Users;
|
||||
// Co-parent (nullable) → FK vers utilisateurs.id
|
||||
@ManyToOne(() => Users, { nullable: true })
|
||||
@JoinColumn({ name: 'id_co_parent', referencedColumnName: 'id' })
|
||||
co_parent?: Users;
|
||||
|
||||
@Column({ type: 'uuid', nullable: true })
|
||||
co_parent_id?: string;
|
||||
// Lien vers enfants via la table enfants_parents
|
||||
@OneToMany(() => ParentsChildren, pc => pc.parent)
|
||||
parentChildren: ParentsChildren[];
|
||||
|
||||
@OneToOne(() => Users)
|
||||
@JoinColumn({ name: 'co_parent_id' })
|
||||
co_parent?: Users;
|
||||
|
||||
@OneToMany(() => ParentsChildren, pc => pc.parent, { onDelete: 'CASCADE' })
|
||||
parentChildren: ParentsChildren[];
|
||||
|
||||
@OneToMany(() => Dossier, d => d.parent)
|
||||
dossiers: Dossier[];
|
||||
// Lien vers les dossiers de ce parent
|
||||
@OneToMany(() => Dossier, d => d.parent)
|
||||
dossiers: Dossier[];
|
||||
}
|
||||
|
||||
@ -1,21 +1,22 @@
|
||||
import { Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm";
|
||||
import { Parents } from "./parents.entity";
|
||||
import { Children } from "./children.entity";
|
||||
import {
|
||||
Entity, ManyToOne, JoinColumn, PrimaryColumn
|
||||
} from 'typeorm';
|
||||
import { Parents } from './parents.entity';
|
||||
import { Children } from './children.entity';
|
||||
|
||||
@Entity('parents_children')
|
||||
@Entity('enfants_parents')
|
||||
export class ParentsChildren {
|
||||
|
||||
@PrimaryColumn('uuid')
|
||||
parent_id: string;
|
||||
@PrimaryColumn('uuid', { name: 'id_parent' })
|
||||
id_parent: string;
|
||||
|
||||
@PrimaryColumn('uuid')
|
||||
child_id: string;
|
||||
@PrimaryColumn('uuid', { name: 'id_enfant' })
|
||||
id_enfant: string;
|
||||
|
||||
@ManyToOne(() => Parents, (parent) => parent.parentChildren, {onDelete: 'CASCADE'})
|
||||
@JoinColumn({ name: 'parent_id', referencedColumnName: 'user_id' })
|
||||
parent: Parents;
|
||||
@ManyToOne(() => Parents, p => p.parentChildren, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'id_parent', referencedColumnName: 'user_id' })
|
||||
parent: Parents;
|
||||
|
||||
@ManyToOne(() => Children, (child) => child.parentChildren, {onDelete: 'CASCADE'})
|
||||
@JoinColumn({ name: 'child_id', referencedColumnName: 'id' })
|
||||
child: Children;
|
||||
}
|
||||
@ManyToOne(() => Children, c => c.parentLinks, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'id_enfant', referencedColumnName: 'id' })
|
||||
child: Children;
|
||||
}
|
||||
|
||||
19
src/entities/signalements_bugs.entity.ts
Normal file
19
src/entities/signalements_bugs.entity.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
|
||||
import { Users } from "./users.entity";
|
||||
|
||||
@Entity('signalements_bugs')
|
||||
export class SignalementBug {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@ManyToOne(() => Users, {nullable: true})
|
||||
@JoinColumn({ name: 'id_utilisateur', referencedColumnName: 'id' })
|
||||
user?: Users;
|
||||
|
||||
@Column({ type: 'text', name: 'description'})
|
||||
description: string;
|
||||
|
||||
@CreateDateColumn({ name: 'cree_le', type: 'timestamptz' })
|
||||
created_at: Date;
|
||||
|
||||
}
|
||||
21
src/entities/uploads.entity.ts
Normal file
21
src/entities/uploads.entity.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
|
||||
import { Users } from "./users.entity";
|
||||
|
||||
@Entity('uploads')
|
||||
export class Upload {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@ManyToOne(() => Users, { onDelete: 'SET NULL', nullable: true })
|
||||
@JoinColumn({ name: 'id_utilisateur', referencedColumnName: 'id' })
|
||||
user?: Users;
|
||||
|
||||
@Column({ type: 'text', name: 'fichier_url' })
|
||||
file_url: string;
|
||||
|
||||
@Column({type: 'varchar', length: 50, nullable: true, name: 'type'})
|
||||
type?: string;
|
||||
|
||||
@CreateDateColumn({ name: 'cree_le', type: 'timestamptz' })
|
||||
created_at: Date;
|
||||
}
|
||||
@ -1,73 +0,0 @@
|
||||
import {
|
||||
Entity, PrimaryGeneratedColumn, Column,
|
||||
CreateDateColumn, UpdateDateColumn,
|
||||
OneToOne
|
||||
} from 'typeorm';
|
||||
import { AssistanteMaternelle } from './assistantes_maternelles.entity';
|
||||
import { Parents } from './parents.entity';
|
||||
export enum UserRole {
|
||||
PARENT = 'PARENT',
|
||||
ASSISTANT = 'ASSISTANT',
|
||||
GESTIONNAIRE = 'GESTIONNAIRE',
|
||||
ADMIN = 'ADMIN',
|
||||
}
|
||||
|
||||
@Entity('users')
|
||||
export class Users {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ unique: true })
|
||||
email: string;
|
||||
|
||||
@Column()
|
||||
password_hash: string;
|
||||
|
||||
@Column()
|
||||
first_name: string;
|
||||
|
||||
@Column()
|
||||
last_name: string;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: UserRole,
|
||||
default: UserRole.PARENT,
|
||||
})
|
||||
role: UserRole;
|
||||
|
||||
@Column({ default: 'pending' })
|
||||
status: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
phone: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
address: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
photo_url: string;
|
||||
|
||||
@Column({ default: false })
|
||||
consent_photo: boolean;
|
||||
|
||||
@Column({ type: 'timestamp', nullable: true })
|
||||
consent_photo_at: Date;
|
||||
|
||||
@Column({ default: false })
|
||||
must_change_password: boolean;
|
||||
|
||||
@CreateDateColumn()
|
||||
created_at: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updated_at: Date;
|
||||
|
||||
@OneToOne(() => AssistanteMaternelle, a => a.user)
|
||||
assistanteMaternelle?: AssistanteMaternelle;
|
||||
|
||||
@OneToOne(() => Parents, p => p.user)
|
||||
parent?: Parents;
|
||||
|
||||
}
|
||||
|
||||
109
src/entities/users.entity.ts
Normal file
109
src/entities/users.entity.ts
Normal file
@ -0,0 +1,109 @@
|
||||
import {
|
||||
Entity, PrimaryGeneratedColumn, Column,
|
||||
CreateDateColumn, UpdateDateColumn,
|
||||
OneToOne, OneToMany
|
||||
} from 'typeorm';
|
||||
import { AssistanteMaternelle } from './assistantes_maternelles.entity';
|
||||
import { Parents } from './parents.entity';
|
||||
import { Message } from './messages.entity';
|
||||
|
||||
// Enums alignés avec la BDD PostgreSQL
|
||||
export enum RoleType {
|
||||
PARENT = 'parent',
|
||||
GESTIONNAIRE = 'gestionnaire',
|
||||
SUPER_ADMIN = 'super_admin',
|
||||
ASSISTANTE_MATERNELLE = 'assistante_maternelle',
|
||||
}
|
||||
|
||||
//Enum pour definir le genre
|
||||
export enum GenreType {
|
||||
H = 'H',
|
||||
F = 'F',
|
||||
AUTRE = 'Autre',
|
||||
}
|
||||
|
||||
//Enum pour definir le statut utilisateur
|
||||
export enum StatutUtilisateurType {
|
||||
EN_ATTENTE = 'en_attente',
|
||||
ACTIF = 'actif',
|
||||
SUSPENDU = 'suspendu',
|
||||
}
|
||||
|
||||
//Declaration de l'entite utilisateur
|
||||
@Entity('utilisateurs')
|
||||
export class Users {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ unique: true, name: 'courriel' })
|
||||
email: string;
|
||||
|
||||
@Column({ name: 'mot_de_passe_hash' })
|
||||
password_hash: string;
|
||||
|
||||
@Column({ name: 'prenom', nullable: true })
|
||||
first_name: string;
|
||||
|
||||
@Column({ name: 'nom', nullable: true })
|
||||
last_name: string;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: GenreType,
|
||||
enumName: 'genre_type', // correspond à l'enum de la db psql
|
||||
nullable: true,
|
||||
name: 'genre'
|
||||
})
|
||||
gender?: GenreType;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: RoleType,
|
||||
enumName: 'role_type', // correspond à l'enum de la db psql
|
||||
name: 'role'
|
||||
})
|
||||
role: RoleType;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: StatutUtilisateurType,
|
||||
enumName: 'statut_utilisateur_type', // correspond à l'enum de la db psql
|
||||
default: StatutUtilisateurType.EN_ATTENTE,
|
||||
name: 'statut'
|
||||
})
|
||||
status: StatutUtilisateurType;
|
||||
|
||||
@Column({ nullable: true, name: 'telephone' })
|
||||
phone?: string;
|
||||
|
||||
@Column({ nullable: true, name: 'adresse' })
|
||||
address?: string;
|
||||
|
||||
@Column({ nullable: true, name: 'photo_url' })
|
||||
photo_url?: string;
|
||||
|
||||
@Column({ default: false, name: 'consentement_photo' })
|
||||
consent_photo: boolean;
|
||||
|
||||
@Column({ type: 'timestamptz', nullable: true, name: 'date_consentement_photo' })
|
||||
consent_photo_at?: Date;
|
||||
|
||||
@Column({ default: false, name: 'changement_mdp_obligatoire' })
|
||||
must_change_password: boolean;
|
||||
|
||||
@CreateDateColumn({ name: 'cree_le', type: 'timestamptz' })
|
||||
created_at: Date;
|
||||
|
||||
@UpdateDateColumn({ name: 'modifie_le', type: 'timestamptz' })
|
||||
updated_at: Date;
|
||||
|
||||
// Relations
|
||||
@OneToOne(() => AssistanteMaternelle, a => a.user)
|
||||
assistanteMaternelle?: AssistanteMaternelle;
|
||||
|
||||
@OneToOne(() => Parents, p => p.user)
|
||||
parent?: Parents;
|
||||
|
||||
@OneToMany(() => Message, m => m.sender)
|
||||
messages?: Message[];
|
||||
}
|
||||
36
src/entities/validations.entity.ts
Normal file
36
src/entities/validations.entity.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
|
||||
import { Users } from "./users.entity";
|
||||
|
||||
export enum StatutValidationType {
|
||||
EN_ATTENTE = 'en_attente',
|
||||
VALIDE = 'valide',
|
||||
REFUSE = 'refuse',
|
||||
}
|
||||
|
||||
@Entity('validations')
|
||||
export class Validation {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@ManyToOne(() => Users, { nullable: true })
|
||||
@JoinColumn({ name: 'id_utilisateur', referencedColumnName: 'id' })
|
||||
user?: Users;
|
||||
|
||||
@Column({ type: 'varchar', length: 50, name: 'type' })
|
||||
type: string;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: StatutValidationType,
|
||||
enumName: 'statut_validation_type',
|
||||
name: 'statut',
|
||||
default: StatutValidationType.EN_ATTENTE
|
||||
})
|
||||
status: StatutValidationType;
|
||||
|
||||
@CreateDateColumn({ name: 'cree_le', type: 'timestamptz' })
|
||||
created_at: Date;
|
||||
|
||||
@UpdateDateColumn({ name: 'modifie_le', type: 'timestamptz' })
|
||||
updated_at: Date;
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
import { Body, Controller, Get, Post } from '@nestjs/common';
|
||||
import { AuthService } from './auth.service';
|
||||
import { LoginDto } from './dto/login.dto';
|
||||
import { RegisterDto } from './dto/register.dto';
|
||||
|
||||
@Controller('auth')
|
||||
export class AuthController {
|
||||
constructor(private readonly authService: AuthService) {}
|
||||
|
||||
|
||||
//Route pour se connecter
|
||||
@Post('login')
|
||||
login(@Body() loginDto: LoginDto) {
|
||||
return this.authService.login(loginDto);
|
||||
}
|
||||
|
||||
//Route pour s'inscrire
|
||||
@Post('register')
|
||||
register(@Body() registerDto: RegisterDto) {
|
||||
return this.authService.register(registerDto);
|
||||
}
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AuthController } from './auth.controller';
|
||||
import { AuthService } from './auth.service';
|
||||
|
||||
@Module({
|
||||
controllers: [AuthController],
|
||||
providers: [AuthService]
|
||||
})
|
||||
export class AuthModule {}
|
||||
@ -1,21 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { LoginDto } from './dto/login.dto';
|
||||
import { RegisterDto } from './dto/register.dto';
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
|
||||
register(registerDto: RegisterDto) {
|
||||
return {
|
||||
message: `User registered successfully ${registerDto}`,
|
||||
user: registerDto,
|
||||
};
|
||||
}
|
||||
|
||||
login(loginDto: LoginDto) {
|
||||
return {
|
||||
message: `Login successful ${loginDto.email}`,
|
||||
user: loginDto,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
import { IsEmail, MinLength } from 'class-validator';
|
||||
|
||||
export class LoginDto {
|
||||
@IsEmail()
|
||||
email: string;
|
||||
|
||||
@MinLength(8)
|
||||
password: string;
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
import { IsEmail, IsNotEmpty, MaxLength, MinLength } from "class-validator";
|
||||
|
||||
export class RegisterDto {
|
||||
|
||||
@IsEmail()
|
||||
email: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
username: string;
|
||||
|
||||
@MinLength(8)
|
||||
password: string;
|
||||
}
|
||||
|
||||
|
||||
10
src/routes/parents/dto/create_parents.dto.ts
Normal file
10
src/routes/parents/dto/create_parents.dto.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { IsUUID, IsOptional } from 'class-validator';
|
||||
|
||||
export class CreateParentDto {
|
||||
@IsUUID()
|
||||
id_utilisateur: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsUUID()
|
||||
co_parent_id?: string;
|
||||
}
|
||||
@ -1,15 +1,15 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { AuthController } from './auth.controller';
|
||||
import { ParentsController } from './parents.controller';
|
||||
|
||||
describe('AuthController', () => {
|
||||
let controller: AuthController;
|
||||
describe('ParentsController', () => {
|
||||
let controller: ParentsController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [AuthController],
|
||||
controllers: [ParentsController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<AuthController>(AuthController);
|
||||
controller = module.get<ParentsController>(ParentsController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
19
src/routes/parents/parents.controller.ts
Normal file
19
src/routes/parents/parents.controller.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import { BaseController } from 'src/common/base.controller';
|
||||
import { Parents } from 'src/entities/parents.entity';
|
||||
import { ParentsService } from './parents.service';
|
||||
import { Roles } from 'src/common/decorators/roles.decorator';
|
||||
import { RoleType } from 'src/entities/users.entity';
|
||||
|
||||
@Controller('parents')
|
||||
export class ParentsController extends BaseController<Parents> {
|
||||
constructor(private readonly parentsService: ParentsService) {
|
||||
super(parentsService);
|
||||
}
|
||||
|
||||
@Roles(RoleType.SUPER_ADMIN, RoleType.GESTIONNAIRE)
|
||||
@Get()
|
||||
override getAll(): Promise<Parents[]> {
|
||||
return this.parentsService.findAll();
|
||||
}
|
||||
}
|
||||
13
src/routes/parents/parents.module.ts
Normal file
13
src/routes/parents/parents.module.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { Parents } from 'src/entities/parents.entity';
|
||||
import { ParentsController } from './parents.controller';
|
||||
import { ParentsService } from './parents.service';
|
||||
import { Users } from 'src/entities/users.entity';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Parents, Users])],
|
||||
controllers: [ParentsController],
|
||||
providers: [ParentsService],
|
||||
})
|
||||
export class ParentsModule {}
|
||||
@ -1,15 +1,15 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { AuthService } from './auth.service';
|
||||
import { ParentsService } from './parents.service';
|
||||
|
||||
describe('AuthService', () => {
|
||||
let service: AuthService;
|
||||
describe('ParentsService', () => {
|
||||
let service: ParentsService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [AuthService],
|
||||
providers: [ParentsService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<AuthService>(AuthService);
|
||||
service = module.get<ParentsService>(ParentsService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
57
src/routes/parents/parents.service.ts
Normal file
57
src/routes/parents/parents.service.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { BadRequestException, ConflictException, Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { BaseService } from 'src/common/base.service';
|
||||
import { Parents } from 'src/entities/parents.entity';
|
||||
import { RoleType, Users } from 'src/entities/users.entity';
|
||||
import { DeepPartial, Repository } from 'typeorm';
|
||||
import { CreateParentDto } from './dto/create_parents.dto';
|
||||
|
||||
@Injectable()
|
||||
export class ParentsService extends BaseService<Parents> {
|
||||
constructor(
|
||||
@InjectRepository(Parents) private readonly parentsRepository: Repository<Parents>,
|
||||
@InjectRepository(Users) private readonly usersRepository: Repository<Users>,
|
||||
) {
|
||||
super(parentsRepository);
|
||||
}
|
||||
|
||||
override async create(data: DeepPartial<Parents>): Promise<Parents> {
|
||||
const dto = data as CreateParentDto;
|
||||
|
||||
const user = await this.usersRepository.findOneBy({ id: dto.id_utilisateur });
|
||||
if (!user) throw new NotFoundException('Utilisateur introuvable');
|
||||
if (user.role !== RoleType.PARENT) throw new BadRequestException('Acces reserve aux parents');
|
||||
|
||||
const exist = await this.parentsRepository.findOneBy({ user_id: dto.id_utilisateur });
|
||||
if (exist) throw new ConflictException('Ce parent existe deja');
|
||||
|
||||
let co_parent: Users | null = null;
|
||||
if (dto.co_parent_id) {
|
||||
co_parent = await this.usersRepository.findOneBy({ id: dto.co_parent_id });
|
||||
if (!co_parent) throw new NotFoundException('Co-parent introuvable');
|
||||
if (co_parent.role !== RoleType.PARENT) throw new BadRequestException('Acces reserve aux parents');
|
||||
}
|
||||
const entity = this.parentsRepository.create({
|
||||
user_id: dto.id_utilisateur,
|
||||
user,
|
||||
co_parent: co_parent ?? undefined,
|
||||
}) as DeepPartial<Parents>;
|
||||
return this.parentsRepository.save(entity)
|
||||
}
|
||||
|
||||
override async findAll(): Promise<Parents[]> {
|
||||
return this.parentsRepository.find({
|
||||
relations: ['user', 'co_parent',
|
||||
'parentChildren', 'dossiers'],
|
||||
});
|
||||
}
|
||||
|
||||
override async findOne(user_id: string): Promise<Parents> {
|
||||
const parent = await this.parentsRepository.findOne({
|
||||
where: { user_id },
|
||||
relations: ['user', 'co_parent', 'parentChildren', 'dossiers'],
|
||||
});
|
||||
if (!parent) throw new NotFoundException('Parent introuvable');
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user