Skip to content

Commit

Permalink
feat: gh actions, category supploes and fix shelter service methods
Browse files Browse the repository at this point in the history
  • Loading branch information
fagundesjg committed May 5, 2024
1 parent 067fa6b commit d95d816
Show file tree
Hide file tree
Showing 19 changed files with 301 additions and 14 deletions.
12 changes: 12 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
TZ=America/Sao_Paulo

DB_HOST=
DB_PORT=
DB_USER=
DB_PASSWORD=
DB_DATABASE_NAME=
DATABASE_URL="postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_DATABASE_NAME}?schema=public&sslmode=require"
SECRET_KEY=

HOST=::0.0.0.0
PORT=4000
36 changes: 36 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Deploy Backend

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build:
runs-on: self-hosted

steps:
- uses: actions/checkout@v4

- name: Create .env file
run: |
touch .env
echo TZ=${{ secrets.TZ }} >> .env
echo DB_HOST=${{ secrets.DB_HOST }} >> .env
echo DB_PORT=${{ secrets.DB_PORT }} >> .env
echo DB_USER=${{ secrets.DB_USER }} >> .env
echo DB_PASSWORD=${{ secrets.DB_PASSWORD }} >> .env
echo DB_DATABASE_NAME=${{ secrets.DB_DATABASE_NAME }} >> .env
echo DATABASE_URL=postgresql://${{ secrets.DB_USER }}:${{ secrets.DB_PASSWORD }}@${{ secrets.DB_HOST }}:${{ secrets.DB_PORT }}/${{ secrets.DB_DATABASE_NAME }}?schema=public >> .env
echo SECRET_KEY=${{ secrets.SECRET_KEY }} >> .env
echo HOST=${{ secrets.HOST }} >> .env
echo PORT=${{ secrets.PORT }} >> .env
echo SERVER_USER_PASSWORD=${{ secrets.SERVER_USER_PASSWORD }} >> .env
cat .env
- name: Remove old docker image
run: echo ${{ secrets.SERVER_USER_PASSWORD }} | sudo -S docker compose down --rmi all

- name: Create new docker image
run: echo ${{ secrets.SERVER_USER_PASSWORD }} | sudo -S docker compose up -d --force-recreate
8 changes: 8 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM node:18.18 as node

WORKDIR /usr/app

COPY package.json package-lock.json ./

RUN npm install
COPY . .
14 changes: 14 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
services:
sos-rs-api:
container_name: sos-rs-api
build:
context: .
dockerfile: Dockerfile
restart: always
tty: true
ports:
- '4000:4000'
command: >
sh -c "npx prisma generate &&
npx prisma migrate deploy &&
npm run build && npm run start:prod"
12 changes: 12 additions & 0 deletions prisma/migrations/20240505203201_/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
Warnings:
- A unique constraint covering the columns `[name]` on the table `shelters` will be added. If there are existing duplicate values, this will fail.
- Added the required column `name` to the `shelters` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "shelters" ADD COLUMN "name" TEXT NOT NULL;

