feat: complete platform operations roadmap
This commit is contained in:
@@ -10,10 +10,24 @@ import { manageCourseRoutes } from './routes/manage-courses.js';
|
||||
import { learningRoutes } from './routes/learning.js';
|
||||
import { adminRoutes } from './routes/admin.js';
|
||||
import { mediaRoutes } from './routes/media.js';
|
||||
import { bunnyWebhookRoutes } from './routes/bunny-webhooks.js';
|
||||
|
||||
export function buildApp() {
|
||||
const app = Fastify({ logger: true });
|
||||
|
||||
// Bunny signs the exact webhook byte sequence. Preserve the raw JSON body
|
||||
// before parsing it so the signature can be verified server-side.
|
||||
app.removeContentTypeParser('application/json');
|
||||
app.addContentTypeParser('application/json', { parseAs: 'buffer' }, (request, body, done) => {
|
||||
const rawBody = Buffer.isBuffer(body) ? body : Buffer.from(body);
|
||||
(request as typeof request & { rawBody?: Buffer }).rawBody = rawBody;
|
||||
try {
|
||||
done(null, JSON.parse(rawBody.toString('utf8')));
|
||||
} catch {
|
||||
done(new Error('Invalid JSON body'));
|
||||
}
|
||||
});
|
||||
|
||||
// Bunny uploads are streamed through the authenticated API. Keeping the body
|
||||
// as a stream avoids loading a whole course video into Node's memory.
|
||||
const rawUploadParser = (_request: unknown, payload: unknown, done: (error: Error | null, body?: unknown) => void) => done(null, payload);
|
||||
@@ -50,6 +64,7 @@ export function buildApp() {
|
||||
app.register(courseRoutes, { prefix: '/api/v1/courses' });
|
||||
app.register(manageCourseRoutes, { prefix: '/api/v1/manage/courses' });
|
||||
app.register(mediaRoutes, { prefix: '/api/v1/manage/media' });
|
||||
app.register(bunnyWebhookRoutes, { prefix: '/api/v1/webhooks' });
|
||||
app.register(learningRoutes, { prefix: '/api/v1' });
|
||||
app.register(adminRoutes, { prefix: '/api/v1/admin' });
|
||||
return app;
|
||||
|
||||
Reference in New Issue
Block a user