Implement sessions management

main
MiguelMLorente 2025-12-01 21:15:39 +01:00
parent 9b883068cd
commit 69bc958991
6 changed files with 147 additions and 5 deletions

View File

@ -7,6 +7,9 @@ import { StripeService } from './service/stripe.service';
import { TypeOrmModule } from '@nestjs/typeorm'; import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './dto/user'; import { User } from './dto/user';
import { Purchase } from './dto/purchase'; import { Purchase } from './dto/purchase';
import { SessionService } from './service/session.service';
import { SessionController } from './controller/session.controller';
import { Session } from './dto/session';
@Module({ @Module({
imports: [ imports: [
@ -18,12 +21,12 @@ import { Purchase } from './dto/purchase';
username: process.env.DB_USER || 'postgres', username: process.env.DB_USER || 'postgres',
password: process.env.DB_PASSWORD || 'postgres', password: process.env.DB_PASSWORD || 'postgres',
database: process.env.DB_NAME || 'appdb', database: process.env.DB_NAME || 'appdb',
entities: [User, Purchase], entities: [User, Purchase, Session],
synchronize: true, synchronize: true,
}), }),
TypeOrmModule.forFeature([User, Purchase]), TypeOrmModule.forFeature([User, Purchase, Session]),
], ],
controllers: [AccessController, BuyController], controllers: [AccessController, BuyController, SessionController],
providers: [UserService, PurchaseService, StripeService], providers: [UserService, PurchaseService, StripeService, SessionService],
}) })
export class AppModule {} export class AppModule {}

View File

@ -0,0 +1,50 @@
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
import { SessionService } from 'src/service/session.service';
import { UserService } from 'src/service/user.service';
@Controller('/session')
export class SessionController {
constructor(
private readonly userService: UserService,
private readonly sessionService: SessionService,
) {}
@Post('/create')
public createSession() {
this.sessionService.createSession(
new Date(Date.now() + 24 * 3600 * 1000),
10,
);
}
@Get()
public async getAllSessions(@Query('userId') userId: string) {
const sessions = await this.sessionService.getAllSessions();
const user = await this.userService.getUserById(userId);
return sessions.map((session) => ({
id: session.id,
size: session.size,
userCount: session.users.length,
includesRequester: session.users.includes(user),
date: session.date,
}));
}
@Post('/join')
public async joinSession(
@Body('userId') userId: string,
@Body('sessionId') sessionId: string,
) {
const user = await this.userService.getUserById(userId);
this.sessionService.joinSession(user, sessionId);
}
@Post('/leave')
public async leaveSession(
@Body('userId') userId: string,
@Body('sessionId') sessionId: string,
) {
const user = await this.userService.getUserById(userId);
this.sessionService.leaveSession(user, sessionId);
}
}

17
src/dto/session.ts Normal file
View File

@ -0,0 +1,17 @@
import { Column, Entity, ManyToMany, PrimaryGeneratedColumn } from 'typeorm';
import { User } from './user';
@Entity('SESSIONS')
export class Session {
@PrimaryGeneratedColumn('uuid')
id: string;
@ManyToMany(() => User, (user) => user.joinedSessions)
users: User[];
@Column()
size: number;
@Column()
date: Date;
}

View File

@ -1,5 +1,13 @@
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm'; import {
Column,
Entity,
JoinTable,
ManyToMany,
OneToMany,
PrimaryGeneratedColumn,
} from 'typeorm';
import { Purchase } from './purchase'; import { Purchase } from './purchase';
import { Session } from './session';
@Entity('USERS') @Entity('USERS')
export class User { export class User {
@ -14,4 +22,8 @@ export class User {
@OneToMany(() => Purchase, (purchase) => purchase.purchasedBy) @OneToMany(() => Purchase, (purchase) => purchase.purchasedBy)
purchases: Purchase[]; purchases: Purchase[];
@ManyToMany(() => Session, (session) => session.users)
@JoinTable()
joinedSessions: Session[];
} }

View File

@ -0,0 +1,59 @@
import { Injectable, Logger, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Session } from 'src/dto/session';
import { User } from 'src/dto/user';
import { Repository } from 'typeorm';
@Injectable()
export class SessionService {
private readonly logger = new Logger(SessionService.name);
constructor(
@InjectRepository(Session) private sessionRepo: Repository<Session>,
) {}
public createSession(date: Date, size: number) {
const session = this.sessionRepo.create({
users: [],
date,
size,
});
this.sessionRepo.save(session);
}
public getAllSessions() {
return this.sessionRepo.find({ relations: { users: true } });
}
public async joinSession(user: User, sessionId: string) {
const session = await this.sessionRepo.findOneOrFail({
where: {
id: sessionId,
},
});
if (!session) {
throw new NotFoundException();
}
if (
session.users.find((u) => u === user) ||
session.users.length >= session.size
) {
return;
}
session.users.push(user);
await this.sessionRepo.save(session);
}
public async leaveSession(user: User, sessionId: string) {
const session = await this.sessionRepo.findOneOrFail({
where: {
id: sessionId,
},
});
if (!session) {
throw new NotFoundException();
}
session.users = session.users.filter((u) => u !== user);
await this.sessionRepo.save(session);
}
}

View File

@ -40,6 +40,7 @@ export class UserService {
name, name,
password, password,
purchases: [], purchases: [],
joinedSessions: [],
}); });
return this.userRepo.save(user); return this.userRepo.save(user);
} }