-- CreateIndex
CREATE UNIQUE INDEX "shelters_name_key" ON "shelters"("name");
3 changes: 2 additions & 1 deletion prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ enum SupplyStatus {

model SupplyCategory {
id String @id @default(uuid())
name String
name String @unique
createdAt String @map("created_at") @db.VarChar(32)
updatedAt String? @map("updated_at") @db.VarChar(32)
Expand All @@ -77,6 +77,7 @@ model Supply {

model Shelter {
id String @id @default(uuid())
name String @unique
pix String @unique
address String
petFriendly Boolean? @map("pet_friendly")
Expand Down
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ServerResponseInterceptor } from './interceptors';
import { LoggingMiddleware } from './middlewares/logging.middleware';
import { UsersModule } from './users/users.module';
import { SessionsModule } from './sessions/sessions.module';
import { SupplyCategoriesModule } from './supply-categories/supply-categories.module';

@Module({
imports: [
Expand All @@ -16,6 +17,7 @@ import { SessionsModule } from './sessions/sessions.module';
SessionsModule,
ShelterModule,
SupplyModule,
SupplyCategoriesModule,
],
controllers: [],
providers: [
Expand Down
10 changes: 7 additions & 3 deletions src/shelter/shelter.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import {
Param,
Post,
Put,
UseGuards,
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';

import { ShelterService } from './shelter.service';
import { ServerResponse } from '../utils';
import { SearchQuery } from '../decorators';
import { SeachQueryProps } from '@/decorators/search-query/types';
import { StaffGuard } from '@/guards/staff.guard';

@ApiTags('Abrigos')
@Controller('shelters')
Expand All @@ -25,7 +27,7 @@ export class ShelterController {
@Get('')
async index(@SearchQuery() searchQueryParams: SeachQueryProps) {
try {
const data = await this.shelterService.getAll(searchQueryParams);
const data = await this.shelterService.index(searchQueryParams);
return new ServerResponse(200, 'Successfully get shelters', data);
} catch (err: any) {
this.logger.error(`Failed to get shelters: ${err}`);
Expand All @@ -34,12 +36,13 @@ export class ShelterController {
}

@Post('')
@UseGuards(StaffGuard)
async store(@Body() body) {
try {
const data = await this.shelterService.store(body);
return new ServerResponse(200, 'Successfully created shelter', data);
} catch (err: any) {
this.logger.error(`Failed to get all users: ${err}`);
this.logger.error(`Failed to create shelter: ${err}`);
throw new HttpException(err?.code ?? err?.name ?? `${err}`, 400);
}
}
Expand All @@ -56,12 +59,13 @@ export class ShelterController {
}

@Put(':id/admin')
@UseGuards(StaffGuard)
async fullUpdate(@Param('id') id: string, @Body() body) {
try {
const data = await this.shelterService.fullUpdate(id, body);
return new ServerResponse(200, 'Successfully updated shelter', data);
} catch (err: any) {
this.logger.error(`Failed update shelter: ${err}`);
this.logger.error(`Failed to update shelter: ${err}`);
throw new HttpException(err?.code ?? err?.name ?? `${err}`, 400);
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/shelter/shelter.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class ShelterService {
},
data: {
...payload,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
},
});
}
Expand All @@ -46,18 +46,19 @@ export class ShelterService {
},
data: {
...payload,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
},
});
}

async getAll(props: SeachQueryProps) {
async index(props: SeachQueryProps) {
const { handleSearch } = props;
return await handleSearch<Prisma.ShelterSelect<DefaultArgs>>(
this.prismaService.shelter,
{
select: {
id: true,
name: true,
pix: true,
address: true,
capacity: true,
Expand Down
1 change: 1 addition & 0 deletions src/shelter/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import z from 'zod';

const ShelterSchema = z.object({
id: z.string(),
name: z.string(),
pix: z.string(),
address: z.string(),
petFriendly: z.boolean().nullable().optional(),
Expand Down
18 changes: 18 additions & 0 deletions src/supply-categories/supply-categories.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { SupplyCategoriesController } from './supply-categories.controller';

describe('SupplyCategoriesController', () => {
let controller: SupplyCategoriesController;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [SupplyCategoriesController],
}).compile();

controller = module.get<SupplyCategoriesController>(SupplyCategoriesController);
});

it('should be defined', () => {
expect(controller).toBeDefined();
});
});
73 changes: 73 additions & 0 deletions src/supply-categories/supply-categories.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {
Body,
Controller,
Get,
HttpException,
Logger,
Param,
Post,
Put,
UseGuards,
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';

import { SupplyCategoriesService } from './supply-categories.service';
import { ServerResponse } from '../utils';
import { StaffGuard } from '@/guards/staff.guard';

@ApiTags('Categoria de Suprimentos')
@Controller('supply-categories')
export class SupplyCategoriesController {
private logger = new Logger(SupplyCategoriesController.name);

constructor(
private readonly supplyCategoryServices: SupplyCategoriesService,
) {}

@Get('')
async index() {
try {
const data = await this.supplyCategoryServices.index();
return new ServerResponse(
200,
'Successfully get supply categories',
data,
);
} catch (err: any) {
this.logger.error(`Failed to get supply categories: ${err}`);
throw new HttpException(err?.code ?? err?.name ?? `${err}`, 400);
}
}

@Post('')
@UseGuards(StaffGuard)
async store(@Body() body) {
try {
const data = await this.supplyCategoryServices.store(body);
return new ServerResponse(
200,
'Successfully created supply category',
data,
);
} catch (err: any) {
this.logger.error(`Failed to create supply category: ${err}`);
throw new HttpException(err?.code ?? err?.name ?? `${err}`, 400);
}
}

@Put(':id')
@UseGuards(StaffGuard)
async update(@Param('id') id: string, @Body() body) {
try {
const data = await this.supplyCategoryServices.update(id, body);
return new ServerResponse(
200,
'Successfully updated supply category',
data,
);
} catch (err: any) {
this.logger.error(`Failed to update supply category: ${err}`);
throw new HttpException(err?.code ?? err?.name ?? `${err}`, 400);
}
}
}
12 changes: 12 additions & 0 deletions src/supply-categories/supply-categories.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';

import { SupplyCategoriesService } from './supply-categories.service';
import { SupplyCategoriesController } from './supply-categories.controller';
import { PrismaModule } from '../prisma/prisma.module';

@Module({
imports: [PrismaModule],
providers: [SupplyCategoriesService],
controllers: [SupplyCategoriesController],
})
export class SupplyCategoriesModule {}
18 changes: 18 additions & 0 deletions src/supply-categories/supply-categories.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { SupplyCategoriesService } from './supply-categories.service';

describe('SupplyCategoriesService', () => {
let service: SupplyCategoriesService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [SupplyCategoriesService],
}).compile();

service = module.get<SupplyCategoriesService>(SupplyCategoriesService);
});

it('should be defined', () => {
expect(service).toBeDefined();
});
});
40 changes: 40 additions & 0 deletions src/supply-categories/supply-categories.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Injectable } from '@nestjs/common';

import { PrismaService } from '../prisma/prisma.service';
import { z } from 'zod';
import {
CreateSupplyCategorySchema,
UpdateSupplyCategorySchema,
} from './types';

@Injectable()
export class SupplyCategoriesService {
constructor(private readonly prismaService: PrismaService) {}

async store(body: z.infer<typeof CreateSupplyCategorySchema>) {
const payload = CreateSupplyCategorySchema.parse(body);
await this.prismaService.supplyCategory.create({
data: {
...payload,
createdAt: new Date().toISOString(),
},
});
}

async update(id: string, body: z.infer<typeof UpdateSupplyCategorySchema>) {
const payload = UpdateSupplyCategorySchema.parse(body);
await this.prismaService.supplyCategory.update({
where: {
id,
},
data: {
...payload,
updatedAt: new Date().toISOString(),
},
});
}

async index() {
return await this.prismaService.supplyCategory.findMany({});
}
}
Loading

0 comments on commit d95d816

Please sign in to comment.