mirror of
https://github.com/Sea-Haven-Industries/seahaven-door-unlock-api.git
synced 2026-09-30 03:43:11 +00:00
Some checks failed
Deploy / deploy (push) Has been cancelled
* feat(3cx): sync office department BLFs via XAPI Keep unlock and lockdown keys in the templates and write colleague plus shared-parking BLFs per extension so phones skip their own line. * fix(3cx): preserve parking BLF IDs and fail the job on PATCH errors
80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
export type TemplateId =
|
|
| "t54w-door-unlock"
|
|
| "t54w-door-unlock-with-sp"
|
|
| "t58w-door-unlock";
|
|
|
|
export interface SharedParkingSlot {
|
|
readonly blfNo: number;
|
|
readonly value: string;
|
|
}
|
|
|
|
export interface SlotContract {
|
|
readonly reserved: readonly number[];
|
|
readonly sharedParking: readonly SharedParkingSlot[];
|
|
readonly ownLine: number;
|
|
readonly managedStart: number;
|
|
readonly managedEnd: number;
|
|
}
|
|
|
|
export const SLOT_CONTRACT: Record<TemplateId, SlotContract> = {
|
|
"t54w-door-unlock": {
|
|
reserved: [2],
|
|
sharedParking: [],
|
|
ownLine: 1,
|
|
managedStart: 3,
|
|
managedEnd: 12,
|
|
},
|
|
"t54w-door-unlock-with-sp": {
|
|
reserved: [2],
|
|
sharedParking: [
|
|
{ blfNo: 3, value: "SP1" },
|
|
{ blfNo: 4, value: "SP2" },
|
|
{ blfNo: 5, value: "SP3" },
|
|
],
|
|
ownLine: 1,
|
|
managedStart: 6,
|
|
managedEnd: 15,
|
|
},
|
|
"t58w-door-unlock": {
|
|
reserved: [2, 3, 4],
|
|
sharedParking: [],
|
|
ownLine: 1,
|
|
managedStart: 5,
|
|
managedEnd: 14,
|
|
},
|
|
};
|
|
|
|
const TEMPLATE_MATCHERS: { id: TemplateId; needle: string }[] = [
|
|
{ id: "t54w-door-unlock-with-sp", needle: "yealinkT54W-door-unlock-with-sp" },
|
|
{ id: "t54w-door-unlock", needle: "yealinkT54W-door-unlock" },
|
|
{ id: "t58w-door-unlock", needle: "yealinkT58W-door-unlock" },
|
|
];
|
|
|
|
export function resolveTemplateId(...candidates: Array<string | undefined | null>): TemplateId | undefined {
|
|
const haystack = candidates.filter(Boolean).join(" ");
|
|
if (!haystack) {
|
|
return undefined;
|
|
}
|
|
for (const matcher of TEMPLATE_MATCHERS) {
|
|
if (haystack.includes(matcher.needle)) {
|
|
return matcher.id;
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
export function isManagedSlot(contract: SlotContract, blfNo: number): boolean {
|
|
return blfNo >= contract.managedStart && blfNo <= contract.managedEnd;
|
|
}
|
|
|
|
export function isReservedSlot(contract: SlotContract, blfNo: number): boolean {
|
|
return contract.reserved.includes(blfNo);
|
|
}
|
|
|
|
export function isSharedParkingSlot(contract: SlotContract, blfNo: number): boolean {
|
|
return contract.sharedParking.some((slot) => slot.blfNo === blfNo);
|
|
}
|
|
|
|
export function managedSlotCount(contract: SlotContract): number {
|
|
return contract.managedEnd - contract.managedStart + 1;
|
|
}
|