feat: initial model

This commit is contained in:
2025-05-30 10:33:26 +02:00
parent 6825726668
commit d11ee1df53
13 changed files with 835 additions and 75 deletions
+24
View File
@@ -0,0 +1,24 @@
services:
postgres:
image: postgres
ports:
- 5432:5432
volumes:
- pg_data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=test
pgadmin:
image: dpage/pgadmin4
ports:
- 8080:80
environment:
- PGADMIN_DEFAULT_EMAIL=postgres@postgres.com
- PGADMIN_DEFAULT_PASSWORD=postgres
- PGADMIN_DISABLE_POSTFIX=true
volumes:
- pgadmin_data:/var/lib/pgadmin
volumes:
pg_data:
pgadmin_data:
+589 -72
View File
File diff suppressed because it is too large Load Diff
+6 -1
View File
@@ -21,10 +21,15 @@
},
"dependencies": {
"@nestjs/common": "^11.0.1",
"@nestjs/config": "^4.0.2",
"@nestjs/core": "^11.0.1",
"@nestjs/platform-express": "^11.0.1",
"@nestjs/swagger": "^11.2.0",
"@nestjs/typeorm": "^11.0.0",
"pg": "^8.16.0",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1"
"rxjs": "^7.8.1",
"typeorm": "^0.3.24"
},
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",
+37 -1
View File
@@ -1,9 +1,45 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { PollsModule } from './polls/polls.module';
import { Answer } from './polls/entities/answer.entity';
import { Choice } from './polls/entities/choice.entity';
import { InviteCode } from './polls/entities/inviteCode.entity';
import { Poll } from './polls/entities/poll.entity';
import { Question } from './polls/entities/question.entity';
import { QuestionOption } from './polls/entities/questionOptions';
import { User } from './polls/entities/user.entity';
void ConfigModule.forRoot({
envFilePath: '.env',
isGlobal: true,
});
const configService = new ConfigService();
@Module({
imports: [],
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: configService.get('PG_HOST'),
password: configService.get('PG_PASSWORD'),
username: configService.get('PG_USER'),
database: configService.get('PG_DATABASE'),
synchronize: configService.get('DEV_MODE') == 'true',
entities: [
Answer,
Choice,
InviteCode,
Poll,
Question,
QuestionOption,
User,
],
}),
PollsModule,
],
controllers: [AppController],
providers: [AppService],
})
+12 -1
View File
@@ -1,8 +1,19 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('Vote au jugement majoritaire')
.setDescription('API description')
.setVersion('1.0')
.build();
const documentFactory = () => SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, documentFactory);
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
void bootstrap();
+20
View File
@@ -0,0 +1,20 @@
import { Entity, PrimaryGeneratedColumn, ManyToOne, Unique } from 'typeorm';
import { Question } from './question.entity';
import { User } from './user.entity';
import { QuestionOption } from './questionOptions';
@Entity()
@Unique(['question', 'choice', 'user'])
export class Answer {
@PrimaryGeneratedColumn({})
id: number;
@ManyToOne(() => QuestionOption)
choice: QuestionOption;
@ManyToOne(() => Question, (question: Question) => question.answers)
question: Question;
@ManyToOne(() => User)
user: User;
}
+14
View File
@@ -0,0 +1,14 @@
import { Entity, Column, PrimaryGeneratedColumn, Unique } from 'typeorm';
@Entity()
@Unique(['value'])
export class Choice {
@PrimaryGeneratedColumn({})
id: number;
@Column()
value: string;
@Column()
order: string;
}
+29
View File
@@ -0,0 +1,29 @@
import {
Entity,
Column,
PrimaryGeneratedColumn,
Unique,
Generated,
ManyToOne,
} from 'typeorm';
import { Poll } from './poll.entity';
@Entity()
@Unique(['value'])
export class InviteCode {
@PrimaryGeneratedColumn({})
id: number;
@Column()
description: string;
@Column({ nullable: true, default: null })
max_usages: number;
@Column()
@Generated('uuid')
value: string;
@ManyToOne(() => Poll, (poll) => poll.codes)
poll: Poll;
}
+36
View File
@@ -0,0 +1,36 @@
import {
Entity,
Column,
PrimaryGeneratedColumn,
OneToMany,
Generated,
Unique,
} from 'typeorm';
import { Question } from './question.entity';
import { InviteCode } from './inviteCode.entity';
@Entity()
@Unique(['editCode'])
export class Poll {
@PrimaryGeneratedColumn({})
id: number;
@Column()
name: string;
@Column()
description: string;
@Column()
@Generated('uuid')
editCode: string;
@Column({ default: false })
published: boolean;
@OneToMany(() => InviteCode, (code) => code.poll, { cascade: true })
codes: InviteCode;
@OneToMany(() => Question, (question) => question.poll, { cascade: true })
questions: Question[];
}
+34
View File
@@ -0,0 +1,34 @@
import {
Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
OneToMany,
} from 'typeorm';
import { Poll } from './poll.entity';
import { Answer } from './answer.entity';
import { QuestionOption } from './questionOptions';
@Entity()
export class Question {
@PrimaryGeneratedColumn({})
id: number;
@Column()
value: string;
@Column()
mandatory: boolean;
@Column()
order: number;
@ManyToOne(() => Poll, (poll: Poll) => poll.questions)
poll: Poll;
@OneToMany(() => QuestionOption, (questionOption) => questionOption.question)
options: QuestionOption[];
@OneToMany(() => Answer, (answer) => answer.question)
answers: Answer[];
}
+16
View File
@@ -0,0 +1,16 @@
import { Entity, ManyToOne, PrimaryGeneratedColumn, Unique } from 'typeorm';
import { Choice } from './choice.entity';
import { Question } from './question.entity';
@Entity()
@Unique(['question', 'choice'])
export class QuestionOption {
@PrimaryGeneratedColumn()
id: number;
@ManyToOne(() => Choice)
choice: Choice;
@ManyToOne(() => Question, (question) => question.options)
question: Question;
}
+10
View File
@@ -0,0 +1,10 @@
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn({})
id: number;
@Column()
username: string;
}
+8
View File
@@ -0,0 +1,8 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Poll } from './entities/poll.entity';
@Module({
imports: [TypeOrmModule.forFeature([Poll])],
})
export class PollsModule {}