import type { FastifyInstance } from 'fastify'; import { z } from 'zod'; import { auditLog, createDb, desc, eq, memberships, organizations, users } from '@bmm/db'; import { requireAuth } from '../plugins/session.js'; const db = createDb(); export async function settingsRoutes(app: FastifyInstance): Promise { app.get('/v1/me/org', { preHandler: requireAuth }, async (req, reply) => { const user = req.user!; const [org] = await db.select().from(organizations).where(eq(organizations.id, user.orgId)).limit(1); if (!org) return reply.code(404).send({ error: 'not_found' }); const members = await db .select({ id: memberships.id, userId: users.id, email: users.email, name: users.name, role: memberships.role, createdAt: memberships.createdAt, }) .from(memberships) .innerJoin(users, eq(users.id, memberships.userId)) .where(eq(memberships.orgId, org.id)) .orderBy(memberships.createdAt); return reply.send({ org, members }); }); app.get('/v1/audit', { preHandler: requireAuth }, async (req, reply) => { const user = req.user!; const Query = z.object({ limit: z.coerce.number().min(1).max(500).default(100), action: z.string().optional(), resourceType: z.string().optional(), }); const parsed = Query.safeParse(req.query); if (!parsed.success) return reply.code(400).send({ error: 'invalid_query' }); let rows = await db .select() .from(auditLog) .where(eq(auditLog.orgId, user.orgId)) .orderBy(desc(auditLog.createdAt)) .limit(parsed.data.limit); if (parsed.data.action) { rows = rows.filter((r) => r.action === parsed.data.action); } if (parsed.data.resourceType) { rows = rows.filter((r) => r.resourceType === parsed.data.resourceType); } return reply.send({ entries: rows }); }); }