Implement backend API and database services in Docker setup
- Added a new `api` service for the NestJS backend, including health checks and dependencies on PostgreSQL, Redis, and MinIO. - Introduced PostgreSQL and Redis services with health checks and configurations for data persistence. - Added MinIO for S3-compatible object storage and a one-shot service to initialize required buckets. - Updated the Nginx configuration to proxy requests to the new backend API and MinIO storage. - Enhanced the Dockerfile to support the new API environment variables and configurations. - Updated the `package.json` and `package-lock.json` to include new dependencies for QR code generation and other utilities. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
31
backend/src/invites/entities/invite.entity.ts
Normal file
31
backend/src/invites/entities/invite.entity.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { Content } from 'src/contents/entities/content.entity';
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
PrimaryColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
@Entity('invites')
|
||||
export class Invite {
|
||||
@PrimaryColumn()
|
||||
id: string;
|
||||
|
||||
@PrimaryColumn()
|
||||
contentId: string;
|
||||
|
||||
@Column()
|
||||
email: string;
|
||||
|
||||
@Column({ default: 0 })
|
||||
share: number;
|
||||
|
||||
@CreateDateColumn({ type: 'timestamptz' })
|
||||
createdAt: Date;
|
||||
|
||||
@ManyToOne(() => Content, (content) => content.invites)
|
||||
@JoinColumn({ name: 'content_id' })
|
||||
content: Content;
|
||||
}
|
||||
11
backend/src/invites/invites.module.ts
Normal file
11
backend/src/invites/invites.module.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { Invite } from './entities/invite.entity';
|
||||
import { InvitesService } from './invites.service';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Invite])],
|
||||
providers: [InvitesService],
|
||||
exports: [InvitesService],
|
||||
})
|
||||
export class InvitesModule {}
|
||||
64
backend/src/invites/invites.service.ts
Normal file
64
backend/src/invites/invites.service.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Invite } from './entities/invite.entity';
|
||||
import { Repository } from 'typeorm';
|
||||
import { MailService } from 'src/mail/mail.service';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
|
||||
@Injectable()
|
||||
export class InvitesService {
|
||||
constructor(
|
||||
@InjectRepository(Invite)
|
||||
private invitesRepository: Repository<Invite>,
|
||||
@Inject(MailService)
|
||||
private mailService: MailService,
|
||||
) {}
|
||||
|
||||
async getUserInvites(email: string) {
|
||||
return this.invitesRepository.find({
|
||||
where: { email },
|
||||
});
|
||||
}
|
||||
|
||||
async getFilmInvites(contentId: string, email?: string) {
|
||||
return this.invitesRepository.find({
|
||||
where: { contentId, email },
|
||||
});
|
||||
}
|
||||
|
||||
async sendInvite(email: string, contentId: string) {
|
||||
const invite = await this.invitesRepository.save({
|
||||
id: randomUUID(),
|
||||
email,
|
||||
contentId,
|
||||
});
|
||||
return invite;
|
||||
}
|
||||
|
||||
async sendInvites(
|
||||
invites: Array<{ email: string; share: number }>,
|
||||
contentId: string,
|
||||
) {
|
||||
const parsedInvites = invites.map((invite) => ({
|
||||
id: randomUUID(),
|
||||
email: invite.email,
|
||||
contentId,
|
||||
share: invite.share,
|
||||
}));
|
||||
await this.invitesRepository.save(parsedInvites);
|
||||
return true;
|
||||
}
|
||||
|
||||
async removeInvite(email: string, contentId?: string) {
|
||||
await this.invitesRepository.delete({
|
||||
email,
|
||||
contentId,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
async updateInvite(email: string, contentId: string, share: number) {
|
||||
await this.invitesRepository.update({ email, contentId }, { share });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user