Password auth, artist folders, timezone fix

Add password-based registration + login alongside existing magic links.
New /register and updated /login with tabs (password default, magic link
as alternative). Bun.password.hash/verify for bcrypt. Auto-login on
register. Landing page CTAs point to /register.

Add projects.artist field for grouping projects by artist in sidebar.
Sidebar shows collapsible artist sections (▸ Anna Berger) with project
counts, "Ohne Zuordnung" for ungrouped projects. Search filters across
artist names. New/edit project forms include artist field.

Fix timezone bug: set postgres connection timezone to UTC so magic link
expiry works correctly in CEST and other non-UTC timezones.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Robin Choice
2026-04-12 19:06:06 +02:00
parent 8bf72c2482
commit 09e47d8800
19 changed files with 2335 additions and 76 deletions

View File

@@ -8,5 +8,18 @@ export const verifyTokenSchema = z.object({
token: z.string().min(1),
});
export const registerSchema = z.object({
name: z.string().min(1).max(255),
email: z.string().email(),
password: z.string().min(8).max(200),
});
export const loginSchema = z.object({
email: z.string().email(),
password: z.string().min(1).max(200),
});
export type MagicLinkInput = z.infer<typeof magicLinkSchema>;
export type VerifyTokenInput = z.infer<typeof verifyTokenSchema>;
export type RegisterInput = z.infer<typeof registerSchema>;
export type LoginInput = z.infer<typeof loginSchema>;

View File

@@ -4,11 +4,13 @@ import { PROJECT_ROLES } from '../constants/roles.js';
export const createProjectSchema = z.object({
name: z.string().min(1).max(255),
description: z.string().max(2000).optional(),
artist: z.string().max(255).nullable().optional(),
});
export const updateProjectSchema = z.object({
name: z.string().min(1).max(255).optional(),
description: z.string().max(2000).optional(),
artist: z.string().max(255).nullable().optional(),
coverImageUrl: z.string().nullable().optional(),
});