diff --git a/backend/package-lock.json b/backend/package-lock.json index 65c4816f9a9886eb650d0f4d3232ddd02c72db47..02e86f6a23038d6a09c4d8a3b01b6ec3e21e19ea 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -14,6 +14,7 @@ "@nestjs/jwt": "^10.2.0", "@nestjs/mapped-types": "*", "@nestjs/platform-express": "^10.0.0", + "@nestjs/serve-static": "^4.0.2", "@nestjs/swagger": "^7.3.0", "@nestjs/typeorm": "^10.0.2", "bcrypt": "^5.1.1", @@ -2040,6 +2041,37 @@ "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", "dev": true }, + "node_modules/@nestjs/serve-static": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@nestjs/serve-static/-/serve-static-4.0.2.tgz", + "integrity": "sha512-cT0vdWN5ar7jDI2NKbhf4LcwJzU4vS5sVpMkVrHuyLcltbrz6JdGi1TfIMMatP2pNiq5Ie/uUdPSFDVaZX/URQ==", + "dependencies": { + "path-to-regexp": "0.2.5" + }, + "peerDependencies": { + "@fastify/static": "^6.5.0 || ^7.0.0", + "@nestjs/common": "^9.0.0 || ^10.0.0", + "@nestjs/core": "^9.0.0 || ^10.0.0", + "express": "^4.18.1", + "fastify": "^4.7.0" + }, + "peerDependenciesMeta": { + "@fastify/static": { + "optional": true + }, + "express": { + "optional": true + }, + "fastify": { + "optional": true + } + } + }, + "node_modules/@nestjs/serve-static/node_modules/path-to-regexp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.2.5.tgz", + "integrity": "sha512-l6qtdDPIkmAmzEO6egquYDfqQGPMRNGjYtrU13HAXb3YSRrt7HSb1sJY0pKp6o2bAa86tSB6iwaW2JbthPKr7Q==" + }, "node_modules/@nestjs/swagger": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.3.0.tgz", diff --git a/backend/package.json b/backend/package.json index c016a217372b39338080df8c4e28c6511ed9d9bd..0198a4d469d0cb85399f23c9019d923f553e8ad3 100644 --- a/backend/package.json +++ b/backend/package.json @@ -25,6 +25,7 @@ "@nestjs/jwt": "^10.2.0", "@nestjs/mapped-types": "*", "@nestjs/platform-express": "^10.0.0", + "@nestjs/serve-static": "^4.0.2", "@nestjs/swagger": "^7.3.0", "@nestjs/typeorm": "^10.0.2", "bcrypt": "^5.1.1", diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 4ec2c55f53d6b90629af08cb8fc1289cca6717d1..190781ced06c78eb853b133ec5e19a6782eee153 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -9,6 +9,11 @@ import { AuthAdminModule } from './auth/admin/authAdmin.module'; import { UserModule } from './user/user.module'; import { User } from './user/entities/user.entity'; import { AuthUserModule } from './auth/user/authUser.module'; +import { StateModule } from './state/state.module'; +import { DatabaseSeederModule } from './database-seeder/database-seeder.module'; +import { State } from './state/entities/state.entity'; +import { ServeStaticModule } from '@nestjs/serve-static'; +import { join } from 'path'; @Module({ imports: [ TypeOrmModule.forRoot({ @@ -18,15 +23,20 @@ import { AuthUserModule } from './auth/user/authUser.module'; username: DbConstants.DB_USER, password: DbConstants.DB_PASSWORD, database: DbConstants.DB_NAME, - entities: [Admin, User], + entities: [Admin, User, State], synchronize: DbConstants.DB_SYNC, }), AuthAdminModule, AdminModule, UserModule, AuthUserModule, + StateModule, + DatabaseSeederModule, + ServeStaticModule.forRoot({ + rootPath: join(__dirname, '..', 'static'), + }), ], controllers: [AppController], - providers: [AppService], + providers: [AppService, DatabaseSeederModule], }) export class AppModule {} diff --git a/backend/src/auth/user/authUserservice.ts b/backend/src/auth/user/authUserservice.ts index b9cf9d7b98fba1b14c1b5b1438819180ac5845e1..2a0011bf8fa8f5f567015f52509e5d90abdf1f30 100644 --- a/backend/src/auth/user/authUserservice.ts +++ b/backend/src/auth/user/authUserservice.ts @@ -1,4 +1,9 @@ -import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; +import { + BadRequestException, + HttpException, + HttpStatus, + Injectable, +} from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { EncryptionService } from '../encryption/encryption.service'; import { JwtConstants } from 'src/constants/jwt.constants'; @@ -25,6 +30,9 @@ export class AuthUserService { createAdminDto.password, ); createAdminDto.password = hashedPwd; + if (this.userService.userExists(createAdminDto.email)) { + throw new BadRequestException('User already exists'); + } await this.userService.create(createAdminDto); const adminSigninResDto: UserSigninResDto = diff --git a/backend/src/constants/db.constants.ts b/backend/src/constants/db.constants.ts index 42bba4f0cb890cd5f7020f57dbed1ac84066f04b..13f7af267765cb6f336e07175ab7a426ec07a55b 100644 --- a/backend/src/constants/db.constants.ts +++ b/backend/src/constants/db.constants.ts @@ -4,7 +4,7 @@ export class DbConstants { static DB_HOST: string = process.env.DB_HOST || 'localhost'; static DB_PORT: number = process.env.DB_PORT ? parseInt(process.env.DB_PORT) - : 3306 ; + : 3306; static DB_USER: string = process.env.DB_USER || 'root'; static DB_PASSWORD: string = process.env.DB_PASSWORD || 'root'; static DB_NAME: string = process.env.DB_NAME || 'pueblos'; diff --git a/backend/src/constants/server.contants.ts b/backend/src/constants/server.contants.ts index bc188d6687691117c5fdec28582cc3b531236a50..67d19ee0788af98f207582ae99765a1735bd36af 100644 --- a/backend/src/constants/server.contants.ts +++ b/backend/src/constants/server.contants.ts @@ -5,4 +5,5 @@ export class ServerConstants { static PORT: number = process.env.SERVER_PORT ? parseInt(process.env.SERVER_PORT) : 3003; + static HOST: string = `${process.env.SERVER_HOST || 'http://localhost'}:${this.PORT}`; } diff --git a/backend/src/database-seeder/database-seeder.module.ts b/backend/src/database-seeder/database-seeder.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..1b3475feb550dcd2ad0398aa8191374c76d5500e --- /dev/null +++ b/backend/src/database-seeder/database-seeder.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { DatabaseSeederService } from './database-seeder.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { State } from 'src/state/entities/state.entity'; +import { StateService } from 'src/state/state.service'; + +@Module({ + providers: [DatabaseSeederService, StateService], + imports: [TypeOrmModule.forFeature([State])], +}) +export class DatabaseSeederModule {} diff --git a/backend/src/database-seeder/database-seeder.service.ts b/backend/src/database-seeder/database-seeder.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..d76e3660c8ef6ac5910d08bd8302c86597b35e67 --- /dev/null +++ b/backend/src/database-seeder/database-seeder.service.ts @@ -0,0 +1,25 @@ +import { Injectable, OnModuleInit } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { State } from 'src/state/entities/state.entity'; +import { StateService } from 'src/state/state.service'; +import { Repository } from 'typeorm'; +import * as data from './states.json'; + +@Injectable() +export class DatabaseSeederService implements OnModuleInit { + constructor( + @InjectRepository(State) private stateRepo: Repository, + private readonly stateService: StateService, + ) {} + + async insertStates() { + const states = data.states; + for (const state of states) { + await this.stateService.create(state); + } + } + + async onModuleInit() { + await this.insertStates(); + } +} diff --git a/backend/src/database-seeder/states.json b/backend/src/database-seeder/states.json new file mode 100644 index 0000000000000000000000000000000000000000..1652be2d9cd5f3184bc11a7bee37fb3d623b12ab --- /dev/null +++ b/backend/src/database-seeder/states.json @@ -0,0 +1,9 @@ +{ + "states": [ + { + "stateId": 1, + "name": "Zacatecas", + "imageName": "1.jpg" + } + ] +} diff --git a/backend/src/state/dto/create-state.dto.ts b/backend/src/state/dto/create-state.dto.ts new file mode 100644 index 0000000000000000000000000000000000000000..28904f236d6a2a0c9ba461cb7cc6f3c9d0c6ded6 --- /dev/null +++ b/backend/src/state/dto/create-state.dto.ts @@ -0,0 +1,4 @@ +export class CreateStateDto { + name: string; + imageName: string; +} diff --git a/backend/src/state/entities/state.entity.ts b/backend/src/state/entities/state.entity.ts new file mode 100644 index 0000000000000000000000000000000000000000..afc58a072e66a9d90a8722c477113b054feb062c --- /dev/null +++ b/backend/src/state/entities/state.entity.ts @@ -0,0 +1,13 @@ +import { Entity, Column, PrimaryColumn } from 'typeorm'; + +@Entity() +export class State { + @PrimaryColumn() + stateId: number; + + @Column() + name: string; + + @Column() + imageName: string; +} diff --git a/backend/src/state/state.controller.ts b/backend/src/state/state.controller.ts new file mode 100644 index 0000000000000000000000000000000000000000..71114a0903da38721b28093ac629351dbaa83d95 --- /dev/null +++ b/backend/src/state/state.controller.ts @@ -0,0 +1,13 @@ +import { Controller, Get } from '@nestjs/common'; +import { StateService } from './state.service'; + +@Controller('state') +@Controller('town') +export class StateController { + constructor(private readonly stateService: StateService) {} + + @Get() + findAll() { + return this.stateService.findAll(); + } +} diff --git a/backend/src/state/state.module.ts b/backend/src/state/state.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..523b6c39c99a6f7ee5ff643fd453bff60dd886af --- /dev/null +++ b/backend/src/state/state.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { StateService } from './state.service'; +import { State } from './entities/state.entity'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { StateController } from './state.controller'; + +@Module({ + controllers: [StateController], + providers: [StateService], + imports: [TypeOrmModule.forFeature([State])], +}) +export class StateModule {} diff --git a/backend/src/state/state.service.ts b/backend/src/state/state.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..44234781ece74e40e9f563ad13324b1b8e37e1c2 --- /dev/null +++ b/backend/src/state/state.service.ts @@ -0,0 +1,30 @@ +import { Injectable } from '@nestjs/common'; +import { CreateStateDto } from './dto/create-state.dto'; +import { InjectRepository } from '@nestjs/typeorm'; +import { State } from './entities/state.entity'; +import { Repository } from 'typeorm'; +import { ServerConstants } from 'src/constants/server.contants'; + +@Injectable() +export class StateService { + constructor( + @InjectRepository(State) private stateRepository: Repository, + ) {} + + async create(createStateDto: CreateStateDto) { + await this.stateRepository.save(createStateDto); + } + + async findAll() { + const states = await this.stateRepository.find(); + const statesResponse = states.map(({ imageName, name, stateId }) => { + return { + stateId, + name, + imageURL: `${ServerConstants.HOST}/states/${imageName}`, + }; + }); + + return statesResponse; + } +} diff --git a/backend/src/user/dto/create-user.dto.ts b/backend/src/user/dto/create-user.dto.ts index 89a565be2bb815d380df0e69d9f3c6b8c60680eb..b8c225a634cf271c074d45d6558975fa20770cce 100644 --- a/backend/src/user/dto/create-user.dto.ts +++ b/backend/src/user/dto/create-user.dto.ts @@ -10,5 +10,5 @@ export class CreateUserDto { @ApiProperty() password: string; @ApiProperty() - birthdate: Date; + birthDate: Date; } diff --git a/backend/src/user/user.service.ts b/backend/src/user/user.service.ts index 0f17c0029e8658c024bc00a287c5f009732e3537..82ef1863eb46d96bc63b30aa3f308fb35fd101e2 100644 --- a/backend/src/user/user.service.ts +++ b/backend/src/user/user.service.ts @@ -20,4 +20,10 @@ export class UserService { async create(createUserDto: CreateUserDto) { await this.userRepository.insert(createUserDto); } + + async userExists(email: string): Promise { + const user = await this.userRepository.findOneBy({ email }); + if (user) return true; + else return false; + } } diff --git a/backend/static/states/1.jpg b/backend/static/states/1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a20424e9462de9eecc11a18ead64ba6a2d36b13c Binary files /dev/null and b/backend/static/states/1.jpg differ diff --git a/backend/tsconfig.json b/backend/tsconfig.json index 95f5641cf7f33d3e9022c4a60c5f0ff0958d2a4e..2b0c0e1f9f522f00ac2ec61ac20b67093ab4c5f9 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -16,6 +16,7 @@ "noImplicitAny": false, "strictBindCallApply": false, "forceConsistentCasingInFileNames": false, - "noFallthroughCasesInSwitch": false + "noFallthroughCasesInSwitch": false, + "resolveJsonModule": true } }