Implement admin users and roles management
- Add user CRUD: list, create (via Better Auth), update role/status, remove from port - Add role CRUD: create, update permissions, delete with system role protection - Full permissions matrix UI with accordion groups and per-action checkboxes - Validators, services, API routes, and UI components following existing patterns Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
35
src/lib/validators/roles.ts
Normal file
35
src/lib/validators/roles.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
const permissionGroupSchema = z.record(z.string(), z.boolean());
|
||||
|
||||
const rolePermissionsSchema = z.object({
|
||||
clients: permissionGroupSchema,
|
||||
interests: permissionGroupSchema,
|
||||
berths: permissionGroupSchema,
|
||||
documents: permissionGroupSchema,
|
||||
expenses: permissionGroupSchema,
|
||||
invoices: permissionGroupSchema,
|
||||
files: permissionGroupSchema,
|
||||
email: permissionGroupSchema,
|
||||
reminders: permissionGroupSchema,
|
||||
calendar: permissionGroupSchema,
|
||||
reports: permissionGroupSchema,
|
||||
document_templates: permissionGroupSchema,
|
||||
admin: permissionGroupSchema,
|
||||
});
|
||||
|
||||
export const createRoleSchema = z.object({
|
||||
name: z.string().min(1).max(100),
|
||||
description: z.string().max(500).optional(),
|
||||
permissions: rolePermissionsSchema,
|
||||
});
|
||||
|
||||
export type CreateRoleInput = z.infer<typeof createRoleSchema>;
|
||||
|
||||
export const updateRoleSchema = z.object({
|
||||
name: z.string().min(1).max(100).optional(),
|
||||
description: z.string().max(500).nullable().optional(),
|
||||
permissions: rolePermissionsSchema.optional(),
|
||||
});
|
||||
|
||||
export type UpdateRoleInput = z.infer<typeof updateRoleSchema>;
|
||||
27
src/lib/validators/users.ts
Normal file
27
src/lib/validators/users.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const createUserSchema = z.object({
|
||||
email: z.string().email(),
|
||||
name: z.string().min(1).max(200),
|
||||
password: z.string().min(12),
|
||||
displayName: z.string().min(1).max(200),
|
||||
phone: z.string().optional(),
|
||||
roleId: z.string().uuid(),
|
||||
});
|
||||
|
||||
export type CreateUserInput = z.infer<typeof createUserSchema>;
|
||||
|
||||
export const updateUserSchema = z.object({
|
||||
displayName: z.string().min(1).max(200).optional(),
|
||||
phone: z.string().nullable().optional(),
|
||||
isActive: z.boolean().optional(),
|
||||
roleId: z.string().uuid().optional(),
|
||||
});
|
||||
|
||||
export type UpdateUserInput = z.infer<typeof updateUserSchema>;
|
||||
|
||||
export const resetPasswordSchema = z.object({
|
||||
newPassword: z.string().min(12),
|
||||
});
|
||||
|
||||
export type ResetPasswordInput = z.infer<typeof resetPasswordSchema>;
|
||||
Reference in New Issue
Block a user