@adventurelabs/scout-core 1.4.43 → 1.4.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export * from "./jobs";
2
+ export * from "./tasks";
@@ -0,0 +1,2 @@
1
+ export * from "./jobs";
2
+ export * from "./tasks";
@@ -0,0 +1,10 @@
1
+ import { SupabaseClient } from "@supabase/supabase-js";
2
+ import { Database } from "../../types/supabase";
3
+ import { AnalysisWorkStatus, IAnalysisJob } from "../../types/db";
4
+ import { IWebResponseCompatible } from "../../types/requests";
5
+ export type GetAnalysisJobsOptions = {
6
+ limit?: number;
7
+ status?: AnalysisWorkStatus;
8
+ };
9
+ export declare function get_analysis_jobs(client: SupabaseClient<Database>, options?: GetAnalysisJobsOptions): Promise<IWebResponseCompatible<IAnalysisJob[]>>;
10
+ export declare function get_analysis_job_by_id(client: SupabaseClient<Database>, job_id: number): Promise<IWebResponseCompatible<IAnalysisJob | null>>;
@@ -0,0 +1,31 @@
1
+ import { IWebResponse } from "../../types/requests";
2
+ export async function get_analysis_jobs(client, options) {
3
+ const limit = options?.limit ?? 100;
4
+ let query = client
5
+ .from("analysis_jobs")
6
+ .select("*")
7
+ .order("timestamp_requested", { ascending: false })
8
+ .limit(limit);
9
+ if (options?.status != null) {
10
+ query = query.eq("status", options.status);
11
+ }
12
+ const { data, error } = await query;
13
+ if (error) {
14
+ return IWebResponse.error(error.message).to_compatible();
15
+ }
16
+ return IWebResponse.success(data ?? []).to_compatible();
17
+ }
18
+ export async function get_analysis_job_by_id(client, job_id) {
19
+ const { data, error } = await client
20
+ .from("analysis_jobs")
21
+ .select("*")
22
+ .eq("id", job_id)
23
+ .single();
24
+ if (error) {
25
+ return IWebResponse.error(error.message).to_compatible();
26
+ }
27
+ if (!data) {
28
+ return IWebResponse.error("Analysis job not found").to_compatible();
29
+ }
30
+ return IWebResponse.success(data).to_compatible();
31
+ }
@@ -0,0 +1,14 @@
1
+ import { SupabaseClient } from "@supabase/supabase-js";
2
+ import { Database } from "../../types/supabase";
3
+ import { AnalysisWorkStatus, IAnalysisTask } from "../../types/db";
4
+ import { IWebResponseCompatible } from "../../types/requests";
5
+ export type GetAnalysisTasksOptions = {
6
+ limit?: number;
7
+ job_id?: number;
8
+ status?: AnalysisWorkStatus;
9
+ };
10
+ export declare function get_analysis_tasks(client: SupabaseClient<Database>, options?: GetAnalysisTasksOptions): Promise<IWebResponseCompatible<IAnalysisTask[]>>;
11
+ export declare function get_analysis_tasks_for_job(client: SupabaseClient<Database>, job_id: number, options?: {
12
+ limit?: number;
13
+ }): Promise<IWebResponseCompatible<IAnalysisTask[]>>;
14
+ export declare function get_analysis_task_by_id(client: SupabaseClient<Database>, task_id: number): Promise<IWebResponseCompatible<IAnalysisTask | null>>;
@@ -0,0 +1,40 @@
1
+ import { IWebResponse } from "../../types/requests";
2
+ export async function get_analysis_tasks(client, options) {
3
+ const limit = options?.limit ?? 500;
4
+ let query = client
5
+ .from("analysis_tasks")
6
+ .select("*")
7
+ .order("id", { ascending: false })
8
+ .limit(limit);
9
+ if (options?.job_id != null) {
10
+ query = query.eq("job_id", options.job_id);
11
+ }
12
+ if (options?.status != null) {
13
+ query = query.eq("status", options.status);
14
+ }
15
+ const { data, error } = await query;
16
+ if (error) {
17
+ return IWebResponse.error(error.message).to_compatible();
18
+ }
19
+ return IWebResponse.success(data ?? []).to_compatible();
20
+ }
21
+ export async function get_analysis_tasks_for_job(client, job_id, options) {
22
+ return get_analysis_tasks(client, {
23
+ job_id,
24
+ limit: options?.limit ?? 500,
25
+ });
26
+ }
27
+ export async function get_analysis_task_by_id(client, task_id) {
28
+ const { data, error } = await client
29
+ .from("analysis_tasks")
30
+ .select("*")
31
+ .eq("id", task_id)
32
+ .single();
33
+ if (error) {
34
+ return IWebResponse.error(error.message).to_compatible();
35
+ }
36
+ if (!data) {
37
+ return IWebResponse.error("Analysis task not found").to_compatible();
38
+ }
39
+ return IWebResponse.success(data).to_compatible();
40
+ }
@@ -1,3 +1,4 @@
1
+ export * from "./analysis_usage";
1
2
  export * from "./auth";
