cards/packages/cards-domain/src/schemas/deck.ts
Till JS 5859e202c5 feat(cards): deck management UI + production auth portal wiring
Deck schema, API routes, and SvelteKit UI for creating and browsing decks
(DeckStack component, inline creation, floating nav). Production compose
updated with PUBLIC_AUTH_WEB_URL so cards-web redirects to auth.mana.how
for login/register instead of the raw API.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 18:50:27 +02:00

80 lines
2.1 KiB
TypeScript

import { z } from 'zod';
import { FsrsSettingsSchema } from './fsrs-settings.ts';
const VisibilitySchema = z.enum(['private', 'space', 'public']);
export const DECK_CATEGORY_IDS = [
'language',
'medicine',
'science',
'math',
'history',
'law',
'technology',
'arts',
'music',
'sport',
'other',
] as const;
export type DeckCategoryId = (typeof DECK_CATEGORY_IDS)[number];
export const DeckCategorySchema = z.enum(DECK_CATEGORY_IDS);
export const DECK_CATEGORY_LABELS: Record<DeckCategoryId, string> = {
language: 'Sprache',
medicine: 'Medizin',
science: 'Wissenschaft',
math: 'Mathematik',
history: 'Geschichte',
law: 'Recht',
technology: 'Technik',
arts: 'Kunst',
music: 'Musik',
sport: 'Sport',
other: 'Sonstiges',
};
export const DeckSchema = z
.object({
id: z.string().min(1),
user_id: z.string().min(1),
name: z.string().min(1).max(200),
description: z.string().max(2000).optional().nullable(),
color: z
.string()
.regex(/^#[0-9a-fA-F]{6}$/)
.optional()
.nullable(),
category: DeckCategorySchema.optional().nullable(),
visibility: VisibilitySchema.default('private'),
fsrs_settings: FsrsSettingsSchema.default({}),
content_hash: z.string().optional().nullable(),
forked_from_marketplace_deck_id: z.string().optional().nullable(),
forked_from_marketplace_version_id: z.string().optional().nullable(),
archived_at: z.string().datetime().optional().nullable(),
created_at: z.string().datetime(),
updated_at: z.string().datetime(),
})
.strict();
export type Deck = z.infer<typeof DeckSchema>;
export const DeckCreateSchema = z
.object({
name: z.string().min(1).max(200),
description: z.string().max(2000).optional(),
color: z
.string()
.regex(/^#[0-9a-fA-F]{6}$/)
.optional(),
category: DeckCategorySchema.optional(),
visibility: VisibilitySchema.optional(),
fsrs_settings: FsrsSettingsSchema.optional(),
})
.strict();
export type DeckCreate = z.infer<typeof DeckCreateSchema>;
export const DeckUpdateSchema = DeckCreateSchema.partial().extend({
archived: z.boolean().optional(),
});
export type DeckUpdate = z.infer<typeof DeckUpdateSchema>;