Skip to content

Commit 4b076e9

Browse files
committed
Serve stored messages from API
1 parent 09900c9 commit 4b076e9

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
@@ -73,13 +73,22 @@ interface StoredMessage {
7373
message: Message;
7474
authorId: Snowflake;
7575
createdAt: Date;
76+
description: string;
77+
tags: string[];
7678
type: PostType;
7779
}
7880
let jobBoardMessageCache: {
7981
forHire: StoredMessage[];
8082
hiring: StoredMessage[];
8183
} = { forHire: [], hiring: [] };
8284

85+
export const getJobPosts = () => {
86+
return {
87+
hiring: jobBoardMessageCache.hiring,
88+
forHire: jobBoardMessageCache.forHire,
89+
};
90+
};
91+
8392
const DAYS_OF_POSTS = 30;
8493

8594
export const loadJobs = async (bot: Client, channel: TextChannel) => {
@@ -100,18 +109,21 @@ export const loadJobs = async (bot: Client, channel: TextChannel) => {
100109
})
101110
)
102111
// Convert fetched messages to be stored in the cache
103-
.map((message) => ({
104-
message,
105-
authorId: message.author.id,
106-
createdAt: message.createdAt,
107-
// By searching for "hiring", we treat posts without tags as "forhire",
108-
// which makes the subject to deletion after aging out. This will only be
109-
// relevant when this change is first shipped, because afterwards all
110-
// un-tagged posts will be removed.
111-
type: parseContent(message.content)[0].tags.includes("hiring")
112-
? PostType.hiring
113-
: PostType.forHire,
114-
}));
112+
.map((message) => {
113+
const { tags, description } = parseContent(message.content)[0];
114+
return {
115+
message,
116+
authorId: message.author.id,
117+
createdAt: message.createdAt,
118+
description,
119+
tags,
120+
// By searching for "hiring", we treat posts without tags as "forhire",
121+
// which makes the subject to deletion after aging out. This will only be
122+
// relevant when this change is first shipped, because afterwards all
123+
// un-tagged posts will be removed.
124+
type: tags.includes("hiring") ? PostType.hiring : PostType.forHire,
125+
};
126+
});
115127
if (newMessages.length === 0) {
116128
break;
117129
}
@@ -230,6 +242,8 @@ export const updateJobs = (message: Message) => {
230242
message,
231243
authorId: message.author.id,
232244
createdAt: message.createdAt,
245+
description: parsed.description,
246+
tags: parsed.tags,
233247
type,
234248
});
235249

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)