Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions infra/controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { InternalServerError, MethodNotAllowedError } from "infra/errors";

function onNoMatchHandler(request, response) {
const publicErrorObject = new MethodNotAllowedError();
response.status(publicErrorObject.statusCode).json(publicErrorObject);
}

function onErrorHandler(error, request, response) {
const publicErrorObject = new InternalServerError({
statusCode: error.statusCode,
cause: error,
});

console.error(publicErrorObject);

response.status(publicErrorObject.statusCode).json(publicErrorObject);
}

const controller = {
errorHandlers: {
onNoMatch: onNoMatchHandler,
onError: onErrorHandler,
},
};

export default controller;
9 changes: 6 additions & 3 deletions infra/database.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Client } from "pg";
import { ServiceError } from "./errors.js";

async function query(queryObject) {
let client;
Expand All @@ -7,9 +8,11 @@ async function query(queryObject) {
const result = await client.query(queryObject);
return result;
} catch (error) {
console.log("\n Erro dentro do catch do database.js: ");
console.error(error);
throw error;
const serviceErrorObject = new ServiceError({
message: "Erro na conexção com Banco ou na Query.",
cause: error,
});
throw serviceErrorObject;
} finally {
if (client) {
await client?.end();
Expand Down
58 changes: 58 additions & 0 deletions infra/errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
export class InternalServerError extends Error {
constructor({ cause, statusCode }) {
super("Um error interno não esperando aconteceu.", {
cause,
});
this.name = "InternalServerError";
this.action = "Entre em contato com o suporte";
this.statusCode = statusCode || 500;
}

toJSON() {
return {
name: this.name,
message: this.message,
action: this.action,
statusCode: this.statusCode,
};
}
}

export class ServiceError extends Error {
constructor({ cause, message }) {
super(message || "Serviço indisponivel no momento.", {
cause,
});
this.name = "InternalServerError";
this.action = "Entre em contato com o suporte";
this.statusCode = 503;
}

toJSON() {
return {
name: this.name,
message: this.message,
action: this.action,
statusCode: this.statusCode,
};
}
}

export class MethodNotAllowedError extends Error {
constructor() {
super("Metodo não permitido para este endpoint.");
this.name = "MethodNotAllowedError";
this.action =
"Verifique se o método HTTP enviado é válido para este endpoint.";
this.statusCode = 405;
}

toJSON() {
return {
name: this.name,
message: this.message,
action: this.action,
statusCode: this.statusCode,
};
}
}
19 changes: 0 additions & 19 deletions infra/erros.js

This file was deleted.

29 changes: 29 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"dotenv": "17.4.2",
"dotenv-expand": "13.0.0",
"next": "16.2.6",
"next-connect": "1.0.0",
"node-pg-migrate": "8.0.4",
"pg": "8.20.0",
"react": "19.2.6",
Expand Down
70 changes: 38 additions & 32 deletions pages/api/v1/migrations/index.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,60 @@
import { createRouter } from "next-connect";
import { runner as migrationRunner } from "node-pg-migrate";
import { resolve } from "node:path";
import database from "infra/database";
import controller from "infra/controller";

export default async function migrations(request, response) {
const allowedMethods = ["GET", "POST"];
const router = createRouter();

if (!allowedMethods.includes(request.method)) {
return response.status(405).json({
error: `Method "${request.method}" not allowed`,
});
}
router.get(getHandler);
router.post(postHandler);

export default router.handler(controller.errorHandlers);

const defaultMigrationsOptions = {
dryRun: true,
dir: resolve("infra", "migrations"),
direction: "up",
verbose: true,
migrationsTable: "pgmigrations",
};

async function getHandler(request, response) {
let dbClient;

try {
dbClient = await database.getNewClient();

const defaultMigrationsOptions = {
const pendingMigrations = await migrationRunner({
...defaultMigrationsOptions,
dbClient,
dryRun: true,
dir: resolve("infra", "migrations"),
direction: "up",
verbose: true,
migrationsTable: "pgmigrations",
};

if (request.method === "GET") {
const pendingMigrations = await migrationRunner(defaultMigrationsOptions);
});

return response.status(200).json(pendingMigrations);
return response.status(200).json(pendingMigrations);
} finally {
if (dbClient) {
await dbClient.end();
}
}
}

if (request.method === "POST") {
const migratedMigrations = await migrationRunner({
...defaultMigrationsOptions,
dryRun: false,
});
async function postHandler(request, response) {
let dbClient;

if (migratedMigrations.length > 0) {
return response.status(201).json(migratedMigrations);
}
try {
dbClient = await database.getNewClient();

return response.status(200).json(migratedMigrations);
const migratedMigrations = await migrationRunner({
...defaultMigrationsOptions,
dbClient,
dryRun: false,
});

if (migratedMigrations.length > 0) {
return response.status(201).json(migratedMigrations);
}
} catch (error) {
console.error(error);

return response.status(500).json({
error: "Internal Server Error",
});
return response.status(200).json(migratedMigrations);
} finally {
if (dbClient) {
await dbClient.end();
Expand Down
83 changes: 38 additions & 45 deletions pages/api/v1/status/index.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,43 @@
// status/api

import { createRouter } from "next-connect";
import database from "infra/database.js";
import { InternalServerError } from "infra/erros";

async function status(request, response) {
try {
const updatedAt = new Date().toISOString();

const databaseVersionResult = await database.query("SHOW server_version;");
const databaseVersionValue = databaseVersionResult.rows[0].server_version;

const databaseMaxConnectionsResult = await database.query(
"SHOW max_connections",
);

const databaseMaxConnectionsValue =
databaseMaxConnectionsResult.rows[0].max_connections;

const databaseName = process.env.POSTGRES_DB;
const databaseOpenConnectionsResult = await database.query({
text: "SELECT count(*)::int FROM pg_stat_activity WHERE datname = $1;",
values: [databaseName],
});
const databaseOpenConnectionsValue =
databaseOpenConnectionsResult.rows[0].count;

response.status(200).json({
updated_at: updatedAt,
dependencies: {
database: {
version: databaseVersionValue,
max_connections: parseInt(databaseMaxConnectionsValue),
open_connections: databaseOpenConnectionsValue,
},
},
});
} catch (error) {
const publicErrorObject = new InternalServerError({
cause: error,
});
import controller from "infra/controller";

console.log("\n Erro dentro do catch do controller: ");
console.error(publicErrorObject);
const router = createRouter();

response.status(500).json(publicErrorObject);
}
}
router.get(getHandler);

export default router.handler(controller.errorHandlers);

async function getHandler(request, response) {
const updatedAt = new Date().toISOString();

const databaseVersionResult = await database.query("SHOW server_version;");
const databaseVersionValue = databaseVersionResult.rows[0].server_version;

export default status;
const databaseMaxConnectionsResult = await database.query(
"SHOW max_connections",
);

const databaseMaxConnectionsValue =
databaseMaxConnectionsResult.rows[0].max_connections;

const databaseName = process.env.POSTGRES_DB;
const databaseOpenConnectionsResult = await database.query({
text: "SELECT count(*)::int FROM pg_stat_activity WHERE datname = $1;",
values: [databaseName],
});
const databaseOpenConnectionsValue =
databaseOpenConnectionsResult.rows[0].count;

response.status(200).json({
updated_at: updatedAt,
dependencies: {
database: {
version: databaseVersionValue,
max_connections: parseInt(databaseMaxConnectionsValue),
open_connections: databaseOpenConnectionsValue,
},
},
});
}
Loading
Loading