major updates to device and links management in admin

This commit is contained in:
user
2026-03-28 15:34:03 +02:00
parent e8c5986df6
commit 6639bcd799
32 changed files with 3304 additions and 496 deletions

View File

@@ -47,10 +47,13 @@ export class DeviceController {
*/
allocate(fctx: FlowExecCtx, id: number): ResultAsync<Device, Err> {
return this.repo.getById(fctx, id).andThen((dev) => {
if (dev.status !== DeviceStatus.ONLINE) {
if (dev.status !== DeviceStatus.ONLINE || dev.inUse) {
return errAsync(deviceErrors.deviceNotAvailable(fctx, id));
}
return this.repo.setStatus(fctx, id, DeviceStatus.BUSY);
return this.repo.update(fctx, id, {
status: DeviceStatus.BUSY,
inUse: true,
});
});
}
@@ -58,7 +61,10 @@ export class DeviceController {
* 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);
return this.repo.update(fctx, id, {
status: DeviceStatus.ONLINE,
inUse: false,
});
}
}

View File

@@ -16,9 +16,10 @@ export const deviceSchema = v.object({
version: v.string(),
status: deviceStatusSchema,
isActive: v.boolean(),
containerId: v.nullable(v.string()),
inUse: v.boolean(),
containerId: v.string(),
host: v.string(),
wsPort: v.nullable(v.string()),
wsPort: v.string(),
createdAt: v.date(),
updatedAt: v.date(),
});
@@ -28,8 +29,8 @@ export const createDeviceSchema = v.object({
title: v.pipe(v.string(), v.minLength(1)),
version: v.pipe(v.string(), v.minLength(1)),
host: v.pipe(v.string(), v.minLength(1)),
containerId: v.optional(v.string()),
wsPort: v.optional(v.string()),
containerId: v.pipe(v.string(), v.minLength(1)),
wsPort: v.pipe(v.string(), v.minLength(1)),
isActive: v.optional(v.boolean()),
});
export type CreateDevice = v.InferOutput<typeof createDeviceSchema>;
@@ -39,9 +40,10 @@ export const updateDeviceSchema = v.partial(
title: v.string(),
version: v.string(),
host: v.string(),
containerId: v.nullable(v.string()),
wsPort: v.nullable(v.string()),
containerId: v.string(),
wsPort: v.string(),
isActive: v.boolean(),
inUse: v.boolean(),
status: deviceStatusSchema,
}),
);

View File

@@ -60,10 +60,11 @@ export class DeviceRepository {
title: data.title,
version: data.version,
host: data.host,
containerId: data.containerId ?? null,
wsPort: data.wsPort ?? null,
containerId: data.containerId,
wsPort: data.wsPort,
status: DeviceStatus.OFFLINE,
isActive: data.isActive ?? false,
inUse: false,
createdAt: new Date(),
updatedAt: new Date(),
})

View File

@@ -15,6 +15,8 @@ export const linkSchema = v.object({
id: v.number(),
token: v.string(),
status: linkStatusSchema,
appName: v.string(),
appPackage: v.string(),
linkedDeviceId: v.nullable(v.number()),
expiresAt: v.nullable(v.date()),
lastAccessedAt: v.nullable(v.date()),
@@ -31,7 +33,9 @@ export type LinkWithDevice = v.InferOutput<typeof linkWithDeviceSchema>;
export const createLinkSchema = v.object({
token: v.pipe(v.string(), v.minLength(1)),
linkedDeviceId: v.optional(v.nullable(v.number())),
appName: v.pipe(v.string(), v.minLength(1)),
appPackage: v.pipe(v.string(), v.minLength(1)),
linkedDeviceId: v.number(),
expiresAt: v.optional(v.nullable(v.date())),
});
export type CreateLink = v.InferOutput<typeof createLinkSchema>;
@@ -39,6 +43,8 @@ export type CreateLink = v.InferOutput<typeof createLinkSchema>;
export const updateLinkSchema = v.partial(
v.object({
status: linkStatusSchema,
appName: v.string(),
appPackage: v.string(),
linkedDeviceId: v.nullable(v.number()),
expiresAt: v.nullable(v.date()),
lastAccessedAt: v.nullable(v.date()),

View File

@@ -81,6 +81,8 @@ export class LinkRepository {
.values({
token: data.token,
status: "active",
appName: data.appName,
appPackage: data.appPackage,
linkedDeviceId: data.linkedDeviceId ?? null,
expiresAt: data.expiresAt ?? null,
createdAt: new Date(),