gadget/gadget-code/src/services/drone.ts
2026-04-28 09:20:37 -04:00

108 lines
2.7 KiB
TypeScript

// services/drone.ts
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
// All Rights Reserved
import DroneRegistration, {
DroneStatus,
IDroneRegistration,
} from "@/models/drone-registration.js";
import { DtpService } from "../lib/service.js";
import { IUser } from "@/models/user.js";
import { PopulateOptions, Types } from "mongoose";
export interface IDroneDefinition {
hostname: string;
}
class DroneService extends DtpService {
private populateDroneRegistration: PopulateOptions[];
constructor() {
super();
this.populateDroneRegistration = [
{
path: "user",
select: "-passwordSalt -password",
},
];
}
get name(): string {
return "DroneService";
}
get slug(): string {
return "svc:drone";
}
async start(): Promise<void> {
this.log.info("service started");
}
async stop(): Promise<void> {
this.log.info("service stopped");
}
async register(
user: IUser,
definition: IDroneDefinition,
): Promise<IDroneRegistration> {
const NOW = new Date();
let registration = new DroneRegistration();
registration.createdAt = NOW;
registration.updatedAt = NOW;
registration.user = user._id;
registration.hostname = definition.hostname;
registration.status = DroneStatus.Starting;
this.log.info("registering drone", { hostname: registration.hostname });
await registration.save();
return registration.populate(this.populateDroneRegistration);
}
async unregister(
registration: IDroneRegistration,
): Promise<IDroneRegistration> {
this.log.info("unregistering drone", { hostname: registration.hostname });
return this.setStatus(registration, DroneStatus.Offline);
}
async getById(registrationId: Types.ObjectId): Promise<IDroneRegistration> {
const registration = await DroneRegistration.findById(
registrationId,
).populate(this.populateDroneRegistration);
if (!registration) {
const error = new Error("drone registration not found");
error.statusCode = 404;
throw error;
}
return registration;
}
async setStatus(
registration: IDroneRegistration,
status: DroneStatus,
): Promise<IDroneRegistration> {
this.log.info("setting drone status", {
hostname: registration.hostname,
old: registration.status,
new: status,
});
const newRegistration = await DroneRegistration.findOneAndUpdate(
{ _id: registration._id },
{ $set: { status } },
{ new: true, populate: this.populateDroneRegistration },
);
if (!newRegistration) {
const error = new Error("drone registration has been removed");
error.statusCode = 404;
throw error;
}
return newRegistration;
}
}
export default new DroneService();