Major changes since initial commit: Schema: version branching (parentVersionId, branchLabel), share links, guest comments, track status enum (sketch/in_progress/final/released), track sections, cover art for projects and tracks. API: 29+ endpoints — auth, projects, tracks, versions, comments, share links (public + management), uploads (cover), activity feed, onboarding demo seed. Email templates in German with brand styling. Web: SvelteKit 5 workspace layout with persistent sidebar, breadcrumb top-bar, collapsible right panel. SoundCloud-style waveform player with round play button, avatar comment markers, keyboard shortcuts (Space/JKL/C). Full German UI. Cover art with gradient fallback. Track status pills. Activity feed dashboard. Welcome modal with demo-seed trigger. Landing page with 7-section scroll layout. Login on /login. Public /listen/:token page for guest feedback. Visual: Inter Variable font, Magenta→Orange gradient accent, warm dark neutrals, Lucide-style inline SVG icon set, spring animations on modals, glass-effect toasts, responsive from 360px to 2560px+. PWA: manifest, service worker, icons, iOS/Android installable. Production: adapter-node, server-side API proxy hook, docker-compose with Postgres + MinIO + auto-migration + health checks. Env example included. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
78 lines
2.8 KiB
TypeScript
78 lines
2.8 KiB
TypeScript
import { z } from 'zod';
|
|
import { SUPPORTED_AUDIO_FORMATS, MAX_FILE_SIZE } from '../constants/audio.js';
|
|
|
|
export const createTrackSchema = z.object({
|
|
name: z.string().min(1).max(255),
|
|
description: z.string().max(2000).optional(),
|
|
});
|
|
|
|
export const TRACK_STATUSES = ['sketch', 'in_progress', 'final', 'released'] as const;
|
|
export type TrackStatus = (typeof TRACK_STATUSES)[number];
|
|
|
|
export const TRACK_STATUS_LABELS: Record<TrackStatus, string> = {
|
|
sketch: 'Skizze',
|
|
in_progress: 'In Arbeit',
|
|
final: 'Final',
|
|
released: 'Veröffentlicht',
|
|
};
|
|
|
|
export const updateTrackSchema = z.object({
|
|
name: z.string().min(1).max(255).optional(),
|
|
description: z.string().max(2000).optional(),
|
|
coverImageUrl: z.string().nullable().optional(),
|
|
status: z.enum(TRACK_STATUSES).optional(),
|
|
section: z.string().max(100).nullable().optional(),
|
|
});
|
|
|
|
export const coverUploadSchema = z.object({
|
|
fileName: z.string().min(1).max(200),
|
|
mimeType: z.enum(['image/jpeg', 'image/png', 'image/webp']),
|
|
fileSize: z.number().int().positive().max(2 * 1024 * 1024),
|
|
});
|
|
|
|
export const requestUploadUrlSchema = z.object({
|
|
fileName: z.string().min(1),
|
|
mimeType: z.enum(SUPPORTED_AUDIO_FORMATS),
|
|
fileSize: z.number().int().positive().max(MAX_FILE_SIZE),
|
|
});
|
|
|
|
export const createVersionSchema = z.object({
|
|
fileKey: z.string().min(1),
|
|
label: z.string().max(100).optional(),
|
|
notes: z.string().max(2000).optional(),
|
|
originalFileName: z.string().min(1),
|
|
mimeType: z.string().min(1),
|
|
fileSize: z.number().int().positive(),
|
|
parentVersionId: z.string().uuid().optional(),
|
|
branchLabel: z.string().max(100).optional(),
|
|
});
|
|
|
|
export const updateVersionSchema = z.object({
|
|
label: z.string().max(100).nullable().optional(),
|
|
notes: z.string().max(2000).nullable().optional(),
|
|
branchLabel: z.string().max(100).nullable().optional(),
|
|
});
|
|
|
|
export const createShareLinkSchema = z.object({
|
|
expiresAt: z.string().datetime().optional(),
|
|
allowComments: z.boolean().optional(),
|
|
allowDownload: z.boolean().optional(),
|
|
password: z.string().min(1).max(255).optional(),
|
|
});
|
|
|
|
export const guestCommentSchema = z.object({
|
|
body: z.string().min(1).max(5000),
|
|
timestampSeconds: z.number().nonnegative().optional(),
|
|
parentId: z.string().uuid().optional(),
|
|
guestName: z.string().min(1).max(100),
|
|
});
|
|
|
|
export type CreateTrackInput = z.infer<typeof createTrackSchema>;
|
|
export type UpdateTrackInput = z.infer<typeof updateTrackSchema>;
|
|
export type RequestUploadUrlInput = z.infer<typeof requestUploadUrlSchema>;
|
|
export type CreateVersionInput = z.infer<typeof createVersionSchema>;
|
|
export type UpdateVersionInput = z.infer<typeof updateVersionSchema>;
|
|
export type CreateShareLinkInput = z.infer<typeof createShareLinkSchema>;
|
|
export type CoverUploadInput = z.infer<typeof coverUploadSchema>;
|
|
export type GuestCommentInput = z.infer<typeof guestCommentSchema>;
|