- Add employeeNumber and pinHash fields to users table - POST /auth/pin-login: takes combined code (4-digit employee# + 4-digit PIN) - POST /auth/set-pin: employee sets their own PIN (requires full auth) - DELETE /auth/pin: remove PIN - Lock screen with numpad, auto-submits on 8 digits, visual dot separator - POS uses its own auth token separate from admin session - Admin "POS" link clears admin session before navigating - /pos route has no auth guard — lock screen is the auth - API client uses POS token when available, admin token otherwise - Auto-lock timer reads pos_lock_timeout from app_config (default 15 min) - Lock button in POS top bar, shows current cashier name Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
30 lines
963 B
TypeScript
30 lines
963 B
TypeScript
import { z } from 'zod'
|
|
|
|
export const UserRole = z.enum(['admin', 'manager', 'staff', 'technician', 'instructor'])
|
|
export type UserRole = z.infer<typeof UserRole>
|
|
|
|
export const RegisterSchema = z.object({
|
|
email: z.string().email(),
|
|
password: z.string().min(12).max(128),
|
|
firstName: z.string().min(1).max(100),
|
|
lastName: z.string().min(1).max(100),
|
|
role: UserRole.default('staff'),
|
|
})
|
|
export type RegisterInput = z.infer<typeof RegisterSchema>
|
|
|
|
export const LoginSchema = z.object({
|
|
email: z.string().email(),
|
|
password: z.string().min(1),
|
|
})
|
|
export type LoginInput = z.infer<typeof LoginSchema>
|
|
|
|
export const PinLoginSchema = z.object({
|
|
code: z.string().min(8).max(10).regex(/^\d+$/, 'Code must be digits only'),
|
|
})
|
|
export type PinLoginInput = z.infer<typeof PinLoginSchema>
|
|
|
|
export const SetPinSchema = z.object({
|
|
pin: z.string().min(4).max(6).regex(/^\d+$/, 'PIN must be digits only'),
|
|
})
|
|
export type SetPinInput = z.infer<typeof SetPinSchema>
|