Files
myeasycms-v2/packages/features/verbandsverwaltung/src/schema/verband.schema.ts
Zaid Marzguioui ebd0fd4638
Some checks failed
Workflow / ʦ TypeScript (push) Failing after 6m26s
Workflow / ⚫️ Test (push) Has been skipped
feat: complete CMS v2 with Docker, Fischerei, Meetings, Verband modules + UX audit fixes
Major changes:
- Docker Compose: full Supabase stack (11 services) equivalent to supabase CLI
- Fischerei module: 16 DB tables, waters/species/stocking/catch books/competitions
- Sitzungsprotokolle module: meeting protocols, agenda items, task tracking
- Verbandsverwaltung module: federation management, member clubs, contacts, fees
- Per-account module activation via Modules page toggle
- Site Builder: live CMS data in Puck blocks (courses, events, membership registration)
- Public registration APIs: course signup, event registration, membership application
- Document generation: PDF member cards, Excel reports, HTML labels
- Landing page: real Com.BISS content (no filler text)
- UX audit fixes: AccountNotFound component, shared status badges, confirm dialog,
  pagination, duplicate heading removal, emoji→badge replacement, a11y fixes
- QA: healthcheck fix, API auth fix, enum mismatch fix, password required attribute
2026-03-31 16:35:46 +02:00

197 lines
6.3 KiB
TypeScript

import { z } from 'zod';
// =====================================================
// Enum Schemas
// =====================================================
export const associationTypeSchema = z.enum([
'sportverein',
'fischereiverein',
'schuetzenverein',
'musikverein',
'kulturverein',
'foerderverein',
'jugendverein',
'sonstige',
]);
export const paymentMethodSchema = z.enum([
'bar',
'lastschrift',
'ueberweisung',
'paypal',
]);
export const billingStatusSchema = z.enum([
'offen',
'bezahlt',
'ueberfaellig',
'storniert',
]);
export const noteTypeSchema = z.enum([
'notiz',
'aufgabe',
'erinnerung',
]);
export const contactRoleSchema = z.enum([
'vorsitzender',
'stellvertreter',
'kassier',
'schriftfuehrer',
'jugendwart',
'sportwart',
'beisitzer',
'sonstige',
]);
// =====================================================
// Type Exports
// =====================================================
export type AssociationType = z.infer<typeof associationTypeSchema>;
export type PaymentMethod = z.infer<typeof paymentMethodSchema>;
export type BillingStatus = z.infer<typeof billingStatusSchema>;
export type NoteType = z.infer<typeof noteTypeSchema>;
export type ContactRole = z.infer<typeof contactRoleSchema>;
// =====================================================
// Member Clubs (Vereine)
// =====================================================
export const CreateMemberClubSchema = z.object({
accountId: z.string().uuid(),
name: z.string().min(1, 'Name ist erforderlich').max(256),
shortName: z.string().max(32).optional(),
associationTypeId: z.string().uuid().optional(),
memberCount: z.number().int().min(0).optional(),
foundedYear: z.number().int().min(1800).max(2100).optional(),
street: z.string().max(256).optional(),
zip: z.string().max(10).optional(),
city: z.string().max(128).optional(),
phone: z.string().max(64).optional(),
email: z.string().email().optional().or(z.literal('')),
website: z.string().url().optional().or(z.literal('')),
iban: z.string().max(34).optional(),
bic: z.string().max(11).optional(),
accountHolder: z.string().max(256).optional(),
isArchived: z.boolean().default(false),
});
export type CreateMemberClubInput = z.infer<typeof CreateMemberClubSchema>;
export const UpdateMemberClubSchema = CreateMemberClubSchema.partial().extend({
clubId: z.string().uuid(),
});
export type UpdateMemberClubInput = z.infer<typeof UpdateMemberClubSchema>;
// =====================================================
// Club Contacts (Ansprechpartner)
// =====================================================
export const CreateClubContactSchema = z.object({
clubId: z.string().uuid(),
firstName: z.string().min(1, 'Vorname ist erforderlich').max(128),
lastName: z.string().min(1, 'Nachname ist erforderlich').max(128),
role: contactRoleSchema.default('sonstige'),
phone: z.string().max(64).optional(),
email: z.string().email().optional().or(z.literal('')),
isPrimary: z.boolean().default(false),
});
export type CreateClubContactInput = z.infer<typeof CreateClubContactSchema>;
export const UpdateClubContactSchema = CreateClubContactSchema.partial().extend({
contactId: z.string().uuid(),
});
export type UpdateClubContactInput = z.infer<typeof UpdateClubContactSchema>;
// =====================================================
// Club Roles (Funktionen im Verband)
// =====================================================
export const CreateClubRoleSchema = z.object({
accountId: z.string().uuid(),
name: z.string().min(1, 'Name ist erforderlich').max(128),
description: z.string().max(512).optional(),
sortOrder: z.number().int().default(0),
});
export type CreateClubRoleInput = z.infer<typeof CreateClubRoleSchema>;
// =====================================================
// Association Types (Vereinstypen)
// =====================================================
export const CreateAssociationTypeSchema = z.object({
accountId: z.string().uuid(),
name: z.string().min(1, 'Name ist erforderlich').max(128),
description: z.string().max(512).optional(),
sortOrder: z.number().int().default(0),
});
export type CreateAssociationTypeInput = z.infer<typeof CreateAssociationTypeSchema>;
// =====================================================
// Club Fee Types (Beitragsarten)
// =====================================================
export const CreateClubFeeTypeSchema = z.object({
accountId: z.string().uuid(),
name: z.string().min(1, 'Name ist erforderlich').max(128),
description: z.string().max(512).optional(),
defaultAmount: z.number().min(0).optional(),
isActive: z.boolean().default(true),
});
export type CreateClubFeeTypeInput = z.infer<typeof CreateClubFeeTypeSchema>;
// =====================================================
// Club Fee Billings (Beitragsabrechnungen)
// =====================================================
export const CreateClubFeeBillingSchema = z.object({
clubId: z.string().uuid(),
feeTypeId: z.string().uuid(),
year: z.number().int().min(2000).max(2100),
amount: z.number().min(0),
dueDate: z.string().optional(),
paidDate: z.string().optional(),
paymentMethod: paymentMethodSchema.optional(),
status: billingStatusSchema.default('offen'),
notes: z.string().max(1024).optional(),
});
export type CreateClubFeeBillingInput = z.infer<typeof CreateClubFeeBillingSchema>;
// =====================================================
// Club Notes (Notizen / Aufgaben)
// =====================================================
export const CreateClubNoteSchema = z.object({
clubId: z.string().uuid(),
title: z.string().min(1, 'Titel ist erforderlich').max(256),
content: z.string().optional(),
noteType: noteTypeSchema.default('notiz'),
dueDate: z.string().optional(),
isCompleted: z.boolean().default(false),
});
export type CreateClubNoteInput = z.infer<typeof CreateClubNoteSchema>;
// =====================================================
// Association History (Verbandshistorie)
// =====================================================
export const CreateAssociationHistorySchema = z.object({
clubId: z.string().uuid(),
year: z.number().int().min(1800).max(2100),
memberCount: z.number().int().min(0).optional(),
notes: z.string().max(2048).optional(),
});
export type CreateAssociationHistoryInput = z.infer<typeof CreateAssociationHistorySchema>;