portail-associations/server/logisticsGroup.ts

82 lines
2.4 KiB
TypeScript

import type { User } from "../drizzle/schema";
import * as db from "./db";
export const LOGISTICS_GROUP_SETTING_KEY = "system.logistics.group";
export type LogisticsGroupSettings = {
label: string;
memberUserIds: number[];
updatedAt: string | null;
};
const defaultLogisticsGroup: LogisticsGroupSettings = {
label: "Groupe interne matériel CCDS - logistique et contrôle",
memberUserIds: [],
updatedAt: null,
};
function sanitizeMemberUserIds(value: unknown) {
if (!Array.isArray(value)) return [];
return Array.from(
new Set(
value
.map((entry) => Number(entry))
.filter((entry) => Number.isInteger(entry) && entry > 0)
)
);
}
export async function getLogisticsGroupSettings(): Promise<LogisticsGroupSettings> {
const storedValue = await db.getPortalSetting(LOGISTICS_GROUP_SETTING_KEY);
if (!storedValue) return defaultLogisticsGroup;
try {
const parsed = JSON.parse(storedValue) as Partial<LogisticsGroupSettings>;
return {
label: typeof parsed.label === "string" && parsed.label.trim()
? parsed.label.trim()
: defaultLogisticsGroup.label,
memberUserIds: sanitizeMemberUserIds(parsed.memberUserIds),
updatedAt: typeof parsed.updatedAt === "string" ? parsed.updatedAt : null,
};
} catch {
return defaultLogisticsGroup;
}
}
export async function saveLogisticsGroupSettings(input: {
label?: string;
memberUserIds?: number[];
}) {
const nextValue: LogisticsGroupSettings = {
label: input.label?.trim() || defaultLogisticsGroup.label,
memberUserIds: sanitizeMemberUserIds(input.memberUserIds),
updatedAt: new Date().toISOString(),
};
await db.setPortalSetting(
LOGISTICS_GROUP_SETTING_KEY,
JSON.stringify(nextValue),
"Groupe interne à accès limité autorisé à traiter les demandes de matériel CCDS, piloter les restitutions et contrôler les retours"
);
return nextValue;
}
export async function userHasLogisticsAccess(user: Pick<User, "id" | "role" | "canManageLogistics">) {
if (user.role === "super_admin" || user.canManageLogistics) {
return true;
}
const group = await getLogisticsGroupSettings();
return group.memberUserIds.includes(user.id);
}
export async function withEffectiveLogisticsAccess<TUser extends User | null>(user: TUser): Promise<TUser> {
if (!user) return user;
const effectiveAccess = await userHasLogisticsAccess(user);
return {
...user,
canManageLogistics: effectiveAccess,
} as TUser;
}