2
3
  export * from "./bounding_boxes";
3
4
  export * from "./chat";
@@ -1,3 +1,4 @@
1
+ export * from "./analysis_usage";
1
2
  export * from "./auth";
2
3
  export * from "./bounding_boxes";
3
4
  export * from "./chat";
@@ -8,5 +8,5 @@ export { useScoutRealtimeSessions } from "./useScoutRealtimeSessions";
8
8
  export { useScoutRealtimePlans } from "./useScoutRealtimePlans";
9
9
  export { useScoutRealtimePins } from "./useScoutRealtimePins";
10
10
  export { useScoutRealtimeParts } from "./useScoutRealtimeParts";
11
- export { useInfiniteSessionsByHerd, useInfiniteSessionsByDevice, useInfiniteEventsByHerd, useInfiniteEventsByDevice, useInfiniteArtifactsByHerd, useInfiniteArtifactsByDevice, useInfiniteFeedByHerd, useInfiniteFeedByDevice, useIntersectionObserver, type UseInfiniteScrollOptions, } from "./useInfiniteQuery";
11
+ export { useInfiniteSessionsByHerd, useInfiniteSessionsByDevice, useInfiniteEventsByHerd, useInfiniteEventsByDevice, useInfiniteArtifactsByHerd, useInfiniteArtifactsByDevice, useInfiniteFeedByHerd, useInfiniteFeedByDevice, useInfiniteAnalysisJobs, useInfiniteAnalysisTasks, useIntersectionObserver, type UseInfiniteScrollOptions, type UseAnalysisJobsInfiniteOptions, type UseAnalysisTasksInfiniteOptions, } from "./useInfiniteQuery";
12
12
  export { useLoadingPerformance, useSessionSummariesByHerd, useHasSessionSummaries, } from "../store/hooks";
@@ -9,6 +9,6 @@ export { useScoutRealtimePlans } from "./useScoutRealtimePlans";
9
9
  export { useScoutRealtimePins } from "./useScoutRealtimePins";
10
10
  export { useScoutRealtimeParts } from "./useScoutRealtimeParts";
11
11
  // RTK Query infinite scroll hooks
12
- export { useInfiniteSessionsByHerd, useInfiniteSessionsByDevice, useInfiniteEventsByHerd, useInfiniteEventsByDevice, useInfiniteArtifactsByHerd, useInfiniteArtifactsByDevice, useInfiniteFeedByHerd, useInfiniteFeedByDevice, useIntersectionObserver, } from "./useInfiniteQuery";
12
+ export { useInfiniteSessionsByHerd, useInfiniteSessionsByDevice, useInfiniteEventsByHerd, useInfiniteEventsByDevice, useInfiniteArtifactsByHerd, useInfiniteArtifactsByDevice, useInfiniteFeedByHerd, useInfiniteFeedByDevice, useInfiniteAnalysisJobs, useInfiniteAnalysisTasks, useIntersectionObserver, } from "./useInfiniteQuery";
13
13
  // Session summaries and performance hooks
14
14
  export { useLoadingPerformance, useSessionSummariesByHerd, useHasSessionSummaries, } from "../store/hooks";
@@ -1,5 +1,5 @@
1
1
  import { SupabaseClient } from "@supabase/supabase-js";
