UNPKG

@adventurelabs/scout-core

Version:

Core utilities and helpers for Adventure Labs Scout applications

330 lines (329 loc) 11.3 kB
import { IWebResponse } from "../types/requests"; /** * Retrieves all active parts for a specific device * @param client - Supabase client instance * @param device_id - ID of the device to get parts for */ export async function get_parts_by_device_id(client, device_id) { const { data, error } = await client .from("parts") .select("*") .eq("device_id", device_id) .is("deleted_at", null) .order("created_at", { ascending: false }); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error("No parts found for device").to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Retrieves a single active part by its ID * @param client - Supabase client instance * @param part_id - ID of the part to retrieve */ export async function get_part_by_id(client, part_id) { const { data, error } = await client .from("parts") .select("*") .eq("id", part_id) .is("deleted_at", null) .single(); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error("Part not found").to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Retrieves all active parts with a specific serial number * @param client - Supabase client instance * @param serial_number - Serial number to search for */ export async function get_parts_by_serial_number(client, serial_number) { const { data, error } = await client .from("parts") .select("*") .eq("serial_number", serial_number) .is("deleted_at", null) .order("created_at", { ascending: false }); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error(`No parts found with serial number: ${serial_number}`).to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Retrieves all active parts with a specific product number * @param client - Supabase client instance * @param product_number - Product number to search for */ export async function get_parts_by_product_number(client, product_number) { const { data, error } = await client .from("parts") .select("*") .eq("product_number", product_number) .is("deleted_at", null) .order("created_at", { ascending: false }); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error(`No parts found with product number: ${product_number}`).to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Retrieves all active parts with a specific status * @param client - Supabase client instance * @param status - Component status to filter by */ export async function get_parts_by_status(client, status) { const { data, error } = await client .from("parts") .select("*") .eq("status", status) .is("deleted_at", null) .order("created_at", { ascending: false }); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error(`No parts found with status: ${status}`).to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Creates a new part with validation * @param client - Supabase client instance * @param newPart - Part data to create */ export async function create_part(client, newPart) { // Validate required fields if (!newPart.device_id) { return IWebResponse.error("Device ID is required").to_compatible(); } if (!newPart.serial_number) { return IWebResponse.error("Serial number is required").to_compatible(); } if (!newPart.product_number) { return IWebResponse.error("Product number is required").to_compatible(); } const { data, error } = await client .from("parts") .insert([newPart]) .select("*") .single(); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error("Failed to create part").to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Updates an existing part * @param client - Supabase client instance * @param part_id - ID of the part to update * @param updatedPart - Partial part data to update */ export async function update_part(client, part_id, updatedPart) { // Remove fields that shouldn't be updated const updateData = { ...updatedPart }; delete updateData.id; delete updateData.created_at; const { data, error } = await client .from("parts") .update(updateData) .eq("id", part_id) .select("*") .single(); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error("Part not found or update failed").to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Soft deletes a part by setting deleted_at timestamp * @param client - Supabase client instance * @param part_id - ID of the part to delete */ export async function delete_part(client, part_id) { // Soft delete by setting deleted_at timestamp const { data, error } = await client .from("parts") .update({ deleted_at: new Date().toISOString() }) .eq("id", part_id) .is("deleted_at", null) .select("*") .single(); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error("Part not found or deletion failed").to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Updates the status of a specific part * @param client - Supabase client instance * @param part_id - ID of the part to update * @param status - New status to set */ export async function update_part_status(client, part_id, status) { const { data, error } = await client .from("parts") .update({ status }) .eq("id", part_id) .is("deleted_at", null) .select("*") .single(); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error("Part not found or status update failed").to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Retrieves all active parts associated with a certificate * @param client - Supabase client instance * @param certificate_id - ID of the certificate to search for */ export async function get_parts_by_certificate_id(client, certificate_id) { const { data, error } = await client .from("parts") .select("*") .eq("certificate_id", certificate_id) .is("deleted_at", null) .order("created_at", { ascending: false }); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error(`No parts found with certificate ID: ${certificate_id}`).to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Retrieves all active parts for devices in a specific herd * @param client - Supabase client instance * @param herd_id - ID of the herd to get parts for */ export async function get_parts_by_herd_id(client, herd_id) { const { data, error } = await client .from("parts") .select(` *, devices!parts_device_id_fkey(herd_id) `) .eq("devices.herd_id", herd_id) .is("deleted_at", null) .order("created_at", { ascending: false }); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error(`No parts found for herd: ${herd_id}`).to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Restores a soft-deleted part by clearing deleted_at timestamp * @param client - Supabase client instance * @param part_id - ID of the part to restore */ export async function restore_part(client, part_id) { // Restore soft deleted part by setting deleted_at to null const { data, error } = await client .from("parts") .update({ deleted_at: null }) .eq("id", part_id) .not("deleted_at", "is", null) .select("*") .single(); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error("Part not found or restore failed").to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Permanently deletes a soft-deleted part from database * @param client - Supabase client instance * @param part_id - ID of the part to permanently delete */ export async function hard_delete_part(client, part_id) { // Permanently delete the part (only use for already soft-deleted parts) const { data, error } = await client .from("parts") .delete() .eq("id", part_id) .not("deleted_at", "is", null) .select("*") .single(); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error("Part not found or permanent deletion failed").to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Retrieves all soft-deleted parts for a specific device * @param client - Supabase client instance * @param device_id - ID of the device to get deleted parts for */ export async function get_deleted_parts_by_device_id(client, device_id) { const { data, error } = await client .from("parts") .select("*") .eq("device_id", device_id) .not("deleted_at", "is", null) .order("deleted_at", { ascending: false }); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error("No deleted parts found for device").to_compatible(); } return IWebResponse.success(data).to_compatible(); } /** * Retrieves a part by its composite unique constraint (product + serial) * @param client - Supabase client instance * @param product_number - Product number to search for * @param serial_number - Serial number to search for */ export async function get_parts_by_product_and_serial(client, product_number, serial_number) { // Get part by the composite unique constraint const { data, error } = await client .from("parts") .select("*") .eq("product_number", product_number) .eq("serial_number", serial_number) .is("deleted_at", null) .single(); if (error) { return IWebResponse.error(error.message).to_compatible(); } if (!data) { return IWebResponse.error(`No part found with product number: ${product_number} and serial number: ${serial_number}`).to_compatible(); } return IWebResponse.success(data).to_compatible(); }