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

@@ -10,8 +10,14 @@ import {
tripListOptions,
tripVehiclesOptions,
tripUsersOptions,
type BackendTrip,
type TripVehicle,
type TripUser,
} from "../lib/queries/trips";
import { companySettingsOptions } from "../lib/queries/settings";
import {
companySettingsOptions,
type CompanySettingsData,
} from "../lib/queries/settings";
import AdminDatePicker from "../components/AdminDatePicker";
import FormField from "../components/FormField";
@@ -23,17 +29,6 @@ import { Skeleton } from "boneyard-js/react";
import TripsAdminFixture from "../fixtures/TripsAdminFixture";
const API_BASE = "/api/admin";
interface Vehicle {
id: number | string;
spz: string;
name: string;
}
interface UserShort {
id: number | string;
name: string;
}
interface Trip {
id: number;
vehicle_id: number | string;
@@ -49,22 +44,6 @@ interface Trip {
driver_name: string;
}
interface BackendTrip {
id: number;
vehicle_id: number;
user_id: number;
trip_date: string;
start_km: number;
end_km: number;
distance: number | null;
route_from: string;
route_to: string;
is_business: boolean;
notes: string | null;
users: { id: number; first_name: string; last_name: string };
vehicles: { id: number; name: string; spz: string };
}
interface EditForm {
vehicle_id: string;
trip_date: string;
@@ -127,15 +106,13 @@ export default function TripsAdmin() {
}>({ show: false, trip: null });
const { data: vehiclesData = [] } = useQuery(tripVehiclesOptions());
const vehicles = vehiclesData as Vehicle[];
const vehicles = vehiclesData;
const { data: tripUsersData = [] } = useQuery(tripUsersOptions());
const tripUsers = tripUsersData as UserShort[];
const tripUsers = tripUsersData;
const { data: companySettings } = useQuery(companySettingsOptions());
const companyName =
((companySettings as Record<string, unknown> | undefined)
?.company_name as string) ?? "";
const companyName = companySettings?.company_name ?? "";
const { data: tripsData, isPending } = useQuery(
tripListOptions({
@@ -146,11 +123,11 @@ export default function TripsAdmin() {
perPage: 100,
}),
);
const trips = ((tripsData ?? []) as BackendTrip[]).map(mapTrip);
const trips = (tripsData ?? []).map(mapTrip);
useModalLock(showEditModal);
if (!hasPermission("trips.admin")) return <Forbidden />;
if (!hasPermission("trips.manage")) return <Forbidden />;
const openEditModal = (trip: Trip) => {
setEditingTrip(trip);