2
- import { IArtifactWithMediaUrl, ISessionWithCoordinates, IEventAndTagsPrettyLocation, IFeedItem } from "../types/db";
2
+ import { IArtifactWithMediaUrl, ISessionWithCoordinates, IEventAndTagsPrettyLocation, IFeedItem, IAnalysisJob, IAnalysisTask, AnalysisWorkStatus } from "../types/db";
3
3
  export interface UseInfiniteScrollOptions {
4
4
  limit?: number;
5
5
  enabled?: boolean;
@@ -30,5 +30,20 @@ export declare const useInfiniteArtifactsByDevice: (deviceId: number, options: U
30
30
  /** useInfiniteFeedByHerd: logic matches useInfiniteFeedByHerdDummy verbatim; only the fetch is via API (RTK Query) instead of supabase.rpc. */
31
31
  export declare const useInfiniteFeedByHerd: (herdId: number, options: UseInfiniteScrollOptions) => InfiniteScrollData<IFeedItem>;
32
32
  export declare const useInfiniteFeedByDevice: (deviceId: number, options: UseInfiniteScrollOptions) => InfiniteScrollData<IFeedItem>;
33
+ export interface UseAnalysisJobsInfiniteOptions {
34
+ limit?: number;
35
+ enabled?: boolean;
36
+ supabase: SupabaseClient;
37
+ status?: AnalysisWorkStatus | null;
38
+ }
39
+ export declare const useInfiniteAnalysisJobs: (options: UseAnalysisJobsInfiniteOptions) => InfiniteScrollData<IAnalysisJob>;
40
+ export interface UseAnalysisTasksInfiniteOptions {
41
+ limit?: number;
42
+ enabled?: boolean;
43
+ supabase: SupabaseClient;
44
+ job_id?: number | null;
45
+ status?: AnalysisWorkStatus | null;
46
+ }
47
+ export declare const useInfiniteAnalysisTasks: (options: UseAnalysisTasksInfiniteOptions) => InfiniteScrollData<IAnalysisTask>;
33
48
  export declare const useIntersectionObserver: (callback: () => void, options?: IntersectionObserverInit) => import("react").Dispatch<import("react").SetStateAction<Element | null>>;
34
49
  export {};
@@ -1,5 +1,5 @@
1
1
  import { useState, useCallback, useMemo, useEffect, useRef } from "react";
2
- import { useGetSessionsInfiniteByHerdQuery, useGetSessionsInfiniteByDeviceQuery, useGetEventsInfiniteByHerdQuery, useGetEventsInfiniteByDeviceQuery, useGetArtifactsInfiniteByHerdQuery, useGetArtifactsInfiniteByDeviceQuery, useGetFeedInfiniteByHerdQuery, useGetFeedInfiniteByDeviceQuery, } from "../store/api";
2
+ import { useGetSessionsInfiniteByHerdQuery, useGetSessionsInfiniteByDeviceQuery, useGetEventsInfiniteByHerdQuery, useGetEventsInfiniteByDeviceQuery, useGetArtifactsInfiniteByHerdQuery, useGetArtifactsInfiniteByDeviceQuery, useGetFeedInfiniteByHerdQuery, useGetFeedInfiniteByDeviceQuery, useGetAnalysisJobsInfiniteQuery, useGetAnalysisTasksInfiniteQuery, } from "../store/api";
3
3
  function useInfiniteFiltersKey(options) {
4
4
  return useMemo(() => JSON.stringify({
5
5
  rangeStart: options.rangeStart ?? null,
@@ -814,6 +814,144 @@ export const useInfiniteFeedByDevice = (deviceId, options) => {
814
814
  error: currentQuery.error,
815
815
  };
816
816
  };
817
+ function useAnalysisJobsInfiniteFiltersKey(options) {
818
+ return useMemo(() => JSON.stringify({ status: options.status ?? null }), [options.status]);
819
+ }
820
+ export const useInfiniteAnalysisJobs = (options) => {
821
+ const [pages, setPages] = useState([]);
822
+ const [currentCursor, setCurrentCursor] = useState(null);
823
+ const infiniteFiltersKey = useAnalysisJobsInfiniteFiltersKey(options);
824
+ const prevInfiniteFiltersKeyRef = useRef(null);
825
+ const currentQuery = useGetAnalysisJobsInfiniteQuery({
826
+ limit: options.limit || 20,
827
+ cursor: currentCursor,
828
+ supabase: options.supabase,
829
+ status: options.status ?? null,
830
+ }, {
831
+ skip: !options.enabled,
832
+ });
833
+ useEffect(() => {
834
+ if (prevInfiniteFiltersKeyRef.current === null) {
835
+ prevInfiniteFiltersKeyRef.current = infiniteFiltersKey;
836
+ return;
837
+ }
838
+ if (prevInfiniteFiltersKeyRef.current !== infiniteFiltersKey) {
839
+ prevInfiniteFiltersKeyRef.current = infiniteFiltersKey;
840
+ setPages([]);
841
+ setCurrentCursor(null);
842
+ }
843
+ }, [infiniteFiltersKey]);
844
+ useEffect(() => {
845
+ if (currentQuery.data && !currentQuery.isLoading) {
846
+ setPages((prev) => {
847
+ const existingPage = prev.find((p) => (p.cursor === null && currentCursor === null) ||
848
+ (p.cursor != null &&
849
+ currentCursor != null &&
850
+ p.cursor.id === currentCursor.id));
851
+ if (!existingPage) {
852
+ return [
853
+ ...prev,
854
+ { cursor: currentCursor, data: currentQuery.data.jobs },
855
+ ];
856
+ }
857
+ return prev;
858
+ });
859
+ }
860
+ }, [currentQuery.data, currentQuery.isLoading, currentCursor]);
861
+ const loadMore = useCallback(() => {
862
+ if (currentQuery.data?.hasMore &&
863
+ currentQuery.data.nextCursor &&
864
+ !currentQuery.isLoading) {
865
+ setCurrentCursor(currentQuery.data.nextCursor);
866
+ }
867
+ }, [currentQuery.data, currentQuery.isLoading]);
868
+ const refetch = useCallback(() => {
869
+ setPages([]);
870
+ setCurrentCursor(null);
871
+ currentQuery.refetch();
872
+ }, [currentQuery]);
873
+ const allItems = useMemo(() => pages.flatMap((page) => page.data), [pages]);
874
+ return {
875
+ items: allItems,
876
+ isLoading: currentQuery.isLoading && pages.length === 0,
877
+ isLoadingMore: currentQuery.isLoading && pages.length > 0,
878
+ hasMore: currentQuery.data?.hasMore || false,
879
+ loadMore,
880
+ refetch,
881
+ error: currentQuery.error,
882
+ };
883
+ };
884
+ function useAnalysisTasksInfiniteFiltersKey(options) {
885
+ return useMemo(() => JSON.stringify({
886
+ job_id: options.job_id ?? null,
887
+ status: options.status ?? null,
888
+ }), [options.job_id, options.status]);
889
+ }
890
+ export const useInfiniteAnalysisTasks = (options) => {
891
+ const [pages, setPages] = useState([]);
892
+ const [currentCursor, setCurrentCursor] = useState(null);
893
+ const infiniteFiltersKey = useAnalysisTasksInfiniteFiltersKey(options);
894
+ const prevInfiniteFiltersKeyRef = useRef(null);
895
+ const currentQuery = useGetAnalysisTasksInfiniteQuery({
896
+ limit: options.limit || 20,
897
+ cursor: currentCursor,
898
+ supabase: options.supabase,
899
+ job_id: options.job_id ?? null,
900
+ status: options.status ?? null,
901
+ }, {
902
+ skip: !options.enabled,
903
+ });
904
+ useEffect(() => {
905
+ if (prevInfiniteFiltersKeyRef.current === null) {
906
+ prevInfiniteFiltersKeyRef.current = infiniteFiltersKey;
907
+ return;
908
+ }
909
+ if (prevInfiniteFiltersKeyRef.current !== infiniteFiltersKey) {
910
+ prevInfiniteFiltersKeyRef.current = infiniteFiltersKey;
911
+ setPages([]);
912
+ setCurrentCursor(null);
913
+ }
914
+ }, [infiniteFiltersKey]);
915
+ useEffect(() => {
916
+ if (currentQuery.data && !currentQuery.isLoading) {
917
+ setPages((prev) => {
918
+ const existingPage = prev.find((p) => (p.cursor === null && currentCursor === null) ||
919
+ (p.cursor != null &&
920
+ currentCursor != null &&
921
+ p.cursor.id === currentCursor.id));
922
+ if (!existingPage) {
923
+ return [
924
+ ...prev,
925
+ { cursor: currentCursor, data: currentQuery.data.tasks },
926
+ ];
927
+ }
928
+ return prev;
929
+ });
930
+ }
931
+ }, [currentQuery.data, currentQuery.isLoading, currentCursor]);
932
+ const loadMore = useCallback(() => {
933
+ if (currentQuery.data?.hasMore &&
934
+ currentQuery.data.nextCursor &&
935
+ !currentQuery.isLoading) {
936
+ setCurrentCursor(currentQuery.data.nextCursor);
937
+ }
938
+ }, [currentQuery.data, currentQuery.isLoading]);
939
+ const refetch = useCallback(() => {
940
+ setPages([]);
941
+ setCurrentCursor(null);
942
+ currentQuery.refetch();
943
+ }, [currentQuery]);
944
+ const allItems = useMemo(() => pages.flatMap((page) => page.data), [pages]);
945
+ return {
946
+ items: allItems,
947
+ isLoading: currentQuery.isLoading && pages.length === 0,
948
+ isLoadingMore: currentQuery.isLoading && pages.length > 0,
949
+ hasMore: currentQuery.data?.hasMore || false,
950
+ loadMore,
951
+ refetch,
952
+ error: currentQuery.error,
953
+ };
954
+ };
817
955
  // =====================================================
818
956
  // INTERSECTION OBSERVER HOOK FOR AUTO-LOADING
819
957
  // =====================================================
package/dist/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export * from "./types/supabase";
10
10
  export * from "./types/bounding_boxes";
11
11
  export * from "./types/events";
12
12
  export * from "./types/connectivity";
13
+ export * from "./helpers/analysis_usage";
13
14
  export * from "./helpers/artifacts";
14
15
  export * from "./helpers/auth";
15
16
  export * from "./helpers/bounding_boxes";
@@ -63,5 +64,5 @@ export * from "./supabase/middleware";
63
64
  export * from "./supabase/server";
64
65
  export * from "./api_keys/actions";
65
66
  export type { HerdModule, IHerdModule } from "./types/herd_module";
66
- export type { IDevice, IEvent, IUser, IHerd, IHerdPrettyLocation, IEventWithTags, IZoneWithActions, IUserAndRole, IApiKeyScout, ILayer, IHeartbeat, IProvider, IConnectivity, ISession, ISessionWithCoordinates, IConnectivityWithCoordinates, IObservation, ObservationInsert, ObservationUpdate, } from "./types/db";
67
+ export type { IDevice, IEvent, IUser, IHerd, IHerdPrettyLocation, IEventWithTags, IZoneWithActions, IUserAndRole, IApiKeyScout, ILayer, IHeartbeat, IProvider, IConnectivity, ISession, ISessionWithCoordinates, IConnectivityWithCoordinates, IObservation, ObservationInsert, ObservationUpdate, IAnalysisJob, IAnalysisTask, AnalysisWorkStatus, } from "./types/db";
67
68
  export { EnumSessionsVisibility } from "./types/events";
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ export * from "./types/bounding_boxes";
13
13
  export * from "./types/events";
14
14
  export * from "./types/connectivity";
15
15
  // Helpers
16
+ export * from "./helpers/analysis_usage";
16
17
  export * from "./helpers/artifacts";
17
18
  export * from "./helpers/auth";
18
19
  export * from "./helpers/bounding_boxes";
@@ -47,6 +47,117 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
47
47
  referencedColumns: ["id"];
48
48
  }];
49
49
  };
50
+ analysis_jobs: {
51
+ Row: {
52
+ id: number;
53
+ inserted_at: string;
54
+ status: Database["public"]["Enums"]["analysis_work_status"];
55
+ timestamp_finished: string | null;
56
+ timestamp_requested: string;
57
+ timestamp_started: string | null;
58
+ };
59
+ Insert: {
60
+ id?: number;
61
+ inserted_at?: string;
62
+ status?: Database["public"]["Enums"]["analysis_work_status"];
63
+ timestamp_finished?: string | null;
64
+ timestamp_requested?: string;
65
+ timestamp_started?: string | null;
66
+ };
67
+ Update: {
68
+ id?: number;
69
+ inserted_at?: string;
70
+ status?: Database["public"]["Enums"]["analysis_work_status"];
71
+ timestamp_finished?: string | null;
72
+ timestamp_requested?: string;
73
+ timestamp_started?: string | null;
74
+ };
75
+ Relationships: [];
76
+ };
77
+ analysis_tasks: {
78
+ Row: {
79
+ artifact_id: number | null;
80
+ cpu_core_seconds: number | null;
81
+ cpu_memory_avg: number | null;
82
+ event_id: number | null;
83
+ execution_environment: string;
84
+ frames_processed: number | null;
85
+ gpu_memory_peak: number | null;
86
+ gpu_seconds: number | null;
87
+ id: number;
88
+ job_id: number;
89
+ model: string | null;
90
+ status: Database["public"]["Enums"]["analysis_work_status"];
91
+ task_type: string;
92
+ time_finished: string | null;
93
+ time_started: string | null;
94
+ };
95
+ Insert: {
96
+ artifact_id?: number | null;
97
+ cpu_core_seconds?: number | null;
98
+ cpu_memory_avg?: number | null;
99
+ event_id?: number | null;
100
+ execution_environment: string;
101
+ frames_processed?: number | null;
102
+ gpu_memory_peak?: number | null;
103
+ gpu_seconds?: number | null;
104
+ id?: number;
105
+ job_id: number;
106
+ model?: string | null;
107
+ status?: Database["public"]["Enums"]["analysis_work_status"];
108
+ task_type: string;
109
+ time_finished?: string | null;
110
+ time_started?: string | null;
111
+ };
112
+ Update: {
113
+ artifact_id?: number | null;
114
+ cpu_core_seconds?: number | null;
115
+ cpu_memory_avg?: number | null;
116
+ event_id?: number | null;
117
+ execution_environment?: string;
118
+ frames_processed?: number | null;
119
+ gpu_memory_peak?: number | null;
120
+ gpu_seconds?: number | null;
121
+ id?: number;
122
+ job_id?: number;
123
+ model?: string | null;
124
+ status?: Database["public"]["Enums"]["analysis_work_status"];
125
+ task_type?: string;
126
+ time_finished?: string | null;
127
+ time_started?: string | null;
128
+ };
129
+ Relationships: [{
130
+ foreignKeyName: "analysis_tasks_artifact_id_fkey";
131
+ columns: ["artifact_id"];
132
+ isOneToOne: false;
133
+ referencedRelation: "artifacts";
134
+ referencedColumns: ["id"];
135
+ }, {
136
+ foreignKeyName: "analysis_tasks_event_id_fkey";
137
+ columns: ["event_id"];
138
+ isOneToOne: false;
139
+ referencedRelation: "events";
140
+ referencedColumns: ["id"];
141
+ }, {
142
+ foreignKeyName: "analysis_tasks_event_id_fkey";
143
+ columns: ["event_id"];
144
+ isOneToOne: false;
145
+ referencedRelation: "events_with_tags";
146
+ referencedColumns: ["id"];
147
+ }, {
148
+ foreignKeyName: "analysis_tasks_event_id_fkey";
149
+ columns: ["event_id"];
150
+ isOneToOne: false;
151
+ referencedRelation: "events_with_tags_by_session";
152
+ referencedColumns: ["id"];
153
+ }, {
154
+ foreignKeyName: "analysis_tasks_job_id_fkey";
155
+ columns: ["job_id"];
156
+ isOneToOne: false;
157
+ referencedRelation: "analysis_jobs";
158
+ referencedColumns: ["id"];
159
+ }];
160
+ };
50
161
  artifacts: {
51
162
  Row: {
52
163
  created_at: string;
@@ -905,6 +1016,27 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
905
1016
  referencedColumns: ["id"];
906
1017
  }];
907
1018
  };
1019
+ platform_superadmins: {
1020
+ Row: {
1021
+ inserted_at: string;
1022
+ user_id: string;
1023
+ };
1024
+ Insert: {
1025
+ inserted_at?: string;
1026
+ user_id: string;
1027
+ };
1028
+ Update: {
1029
+ inserted_at?: string;
1030
+ user_id?: string;
1031
+ };
1032
+ Relationships: [{
1033
+ foreignKeyName: "platform_superadmins_user_id_fkey";
1034
+ columns: ["user_id"];
1035
+ isOneToOne: true;
1036
+ referencedRelation: "users";
1037
+ referencedColumns: ["id"];
1038
+ }];
1039
+ };
908
1040
  providers: {
909
1041
  Row: {
910
1042
  created_at: string;
@@ -2480,6 +2612,7 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
2480
2612
  };
2481
2613
  };
2482
2614
  Enums: {
2615
+ analysis_work_status: "waiting" | "cancelled" | "processing" | "failed" | "success";
2483
2616
  app_permission: "herds.delete" | "events.delete";
2484
2617
  component_status: "active" | "inactive";
2485
2618
  device_type: "trail_camera" | "drone_fixed_wing" | "drone_quad" | "gps_tracker" | "sentry_tower" | "smart_buoy" | "radio_mesh_base_station" | "radio_mesh_repeater" | "unknown" | "gps_tracker_vehicle" | "gps_tracker_person" | "radio_mesh_base_station_gateway";