Skip to content

Commit eac35be

Browse files
committed
Serve stored messages from API
1 parent 8a7449a commit eac35be

File tree

2 files changed

+107
-75
lines changed

2 files changed

+107
-75
lines changed

src/features/jobs-moderation/job-mod-helpers.ts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,22 @@ interface StoredMessage {
6969
message: Message;
7070
authorId: Snowflake;
7171
createdAt: Date;
72+
description: string;
73+
tags: string[];
7274
type: PostType;
7375
}
7476
let jobBoardMessageCache: {
7577
forHire: StoredMessage[];
7678
hiring: StoredMessage[];
7779
} = { forHire: [], hiring: [] };
7880

81+
export const getJobPosts = () => {
82+
return {
83+
hiring: jobBoardMessageCache.hiring,
84+
forHire: jobBoardMessageCache.forHire,
85+
};
86+
};
87+
7988
const DAYS_OF_POSTS = 30;
8089

8190
export const loadJobs = async (bot: Client, channel: TextChannel) => {
@@ -96,18 +105,21 @@ export const loadJobs = async (bot: Client, channel: TextChannel) => {
96105
})
97106
)
98107
// Convert fetched messages to be stored in the cache
99-
.map((message) => ({
100-
message,
101-
authorId: message.author.id,
102-
createdAt: message.createdAt,
103-
// By searching for "hiring", we treat posts without tags as "forhire",
104-
// which makes the subject to deletion after aging out. This will only be
105-
// relevant when this change is first shipped, because afterwards all
106-
// un-tagged posts will be removed.
107-
type: parseContent(message.content)[0].tags.includes("hiring")
108-
? PostType.hiring
109-
: PostType.forHire,
110-
}));
108+
.map((message) => {
109+
const { tags, description } = parseContent(message.content)[0];
110+
return {
111+
message,
112+
authorId: message.author.id,
113+
createdAt: message.createdAt,
114+
description,
115+
tags,
116+
// By searching for "hiring", we treat posts without tags as "forhire",
117+
// which makes the subject to deletion after aging out. This will only be
118+
// relevant when this change is first shipped, because afterwards all
119+
// un-tagged posts will be removed.
120+
type: tags.includes("hiring") ? PostType.hiring : PostType.forHire,
121+
};
122+
});
111123
if (newMessages.length === 0) {
112124
break;
113125
}
@@ -226,6 +238,8 @@ export const updateJobs = (message: Message) => {
226238
message,
227239
authorId: message.author.id,
228240
createdAt: message.createdAt,
241+
description: parsed.description,
242+
tags: parsed.tags,
229243
type,
230244
});
231245

src/server.ts

Lines changed: 81 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,106 @@
11
import Fastify from "fastify";
22
import cors from "@fastify/cors";
33
import helmet from "@fastify/helmet";
4-
import rateLimit from "@fastify/rate-limit";
54
import swagger from "@fastify/swagger";
5+
import { getJobPosts } from "./features/jobs-moderation/job-mod-helpers";
66

7-
const fastify = Fastify({
8-
logger: {
9-
transport: {
10-
target: "pino-pretty",
7+
const fastify = Fastify({ logger: true });
8+
9+
const openApiConfig = {
10+
openapi: "3.0.0",
11+
info: {
12+
title: "Job Board API",
13+
version: "1.0.0",
14+
},
15+
components: {
16+
schemas: {
17+
JobPost: {
18+
type: "object",
19+
required: ["tags", "description", "authorId", "message", "createdAt"],
20+
properties: {
21+
tags: {
22+
type: "array",
23+
items: { type: "string" },
24+
},
25+
description: { type: "string" },
26+
authorId: {
27+
type: "string",
28+
format: "snowflake",
29+
},
30+
message: {
31+
type: "object",
32+
description: "Discord Message object",
33+
},
34+
createdAt: {
35+
type: "string",
36+
format: "date-time",
37+
},
38+
},
39+
},
40+
JobBoardCache: {
41+
type: "object",
42+
required: ["forHire", "hiring"],
43+
properties: {
44+
forHire: {
45+
type: "array",
46+
items: { $ref: "JobPost" },
47+
},
48+
hiring: {
49+
type: "array",
50+
items: { $ref: "JobPost" },
51+
},
52+
},
53+
},
1154
},
1255
},
13-
});
14-
15-
// Swagger documentation
16-
const swaggerConfig = {
17-
swagger: {
18-
info: {
19-
title: "API Documentation",
20-
version: "1.0.0",
56+
paths: {
57+
"/jobs": {
58+
get: {
59+
tags: ["jobs"],
60+
summary: "Get all job posts",
61+
responses: {
62+
"200": {
63+
description: "Successful response",
64+
content: {
65+
"application/json": {
66+
schema: {
67+
$ref: "JobBoardCache",
68+
},
69+
},
70+
},
71+
},
72+
},
73+
},
2174
},
2275
},
2376
};
2477

25-
// Register plugins
26-
await fastify.register(cors);
27-
await fastify.register(helmet);
28-
await fastify.register(rateLimit, {
29-
max: 100,
30-
timeWindow: "1 minute",
31-
});
32-
await fastify.register(swagger, swaggerConfig);
33-
34-
// Example route with schema validation
35-
// fastify.get(
36-
// "/items",
37-
// {
38-
// schema: {
39-
// response: {
40-
// 200: {
41-
// type: "array",
42-
// items: {
43-
// type: "object",
44-
// properties: {
45-
// id: { type: "string" },
46-
// name: { type: "string" },
47-
// },
48-
// },
49-
// },
50-
// },
51-
// },
52-
// },
53-
// async (request, reply) => {
54-
// return [{ id: "1", name: "Item 1" }];
55-
// },
56-
// );
78+
try {
79+
Object.entries(openApiConfig.components.schemas).forEach(([k, schema]) => {
80+
fastify.addSchema({ ...schema, $id: k });
81+
});
82+
// @ts-expect-error something's busted but it works
83+
await fastify.register(swagger, openApiConfig);
84+
await fastify.register(cors);
85+
await fastify.register(helmet);
86+
} catch (e) {
87+
console.log(e);
88+
}
5789

5890
fastify.get(
59-
"/",
91+
"/jobs",
6092
{
6193
schema: {
6294
response: {
6395
200: {
64-
type: "object",
65-
properties: {
66-
hello: { type: "string" },
67-
},
96+
$ref: "JobBoardCache",
6897
},
6998
},
7099
},
71100
},
72101
async () => {
73-
return { hello: "world" };
102+
return getJobPosts();
74103
},
75104
);
76105

77-
// Error handler
78-
fastify.setErrorHandler((error, request, reply) => {
79-
fastify.log.error(error);
80-
reply.status(500).send({ error: "Internal Server Error" });
81-
});
82-
83-
try {
84-
await fastify.listen({ port: 3000 });
85-
} catch (err) {
86-
fastify.log.error(err);
87-
process.exit(1);
88-
}
106+
await fastify.listen({ port: 3000 });

0 commit comments

Comments
 (0)