Initial commit (unpacked platform)

This commit is contained in:
Sven (AAMOS AI)
2026-08-05 19:21:11 +07:00
commit ac5340195a
314 changed files with 57584 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
import type { ZodType } from "zod";
/** Applikationsfel med HTTP-status och maskinläsbar kod. */
export class ApiError extends Error {
constructor(
public readonly statusCode: number,
public readonly code: string,
message: string,
public readonly details?: unknown,
) {
super(message);
this.name = "ApiError";
}
}
export const errors = {
badRequest: (msg: string, details?: unknown) => new ApiError(400, "BAD_REQUEST", msg, details),
unauthorized: (msg = "Ogiltig eller saknad autentisering") =>
new ApiError(401, "UNAUTHORIZED", msg),
forbidden: (msg = "Åtkomst nekad") => new ApiError(403, "FORBIDDEN", msg),
notFound: (msg = "Resursen finns inte") => new ApiError(404, "NOT_FOUND", msg),
conflict: (msg: string) => new ApiError(409, "CONFLICT", msg),
quotaExceeded: (msg: string) => new ApiError(429, "QUOTA_EXCEEDED", msg),
paymentRequired: (msg: string) => new ApiError(402, "PREMIUM_REQUIRED", msg),
internal: (msg = "Internt fel") => new ApiError(500, "INTERNAL", msg),
};
/**
* Validera indata mot ett Zod-schema. Kastar 400 med detaljer vid fel.
* Medvetet vald i stället för type-provider: färre rörliga delar i
* major-versionsgränser, samma säkerhet (se docs/beslutslogg.md D-011).
*/
export function parse<T>(schema: ZodType<T>, data: unknown, what = "indata"): T {
const result = schema.safeParse(data);
if (!result.success) {
throw new ApiError(400, "VALIDATION_ERROR", `Ogiltig ${what}`, result.error.issues);
}
return result.data;
}