Skip to content

Commit 00b4155

Browse files
committed
chore: refactor api
1 parent 97ddf60 commit 00b4155

File tree

3 files changed

+94
-89
lines changed

3 files changed

+94
-89
lines changed

apps/api/src/controllers/webhooks.ts

Lines changed: 58 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,94 @@
1-
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
2-
import { checkToken } from "../lib/jwt";
3-
import { prisma } from "../prisma";
1+
import { FastifyInstance } from "fastify";
42
import { track } from "../lib/hog";
3+
import { Hook, prisma } from "../prisma";
4+
5+
// Type definitions
6+
interface WebhookPayload {
7+
name: string;
8+
url: string;
9+
type: Hook;
10+
active: boolean;
11+
secret: string;
12+
}
513

614
export function webhookRoutes(fastify: FastifyInstance) {
715
// Create a new webhook
8-
fastify.post(
16+
fastify.post<{ Body: WebhookPayload }>(
917
"/api/v1/webhook/create",
18+
async (request, reply) => {
19+
try {
20+
const { name, url, type, active, secret } = request.body;
1021

11-
async (request: FastifyRequest, reply: FastifyReply) => {
12-
const bearer = request.headers.authorization!.split(" ")[1];
13-
const token = checkToken(bearer);
14-
15-
if (token) {
16-
const { name, url, type, active, secret }: any = request.body;
17-
await prisma.webhooks.create({
22+
const webhook = await prisma.webhooks.create({
1823
data: {
1924
name,
2025
url,
2126
type,
2227
active,
2328
secret,
24-
createdBy: "375f7799-5485-40ff-ba8f-0a28e0855ecf",
29+
createdBy: "375f7799-5485-40ff-ba8f-0a28e0855ecf", // TODO: Get from authenticated user
2530
},
2631
});
2732

2833
const client = track();
29-
30-
client.capture({
34+
await client.capture({
3135
event: "webhook_created",
32-
distinctId: "uuid",
36+
distinctId: webhook.id, // Use actual webhook ID
3337
});
38+
await client.shutdownAsync();
3439

35-
client.shutdownAsync();
36-
37-
reply.status(200).send({ message: "Hook created!", success: true });
40+
return reply.status(201).send({
41+
data: webhook,
42+
success: true,
43+
});
44+
} catch (error) {
45+
return reply.status(400).send({
46+
error:
47+
error instanceof Error ? error.message : "Failed to create webhook",
48+
success: false,
49+
});
3850
}
3951
}
4052
);
4153

4254
// Get all webhooks
43-
fastify.get(
44-
"/api/v1/webhooks/all",
45-
46-
async (request: FastifyRequest, reply: FastifyReply) => {
47-
const bearer = request.headers.authorization!.split(" ")[1];
48-
const token = checkToken(bearer);
49-
50-
if (token) {
51-
const webhooks = await prisma.webhooks.findMany({});
55+
fastify.get("/api/v1/webhooks/all", async (request, reply) => {
56+
try {
57+
const webhooks = await prisma.webhooks.findMany();
5258

53-
reply.status(200).send({ webhooks: webhooks, success: true });
54-
}
59+
return reply.status(200).send({
60+
data: webhooks,
61+
success: true,
62+
});
63+
} catch (error) {
64+
return reply.status(400).send({
65+
error:
66+
error instanceof Error ? error.message : "Failed to fetch webhooks",
67+
success: false,
68+
});
5569
}
56-
);
70+
});
5771

5872
// Delete a webhook
59-
60-
fastify.delete(
73+
fastify.delete<{ Params: { id: string } }>(
6174
"/api/v1/admin/webhook/:id/delete",
75+
async (request, reply) => {
76+
try {
77+
const { id } = request.params;
6278

63-
async (request: FastifyRequest, reply: FastifyReply) => {
64-
const bearer = request.headers.authorization!.split(" ")[1];
65-
const token = checkToken(bearer);
66-
67-
if (token) {
68-
const { id }: any = request.params;
6979
await prisma.webhooks.delete({
70-
where: {
71-
id: id,
72-
},
80+
where: { id },
7381
});
7482

75-
reply.status(200).send({ success: true });
83+
return reply.status(200).send({
84+
success: true,
85+
});
86+
} catch (error) {
87+
return reply.status(400).send({
88+
error:
89+
error instanceof Error ? error.message : "Failed to delete webhook",
90+
success: false,
91+
});
7692
}
7793
}
7894
);

apps/api/src/main.ts

Lines changed: 35 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ import fs from "fs";
77
import { exec } from "child_process";
88
import { track } from "./lib/hog";
99
import { getEmails } from "./lib/imap";
10+
import { checkToken } from "./lib/jwt";
1011
import { prisma } from "./prisma";
1112
import { registerRoutes } from "./routes";
1213

1314
// Ensure the directory exists
14-
const logFilePath = './logs.log'; // Update this path to a writable location
15+
const logFilePath = "./logs.log"; // Update this path to a writable location
1516

1617
// Create a writable stream
17-
const logStream = fs.createWriteStream(logFilePath, { flags: 'a' });
18+
const logStream = fs.createWriteStream(logFilePath, { flags: "a" });
1819

1920
// Initialize Fastify with logger
2021
const server: FastifyInstance = Fastify({
@@ -26,62 +27,49 @@ const server: FastifyInstance = Fastify({
2627
});
2728
server.register(cors, {
2829
origin: "*",
29-
30+
3031
methods: ["GET", "POST", "PUT", "DELETE"],
3132
allowedHeaders: ["Content-Type", "Authorization", "Accept"],
3233
});
3334

34-
server.register(require("@fastify/swagger"), {
35-
swagger: {
36-
info: {
37-
title: "Peppermint API DOCS",
38-
description: "Peppermint swagger API",
39-
version: "0.1.0",
40-
},
41-
externalDocs: {
42-
url: "https://swagger.io",
43-
description: "Find more info here",
44-
},
45-
mode: "static",
46-
host: "localhost",
47-
schemes: ["http"],
48-
consumes: ["application/json"],
49-
produces: ["application/json"],
50-
tags: [
51-
{ name: "user", description: "User related end-points" },
52-
{ name: "code", description: "Code related end-points" },
53-
],
54-
exposeRoute: true,
55-
definitions: {
56-
User: {
57-
type: "object",
58-
required: ["id", "email"],
59-
properties: {
60-
id: { type: "string", format: "uuid" },
61-
firstName: { type: "string" },
62-
lastName: { type: "string" },
63-
email: { type: "string", format: "email" },
64-
},
65-
},
66-
},
67-
securityDefinitions: {
68-
apiKey: {
69-
type: "apiKey",
70-
name: "apiKey",
71-
in: "header",
72-
},
73-
},
74-
},
75-
});
76-
7735
server.register(multer.contentParser);
7836

7937
registerRoutes(server);
8038

81-
server.get("/", async function (request, response) {
39+
server.get("/", {
40+
schema: {
41+
tags: ['health'], // This groups the endpoint under a category
42+
description: 'Health check endpoint',
43+
response: {
44+
200: {
45+
type: 'object',
46+
properties: {
47+
healthy: { type: 'boolean' }
48+
}
49+
}
50+
}
51+
}
52+
}, async function (request, response) {
8253
response.send({ healthy: true });
8354
});
8455

56+
server.addHook("preHandler", async (request, reply) => {
57+
if (request.url.startsWith("/api/public") || request.url.startsWith("/documentation")) {
58+
return;
59+
}
60+
61+
try {
62+
const bearer = request.headers.authorization?.split(" ")[1];
63+
if (!bearer) throw new Error("No authorization token provided");
64+
await checkToken(bearer);
65+
} catch (error) {
66+
reply.status(401).send({
67+
error: "Authentication failed",
68+
success: false,
69+
});
70+
}
71+
});
72+
8573
const start = async () => {
8674
try {
8775
// Run prisma generate and migrate commands before starting the server

apps/api/src/prisma.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
import { PrismaClient } from "@prisma/client";
22
export const prisma: PrismaClient = new PrismaClient();
3+
export type Hook = "ticket_created" | "ticket_status_changed";

0 commit comments

Comments
 (0)