Files
illusory-iotam/packages/logic/domains/device/controller.ts

68 lines
2.1 KiB
TypeScript

import { errAsync, ResultAsync } from "neverthrow";
import { db } from "@pkg/db";
import { type Err } from "@pkg/result";
import { FlowExecCtx } from "@core/flow.execution.context";
import { CreateDevice, Device, DeviceStatus, UpdateDevice } from "./data";
import { DeviceRepository } from "./repository";
import { deviceErrors } from "./errors";
export class DeviceController {
constructor(private repo: DeviceRepository) {}
list(fctx: FlowExecCtx): ResultAsync<Device[], Err> {
return this.repo.list(fctx);
}
getById(fctx: FlowExecCtx, id: number): ResultAsync<Device, Err> {
return this.repo.getById(fctx, id);
}
create(fctx: FlowExecCtx, data: CreateDevice): ResultAsync<Device, Err> {
return this.repo.create(fctx, data);
}
update(
fctx: FlowExecCtx,
id: number,
data: UpdateDevice,
): ResultAsync<Device, Err> {
return this.repo.update(fctx, id, data);
}
delete(fctx: FlowExecCtx, id: number): ResultAsync<boolean, Err> {
return this.repo.delete(fctx, id);
}
setStatus(
fctx: FlowExecCtx,
id: number,
status: DeviceStatus,
): ResultAsync<Device, Err> {
return this.repo.setStatus(fctx, id, status);
}
/**
* Mark a device as busy for an incoming session.
* Only succeeds if the device is currently online.
*/
allocate(fctx: FlowExecCtx, id: number): ResultAsync<Device, Err> {
return this.repo.getById(fctx, id).andThen((dev) => {
if (dev.status !== DeviceStatus.ONLINE) {
return errAsync(deviceErrors.deviceNotAvailable(fctx, id));
}
return this.repo.setStatus(fctx, id, DeviceStatus.BUSY);
});
}
/**
* Release a device back to online after a session ends.
*/
release(fctx: FlowExecCtx, id: number): ResultAsync<Device, Err> {
return this.repo.setStatus(fctx, id, DeviceStatus.ONLINE);
}
}
export function getDeviceController(): DeviceController {
return new DeviceController(new DeviceRepository(db));
}