Files
Sauci/apps/api/src/domains/packs/routes.ts
T
jjbrunton 006761d3b0 feat(backend): add standalone data plane
Replace the Supabase application data plane with the Node/PostgreSQL API, migrate mobile, admin, web, and MCP callers, add controlled cutover tooling, and define hardened Dokploy infrastructure.
2026-08-28 14:42:11 +01:00

47 lines
1.9 KiB
TypeScript

import type { ApiErrorResponse } from '@sauci/shared';
import type { Hono } from 'hono';
import { z } from 'zod';
import type { AuthIdentity } from '../../auth.js';
import { PacksDomainError, type PacksRepository } from './repository.js';
type PacksApp = Hono<{ Variables: { identity: AuthIdentity } }>;
const uuidSchema = z.string().uuid();
const toggleSchema = z.object({ enabled: z.boolean() }).strict();
function error(code: string, message: string): ApiErrorResponse {
return { error: { code, message } };
}
export function registerPackRoutes(app: PacksApp, repository: PacksRepository): void {
app.get('/v1/packs', async (c) => {
const showAll = c.req.query('showAllIntensities') === 'true';
return c.json(await repository.getCatalog(c.get('identity').id, showAll));
});
app.get('/v1/me/enabled-packs', async (c) =>
c.json(await repository.getEnabledPacks(c.get('identity').id)));
app.put('/v1/me/enabled-packs/:packId', async (c) => {
const packId = uuidSchema.safeParse(c.req.param('packId'));
if (!packId.success) return c.json(error('invalid_pack_id', 'Pack ID must be a UUID'), 400);
const body = toggleSchema.safeParse(await c.req.json().catch(() => null));
if (!body.success) return c.json(error('invalid_request', 'enabled must be a boolean'), 400);
try {
return c.json(await repository.setPackEnabled(c.get('identity').id, packId.data, body.data.enabled));
} catch (cause) {
if (cause instanceof PacksDomainError && cause.code === 'no_couple') {
return c.json(error('no_couple', 'Join a couple before changing packs'), 409);
}
if (cause instanceof PacksDomainError && cause.code === 'pack_not_found') {
return c.json(error('pack_not_found', 'Pack was not found'), 404);
}
throw cause;
}
});
app.get('/v1/me/pack-progress', async (c) =>
c.json(await repository.getPackProgress(c.get('identity').id)));
}