// services/drone.ts // Copyright (C) 2026 Robert Colbert // 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 { this.log.info("service started"); } async stop(): Promise { this.log.info("service stopped"); } async register( user: IUser, definition: IDroneDefinition, ): Promise { 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 { this.log.info("unregistering drone", { hostname: registration.hostname }); return this.setStatus(registration, DroneStatus.Offline); } async getById(registrationId: Types.ObjectId): Promise { 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 { 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();