we-superapp / apps /api /src /modules /calendar.js
nenbuj
Initial deploy: «МЫ» супер-апп
c562e21
Raw History Blame Contribute Delete
1.55 kB
import crypto from 'node:crypto';
import { db } from '../core/db.js';
import { bus } from '../core/bus.js';
import { requireMember } from '../core/guards.js';
function sendError(reply, status, code, message) {
return reply.code(status).send({ error: { code, message } });
}
export default async function calendarRoutes(fastify) {
fastify.get('/spaces/:id/events', async (request) => {
await requireMember(request, request.params.id);
const events = db
.prepare('SELECT * FROM events WHERE space_id = ? ORDER BY start_at ASC')
.all(request.params.id);
return { events };
});
fastify.post('/spaces/:id/events', async (request, reply) => {
await requireMember(request, request.params.id);
const spaceId = request.params.id;
const { title, start_at } = request.body || {};
if (!title || typeof title !== 'string') {
return sendError(reply, 400, 'VALIDATION', 'title обязателен');
}
if (!Number.isInteger(start_at)) {
return sendError(reply, 400, 'VALIDATION', 'start_at должен быть unix ms');
}
const event = {
id: crypto.randomUUID(),
space_id: spaceId,
title,
start_at,
created_at: Date.now(),
};
db.prepare('INSERT INTO events (id, space_id, title, start_at, created_at) VALUES (?,?,?,?,?)')
.run(event.id, event.space_id, event.title, event.start_at, event.created_at);
bus.emit(spaceId, { type: 'event.created', space_id: spaceId, payload: event });
return reply.code(201).send({ event });
});
}