v1.6.5: fix attendance unique constraint, schema sync, seed script

- Change attendance idx_attendance_user_date from unique to index (allow multiple shifts per day)
- Reset migrations to single baseline init migration
- Add seed script with admin user (admin/admin)
- Update CLAUDE.md with migration workflow documentation
- Various frontend fixes (queries, pages, hooks)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-05-17 16:21:34 +02:00
parent 1db5060c42
commit cd6d3daf43
75 changed files with 1748 additions and 1169 deletions

View File

@@ -1,5 +1,5 @@
import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { userListOptions } from "../lib/queries/users";
import { useAlert } from "../context/AlertContext";
import { useAuth } from "../context/AuthContext";
@@ -14,11 +14,6 @@ import { Skeleton } from "boneyard-js/react";
import AttendanceCreateFixture from "../fixtures/AttendanceCreateFixture";
const API_BASE = "/api/admin";
interface User {
id: number | string;
name: string;
}
interface CreateForm {
user_id: string;
shift_date: string;
@@ -39,8 +34,12 @@ export default function AttendanceCreate() {
const alert = useAlert();
const { hasPermission } = useAuth();
const navigate = useNavigate();
const queryClient = useQueryClient();
const { data: usersData, isPending: loading } = useQuery(userListOptions());
const users = (usersData as unknown as User[] | undefined) ?? [];
const users = (usersData ?? []).map((u) => ({
id: u.id,
name: `${u.first_name} ${u.last_name}`.trim() || u.username,
}));
const [submitting, setSubmitting] = useState(false);
const [form, setForm] = useState<CreateForm>(() => {
@@ -83,6 +82,7 @@ export default function AttendanceCreate() {
if (result.success) {
alert.success(result.message);
await queryClient.invalidateQueries({ queryKey: ["attendance"] });
navigate(`/attendance/admin?month=${form.shift_date.substring(0, 7)}`);
} else {
alert.error(result.error);
@@ -107,7 +107,7 @@ export default function AttendanceCreate() {
const isWorkType = form.leave_type === "work";
if (!hasPermission("attendance.admin")) return <Forbidden />;
if (!hasPermission("attendance.manage")) return <Forbidden />;
return (
<Skeleton