@adventurelabs/scout-core 1.5.1 → 1.5.3
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.
- package/dist/helpers/artifactMedia.d.ts +5 -0
- package/dist/helpers/artifactMedia.js +31 -0
- package/dist/helpers/artifacts.js +13 -19
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.js +1 -0
- package/dist/helpers/operating_contexts.d.ts +4 -1
- package/dist/helpers/operating_contexts.js +9 -0
- package/dist/helpers/sensor_poses.d.ts +16 -0
- package/dist/helpers/sensor_poses.js +97 -0
- package/dist/hooks/useScoutRealtimeOperatingContexts.d.ts +3 -3
- package/dist/hooks/useScoutRealtimeOperatingContexts.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/store/api.js +14 -34
- package/dist/types/db.d.ts +8 -0
- package/dist/types/supabase.d.ts +106 -0
- package/package.json +1 -1
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { IArtifact, IArtifactWithMediaUrl } from "../types/db";
|
|
2
|
+
/** Collect unique non-empty storage paths used for artifact media signing. */
|
|
3
|
+
export declare function collectArtifactStoragePaths(artifacts: Iterable<Pick<IArtifact, "file_path" | "thumbnail_file_path" | "proxy_file_path">>): string[];
|
|
4
|
+
/** Attach signed URLs for original, thumbnail, and proxy storage paths. */
|
|
5
|
+
export declare function withArtifactMediaUrls(artifact: IArtifact, urlMap: Map<string, string | null | undefined>): IArtifactWithMediaUrl;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { isNonEmptyStorageFilePath } from "./storagePath";
|
|
2
|
+
/** Collect unique non-empty storage paths used for artifact media signing. */
|
|
3
|
+
export function collectArtifactStoragePaths(artifacts) {
|
|
4
|
+
const seen = new Set();
|
|
5
|
+
const paths = [];
|
|
6
|
+
for (const artifact of artifacts) {
|
|
7
|
+
for (const path of [
|
|
8
|
+
artifact.file_path,
|
|
9
|
+
artifact.thumbnail_file_path,
|
|
10
|
+
artifact.proxy_file_path,
|
|
11
|
+
]) {
|
|
12
|
+
if (isNonEmptyStorageFilePath(path) && !seen.has(path)) {
|
|
13
|
+
seen.add(path);
|
|
14
|
+
paths.push(path);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return paths;
|
|
19
|
+
}
|
|
20
|
+
function signedUrlForPath(path, urlMap) {
|
|
21
|
+
return isNonEmptyStorageFilePath(path) ? urlMap.get(path) ?? null : null;
|
|
22
|
+
}
|
|
23
|
+
/** Attach signed URLs for original, thumbnail, and proxy storage paths. */
|
|
24
|
+
export function withArtifactMediaUrls(artifact, urlMap) {
|
|
25
|
+
return {
|
|
26
|
+
...artifact,
|
|
27
|
+
media_url: signedUrlForPath(artifact.file_path, urlMap),
|
|
28
|
+
thumbnail_url: signedUrlForPath(artifact.thumbnail_file_path, urlMap),
|
|
29
|
+
proxy_url: signedUrlForPath(artifact.proxy_file_path, urlMap),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -1,26 +1,19 @@
|
|
|
1
1
|
"use server";
|
|
2
2
|
import { newServerClient } from "../supabase/server";
|
|
3
3
|
import { IWebResponse } from "../types/requests";
|
|
4
|
-
import { generateSignedUrlsBatchWithClient,
|
|
5
|
-
import {
|
|
4
|
+
import { generateSignedUrlsBatchWithClient, } from "./storage_internal";
|
|
5
|
+
import { collectArtifactStoragePaths, withArtifactMediaUrls, } from "./artifactMedia";
|
|
6
6
|
async function addArtifactMediaUrls(data, client) {
|
|
7
|
-
const uniqueFilePaths =
|
|
8
|
-
.map((artifact) => artifact.file_path)
|
|
9
|
-
.filter(isNonEmptyStorageFilePath)));
|
|
7
|
+
const uniqueFilePaths = collectArtifactStoragePaths(data);
|
|
10
8
|
if (uniqueFilePaths.length === 0) {
|
|
11
|
-
return data;
|
|
9
|
+
return data.map((artifact) => withArtifactMediaUrls(artifact, new Map()));
|
|
12
10
|
}
|
|
13
11
|
const signedUrls = await generateSignedUrlsBatchWithClient(client, uniqueFilePaths);
|
|
14
12
|
const urlMap = new Map();
|
|
15
13
|
uniqueFilePaths.forEach((path, index) => {
|
|
16
14
|
urlMap.set(path, signedUrls[index]);
|
|
17
15
|
});
|
|
18
|
-
return data.map((artifact) => (
|
|
19
|
-
...artifact,
|
|
20
|
-
media_url: isNonEmptyStorageFilePath(artifact.file_path)
|
|
21
|
-
? urlMap.get(artifact.file_path) ?? null
|
|
22
|
-
: null,
|
|
23
|
-
}));
|
|
16
|
+
return data.map((artifact) => withArtifactMediaUrls(artifact, urlMap));
|
|
24
17
|
}
|
|
25
18
|
export async function server_get_artifact_by_id(id) {
|
|
26
19
|
const client = await newServerClient();
|
|
@@ -36,14 +29,15 @@ export async function server_get_artifact_by_id(id) {
|
|
|
36
29
|
return IWebResponse.success(null).to_compatible();
|
|
37
30
|
}
|
|
38
31
|
const artifact = data;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
const paths = collectArtifactStoragePaths([artifact]);
|
|
33
|
+
const urlMap = new Map();
|
|
34
|
+
if (paths.length > 0) {
|
|
35
|
+
const signedUrls = await generateSignedUrlsBatchWithClient(client, paths);
|
|
36
|
+
paths.forEach((path, index) => {
|
|
37
|
+
urlMap.set(path, signedUrls[index]);
|
|
38
|
+
});
|
|
42
39
|
}
|
|
43
|
-
return IWebResponse.success(
|
|
44
|
-
...artifact,
|
|
45
|
-
media_url,
|
|
46
|
-
}).to_compatible();
|
|
40
|
+
return IWebResponse.success(withArtifactMediaUrls(artifact, urlMap)).to_compatible();
|
|
47
41
|
}
|
|
48
42
|
export async function server_get_artifacts_by_herd(herd_id, limit = 50, offset = 0, options) {
|
|
49
43
|
const client = await newServerClient();
|
package/dist/helpers/index.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ export * from "./cache";
|
|
|
40
40
|
export * from "./observations";
|
|
41
41
|
export * from "./operators";
|
|
42
42
|
export * from "./parts";
|
|
43
|
+
export * from "./sensor_poses";
|
|
43
44
|
export * from "./versions_software";
|
|
44
45
|
export * from "./versions_software_server";
|
|
45
46
|
export * from "./artifacts";
|
package/dist/helpers/index.js
CHANGED
|
@@ -40,6 +40,7 @@ export * from "./cache";
|
|
|
40
40
|
export * from "./observations";
|
|
41
41
|
export * from "./operators";
|
|
42
42
|
export * from "./parts";
|
|
43
|
+
export * from "./sensor_poses";
|
|
43
44
|
export * from "./versions_software";
|
|
44
45
|
export * from "./versions_software_server";
|
|
45
46
|
export * from "./artifacts";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DocumentConditionCreateInput, DocumentConditionUpdateInput, IDocumentCondition, IOperatingContext, IOperatingContextEquipmentCategory, IOperatingContextEquipmentItem, IOperatingContextEquipmentRequirement, IOperatingContextPayload, IOperatingContextRegion, IOperatingContextRisk, IOperatingContextRole, IOperatingContextRoleAssignment, IOperatingContextType, IOperatingContextWeatherSnapshot, OperatingContextCreateInput, OperatingContextEquipmentCategoryCreateInput, OperatingContextEquipmentCategoryUpdateInput, OperatingContextEquipmentItemCreateInput, OperatingContextEquipmentItemUpdateInput, OperatingContextEquipmentRequirementCreateInput, OperatingContextEquipmentRequirementUpdateInput, OperatingContextListOptions, OperatingContextPayloadCreateInput, OperatingContextPayloadUpdateInput, OperatingContextRegionCreateInput, OperatingContextRegionUpdateInput, OperatingContextRiskCreateInput, OperatingContextRiskUpdateInput, OperatingContextRoleAssignmentCreateInput, OperatingContextRoleAssignmentUpdateInput, OperatingContextRoleCreateInput, OperatingContextRoleUpdateInput, OperatingContextTypeCreateInput, OperatingContextTypeUpdateInput, OperatingContextUpdateInput } from "../types/db";
|
|
1
|
+
import { DocumentConditionCreateInput, DocumentConditionUpdateInput, IDocumentCondition, IOperatingContext, IOperatingContextDevice, IOperatingContextEquipmentCategory, IOperatingContextEquipmentItem, IOperatingContextEquipmentRequirement, IOperatingContextPayload, IOperatingContextRegion, IOperatingContextRisk, IOperatingContextRole, IOperatingContextRoleAssignment, IOperatingContextType, IOperatingContextWeatherSnapshot, OperatingContextCreateInput, OperatingContextDeviceCreateInput, OperatingContextDeviceUpdateInput, OperatingContextEquipmentCategoryCreateInput, OperatingContextEquipmentCategoryUpdateInput, OperatingContextEquipmentItemCreateInput, OperatingContextEquipmentItemUpdateInput, OperatingContextEquipmentRequirementCreateInput, OperatingContextEquipmentRequirementUpdateInput, OperatingContextListOptions, OperatingContextPayloadCreateInput, OperatingContextPayloadUpdateInput, OperatingContextRegionCreateInput, OperatingContextRegionUpdateInput, OperatingContextRiskCreateInput, OperatingContextRiskUpdateInput, OperatingContextRoleAssignmentCreateInput, OperatingContextRoleAssignmentUpdateInput, OperatingContextRoleCreateInput, OperatingContextRoleUpdateInput, OperatingContextTypeCreateInput, OperatingContextTypeUpdateInput, OperatingContextUpdateInput } from "../types/db";
|
|
2
2
|
import { IWebResponseCompatible } from "../types/requests";
|
|
3
3
|
export declare function server_get_document_conditions_by_localization(localization_id: number, options?: OperatingContextListOptions): Promise<IWebResponseCompatible<IDocumentCondition[]>>;
|
|
4
4
|
export declare function server_create_document_condition(row: DocumentConditionCreateInput): Promise<IWebResponseCompatible<IDocumentCondition | null>>;
|
|
@@ -25,6 +25,9 @@ export declare function server_update_operating_context_payload(id: number, upda
|
|
|
25
25
|
export declare function server_get_operating_context_role_assignments_by_operating_context(operating_context_id: number, options?: OperatingContextListOptions): Promise<IWebResponseCompatible<IOperatingContextRoleAssignment[]>>;
|
|
26
26
|
export declare function server_create_operating_context_role_assignment(row: OperatingContextRoleAssignmentCreateInput): Promise<IWebResponseCompatible<IOperatingContextRoleAssignment | null>>;
|
|
27
27
|
export declare function server_update_operating_context_role_assignment(id: number, updates: OperatingContextRoleAssignmentUpdateInput): Promise<IWebResponseCompatible<IOperatingContextRoleAssignment | null>>;
|
|
28
|
+
export declare function server_get_operating_context_devices_by_operating_context(operating_context_id: number, options?: OperatingContextListOptions): Promise<IWebResponseCompatible<IOperatingContextDevice[]>>;
|
|
29
|
+
export declare function server_create_operating_context_device(row: OperatingContextDeviceCreateInput): Promise<IWebResponseCompatible<IOperatingContextDevice | null>>;
|
|
30
|
+
export declare function server_update_operating_context_device(id: number, updates: OperatingContextDeviceUpdateInput): Promise<IWebResponseCompatible<IOperatingContextDevice | null>>;
|
|
28
31
|
export declare function server_get_operating_context_equipment_requirements_by_operating_context(operating_context_id: number, options?: OperatingContextListOptions): Promise<IWebResponseCompatible<IOperatingContextEquipmentRequirement[]>>;
|
|
29
32
|
export declare function server_create_operating_context_equipment_requirement(row: OperatingContextEquipmentRequirementCreateInput): Promise<IWebResponseCompatible<IOperatingContextEquipmentRequirement | null>>;
|
|
30
33
|
export declare function server_update_operating_context_equipment_requirement(id: number, updates: OperatingContextEquipmentRequirementUpdateInput): Promise<IWebResponseCompatible<IOperatingContextEquipmentRequirement | null>>;
|
|
@@ -177,6 +177,15 @@ export async function server_create_operating_context_role_assignment(row) {
|
|
|
177
177
|
export async function server_update_operating_context_role_assignment(id, updates) {
|
|
178
178
|
return patch_row("operating_context_role_assignments", id, updates, "lifecycle");
|
|
179
179
|
}
|
|
180
|
+
export async function server_get_operating_context_devices_by_operating_context(operating_context_id, options) {
|
|
181
|
+
return list_by("operating_contexts_devices", "operating_context_id", operating_context_id, options);
|
|
182
|
+
}
|
|
183
|
+
export async function server_create_operating_context_device(row) {
|
|
184
|
+
return insert_row("operating_contexts_devices", row);
|
|
185
|
+
}
|
|
186
|
+
export async function server_update_operating_context_device(id, updates) {
|
|
187
|
+
return patch_row("operating_contexts_devices", id, updates, "lifecycle");
|
|
188
|
+
}
|
|
180
189
|
export async function server_get_operating_context_equipment_requirements_by_operating_context(operating_context_id, options) {
|
|
181
190
|
return list_by("operating_context_equipment_requirements", "operating_context_id", operating_context_id, options);
|
|
182
191
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Database } from "../types/supabase";
|
|
2
|
+
import { ISensorPose, SensorPoseInsert, SensorPoseUpdate } from "../types/db";
|
|
3
|
+
import { IWebResponseCompatible } from "../types/requests";
|
|
4
|
+
import { SupabaseClient } from "@supabase/supabase-js";
|
|
5
|
+
interface SensorPoseTimeRangeOptions {
|
|
6
|
+
start_timestamp?: string;
|
|
7
|
+
end_timestamp?: string;
|
|
8
|
+
limit?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function get_sensor_poses_by_part_id(client: SupabaseClient<Database>, part_id: number, options?: SensorPoseTimeRangeOptions): Promise<IWebResponseCompatible<ISensorPose[]>>;
|
|
11
|
+
export declare function get_sensor_pose_by_id(client: SupabaseClient<Database>, sensor_pose_id: number): Promise<IWebResponseCompatible<ISensorPose | null>>;
|
|
12
|
+
export declare function create_sensor_pose(client: SupabaseClient<Database>, row: SensorPoseInsert): Promise<IWebResponseCompatible<ISensorPose | null>>;
|
|
13
|
+
export declare function create_sensor_poses(client: SupabaseClient<Database>, rows: SensorPoseInsert[]): Promise<IWebResponseCompatible<ISensorPose[]>>;
|
|
14
|
+
export declare function update_sensor_pose(client: SupabaseClient<Database>, sensor_pose_id: number, patch: SensorPoseUpdate): Promise<IWebResponseCompatible<ISensorPose | null>>;
|
|
15
|
+
export declare function delete_sensor_pose(client: SupabaseClient<Database>, sensor_pose_id: number): Promise<IWebResponseCompatible<ISensorPose | null>>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { IWebResponse } from "../types/requests";
|
|
2
|
+
export async function get_sensor_poses_by_part_id(client, part_id, options) {
|
|
3
|
+
let query = client
|
|
4
|
+
.from("sensor_poses")
|
|
5
|
+
.select("*")
|
|
6
|
+
.eq("part_id", part_id)
|
|
7
|
+
.order("timestamp_observation", { ascending: true });
|
|
8
|
+
if (options?.start_timestamp) {
|
|
9
|
+
query = query.gte("timestamp_observation", options.start_timestamp);
|
|
10
|
+
}
|
|
11
|
+
if (options?.end_timestamp) {
|
|
12
|
+
query = query.lte("timestamp_observation", options.end_timestamp);
|
|
13
|
+
}
|
|
14
|
+
if (options?.limit != null) {
|
|
15
|
+
query = query.limit(options.limit);
|
|
16
|
+
}
|
|
17
|
+
const { data, error } = await query;
|
|
18
|
+
if (error) {
|
|
19
|
+
return IWebResponse.error(error.message).to_compatible();
|
|
20
|
+
}
|
|
21
|
+
return IWebResponse.success(data ?? []).to_compatible();
|
|
22
|
+
}
|
|
23
|
+
export async function get_sensor_pose_by_id(client, sensor_pose_id) {
|
|
24
|
+
const { data, error } = await client
|
|
25
|
+
.from("sensor_poses")
|
|
26
|
+
.select("*")
|
|
27
|
+
.eq("id", sensor_pose_id)
|
|
28
|
+
.maybeSingle();
|
|
29
|
+
if (error) {
|
|
30
|
+
return IWebResponse.error(error.message).to_compatible();
|
|
31
|
+
}
|
|
32
|
+
if (!data) {
|
|
33
|
+
return IWebResponse.error("Sensor pose not found").to_compatible();
|
|
34
|
+
}
|
|
35
|
+
return IWebResponse.success(data).to_compatible();
|
|
36
|
+
}
|
|
37
|
+
export async function create_sensor_pose(client, row) {
|
|
38
|
+
const { data, error } = await client
|
|
39
|
+
.from("sensor_poses")
|
|
40
|
+
.insert([row])
|
|
41
|
+
.select("*")
|
|
42
|
+
.single();
|
|
43
|
+
if (error) {
|
|
44
|
+
return IWebResponse.error(error.message).to_compatible();
|
|
45
|
+
}
|
|
46
|
+
if (!data) {
|
|
47
|
+
return IWebResponse.error("Failed to create sensor pose").to_compatible();
|
|
48
|
+
}
|
|
49
|
+
return IWebResponse.success(data).to_compatible();
|
|
50
|
+
}
|
|
51
|
+
export async function create_sensor_poses(client, rows) {
|
|
52
|
+
if (rows.length === 0) {
|
|
53
|
+
return IWebResponse.success([]).to_compatible();
|
|
54
|
+
}
|
|
55
|
+
const { data, error } = await client
|
|
56
|
+
.from("sensor_poses")
|
|
57
|
+
.insert(rows)
|
|
58
|
+
.select("*");
|
|
59
|
+
if (error) {
|
|
60
|
+
return IWebResponse.error(error.message).to_compatible();
|
|
61
|
+
}
|
|
62
|
+
return IWebResponse.success(data ?? []).to_compatible();
|
|
63
|
+
}
|
|
64
|
+
export async function update_sensor_pose(client, sensor_pose_id, patch) {
|
|
65
|
+
const { id: _id, inserted_at: _ia, ...updateData } = patch;
|
|
66
|
+
if (Object.keys(updateData).length === 0) {
|
|
67
|
+
return IWebResponse.error("No valid fields to update").to_compatible();
|
|
68
|
+
}
|
|
69
|
+
const { data, error } = await client
|
|
70
|
+
.from("sensor_poses")
|
|
71
|
+
.update(updateData)
|
|
72
|
+
.eq("id", sensor_pose_id)
|
|
73
|
+
.select("*")
|
|
74
|
+
.single();
|
|
75
|
+
if (error) {
|
|
76
|
+
return IWebResponse.error(error.message).to_compatible();
|
|
77
|
+
}
|
|
78
|
+
if (!data) {
|
|
79
|
+
return IWebResponse.error("Sensor pose not found or update failed").to_compatible();
|
|
80
|
+
}
|
|
81
|
+
return IWebResponse.success(data).to_compatible();
|
|
82
|
+
}
|
|
83
|
+
export async function delete_sensor_pose(client, sensor_pose_id) {
|
|
84
|
+
const { data, error } = await client
|
|
85
|
+
.from("sensor_poses")
|
|
86
|
+
.delete()
|
|
87
|
+
.eq("id", sensor_pose_id)
|
|
88
|
+
.select("*")
|
|
89
|
+
.single();
|
|
90
|
+
if (error) {
|
|
91
|
+
return IWebResponse.error(error.message).to_compatible();
|
|
92
|
+
}
|
|
93
|
+
if (!data) {
|
|
94
|
+
return IWebResponse.error("Sensor pose not found or deletion failed").to_compatible();
|
|
95
|
+
}
|
|
96
|
+
return IWebResponse.success(data).to_compatible();
|
|
97
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { SupabaseClient } from "@supabase/supabase-js";
|
|
2
2
|
import { Database } from "../types/supabase";
|
|
3
|
-
import { IOperatingContext, IOperatingContextEquipmentRequirement, IOperatingContextPayload, IOperatingContextRegion, IOperatingContextRisk, IOperatingContextRoleAssignment } from "../types/db";
|
|
3
|
+
import { IOperatingContext, IOperatingContextDevice, IOperatingContextEquipmentRequirement, IOperatingContextPayload, IOperatingContextRegion, IOperatingContextRisk, IOperatingContextRoleAssignment } from "../types/db";
|
|
4
4
|
import { RealtimeData } from "../types/realtime";
|
|
5
5
|
import { ScoutRealtimeBroadcastOptions } from "./useScoutRealtimeBroadcast";
|
|
6
|
-
export type OperatingContextRealtimeRow = IOperatingContext | IOperatingContextPayload | IOperatingContextRoleAssignment | IOperatingContextEquipmentRequirement | IOperatingContextRegion | IOperatingContextRisk;
|
|
6
|
+
export type OperatingContextRealtimeRow = IOperatingContext | IOperatingContextDevice | IOperatingContextPayload | IOperatingContextRoleAssignment | IOperatingContextEquipmentRequirement | IOperatingContextRegion | IOperatingContextRisk;
|
|
7
7
|
type OperatingContextRealtimeChange<T, Table extends string> = Omit<RealtimeData<T>, "table"> & {
|
|
8
8
|
table: Table;
|
|
9
9
|
};
|
|
10
|
-
export type OperatingContextRealtimeData = OperatingContextRealtimeChange<IOperatingContext, "operating_contexts"> | OperatingContextRealtimeChange<IOperatingContextPayload, "operating_context_payloads"> | OperatingContextRealtimeChange<IOperatingContextRoleAssignment, "operating_context_role_assignments"> | OperatingContextRealtimeChange<IOperatingContextEquipmentRequirement, "operating_context_equipment_requirements"> | OperatingContextRealtimeChange<IOperatingContextRegion, "operating_context_regions"> | OperatingContextRealtimeChange<IOperatingContextRisk, "operating_context_risks">;
|
|
10
|
+
export type OperatingContextRealtimeData = OperatingContextRealtimeChange<IOperatingContext, "operating_contexts"> | OperatingContextRealtimeChange<IOperatingContextDevice, "operating_contexts_devices"> | OperatingContextRealtimeChange<IOperatingContextPayload, "operating_context_payloads"> | OperatingContextRealtimeChange<IOperatingContextRoleAssignment, "operating_context_role_assignments"> | OperatingContextRealtimeChange<IOperatingContextEquipmentRequirement, "operating_context_equipment_requirements"> | OperatingContextRealtimeChange<IOperatingContextRegion, "operating_context_regions"> | OperatingContextRealtimeChange<IOperatingContextRisk, "operating_context_risks">;
|
|
11
11
|
export declare function useScoutRealtimeOperatingContexts(scoutSupabase: SupabaseClient<Database>, options?: ScoutRealtimeBroadcastOptions): [OperatingContextRealtimeData | null, () => void];
|
|
12
12
|
export {};
|
|
@@ -4,6 +4,7 @@ import { useSelector } from "react-redux";
|
|
|
4
4
|
import { useScoutRealtimeBroadcast, } from "./useScoutRealtimeBroadcast";
|
|
5
5
|
const TABLE_MARKERS = [
|
|
6
6
|
["operating_contexts", "operating_context_type_id"],
|
|
7
|
+
["operating_contexts_devices", "device_id"],
|
|
7
8
|
["operating_context_payloads", "payload_type"],
|
|
8
9
|
["operating_context_role_assignments", "membership_id"],
|
|
9
10
|
["operating_context_equipment_requirements", "equipment_item_id"],
|
package/dist/index.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ export * from "./helpers/operators";
|
|
|
62
62
|
export * from "./helpers/versions_software";
|
|
63
63
|
export * from "./helpers/versions_software_server";
|
|
64
64
|
export * from "./helpers/parts";
|
|
65
|
+
export * from "./helpers/sensor_poses";
|
|
65
66
|
export * from "./helpers/manufacturers";
|
|
66
67
|
export * from "./helpers/products";
|
|
67
68
|
export * from "./helpers/product_numbers";
|
package/dist/index.js
CHANGED
|
@@ -65,6 +65,7 @@ export * from "./helpers/operators";
|
|
|
65
65
|
export * from "./helpers/versions_software";
|
|
66
66
|
export * from "./helpers/versions_software_server";
|
|
67
67
|
export * from "./helpers/parts";
|
|
68
|
+
export * from "./helpers/sensor_poses";
|
|
68
69
|
export * from "./helpers/manufacturers";
|
|
69
70
|
export * from "./helpers/products";
|
|
70
71
|
export * from "./helpers/product_numbers";
|
package/dist/store/api.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createApi, fakeBaseQuery } from "@reduxjs/toolkit/query/react";
|
|
2
2
|
import { generateSignedUrlsBatch, } from "../helpers/storage";
|
|
3
|
+
import { collectArtifactStoragePaths, withArtifactMediaUrls, } from "../helpers/artifactMedia";
|
|
3
4
|
import { isNonEmptyStorageFilePath } from "../helpers/storagePath";
|
|
4
5
|
async function signedUrlMapForFeedRows(rows) {
|
|
5
6
|
const seen = new Set();
|
|
@@ -10,10 +11,13 @@ async function signedUrlMapForFeedRows(rows) {
|
|
|
10
11
|
seen.add(ep);
|
|
11
12
|
paths.push(ep);
|
|
12
13
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
if (row.artifact_data) {
|
|
15
|
+
for (const path of collectArtifactStoragePaths([row.artifact_data])) {
|
|
16
|
+
if (!seen.has(path)) {
|
|
17
|
+
seen.add(path);
|
|
18
|
+
paths.push(path);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
17
21
|
}
|
|
18
22
|
}
|
|
19
23
|
const map = new Map();
|
|
@@ -345,9 +349,7 @@ export const scoutApi = createApi({
|
|
|
345
349
|
? artifacts.slice(0, limit)
|
|
346
350
|
: artifacts;
|
|
347
351
|
// Generate signed URLs for artifacts
|
|
348
|
-
const uniqueFilePaths =
|
|
349
|
-
.map((artifact) => artifact.file_path)
|
|
350
|
-
.filter(isNonEmptyStorageFilePath)));
|
|
352
|
+
const uniqueFilePaths = collectArtifactStoragePaths(resultArtifacts);
|
|
351
353
|
let urlMap = new Map();
|
|
352
354
|
if (uniqueFilePaths.length > 0) {
|
|
353
355
|
try {
|
|
@@ -362,12 +364,7 @@ export const scoutApi = createApi({
|
|
|
362
364
|
console.warn("Failed to generate signed URLs for artifacts:", urlError);
|
|
363
365
|
}
|
|
364
366
|
}
|
|
365
|
-
const artifactsWithUrls = resultArtifacts.map((artifact) => (
|
|
366
|
-
...artifact,
|
|
367
|
-
media_url: isNonEmptyStorageFilePath(artifact.file_path)
|
|
368
|
-
? urlMap.get(artifact.file_path) ?? null
|
|
369
|
-
: null,
|
|
370
|
-
}));
|
|
367
|
+
const artifactsWithUrls = resultArtifacts.map((artifact) => withArtifactMediaUrls(artifact, urlMap));
|
|
371
368
|
const nextCursor = hasMore && resultArtifacts.length > 0
|
|
372
369
|
? {
|
|
373
370
|
timestamp: resultArtifacts[resultArtifacts.length - 1].created_at,
|
|
@@ -424,9 +421,7 @@ export const scoutApi = createApi({
|
|
|
424
421
|
? artifacts.slice(0, limit)
|
|
425
422
|
: artifacts;
|
|
426
423
|
// Generate signed URLs for artifacts
|
|
427
|
-
const uniqueFilePaths =
|
|
428
|
-
.map((artifact) => artifact.file_path)
|
|
429
|
-
.filter(isNonEmptyStorageFilePath)));
|
|
424
|
+
const uniqueFilePaths = collectArtifactStoragePaths(resultArtifacts);
|
|
430
425
|
let urlMap = new Map();
|
|
431
426
|
if (uniqueFilePaths.length > 0) {
|
|
432
427
|
try {
|
|
@@ -441,12 +436,7 @@ export const scoutApi = createApi({
|
|
|
441
436
|
console.warn("Failed to generate signed URLs for artifacts:", urlError);
|
|
442
437
|
}
|
|
443
438
|
}
|
|
444
|
-
const artifactsWithUrls = resultArtifacts.map((artifact) => (
|
|
445
|
-
...artifact,
|
|
446
|
-
media_url: isNonEmptyStorageFilePath(artifact.file_path)
|
|
447
|
-
? urlMap.get(artifact.file_path) ?? null
|
|
448
|
-
: null,
|
|
449
|
-
}));
|
|
439
|
+
const artifactsWithUrls = resultArtifacts.map((artifact) => withArtifactMediaUrls(artifact, urlMap));
|
|
450
440
|
const nextCursor = hasMore && resultArtifacts.length > 0
|
|
451
441
|
? {
|
|
452
442
|
timestamp: resultArtifacts[resultArtifacts.length - 1].created_at,
|
|
@@ -523,12 +513,7 @@ export const scoutApi = createApi({
|
|
|
523
513
|
}
|
|
524
514
|
: null,
|
|
525
515
|
artifact_data: row.artifact_data
|
|
526
|
-
?
|
|
527
|
-
...row.artifact_data,
|
|
528
|
-
media_url: isNonEmptyStorageFilePath(row.artifact_data.file_path)
|
|
529
|
-
? urlMap.get(row.artifact_data.file_path) ?? null
|
|
530
|
-
: null,
|
|
531
|
-
}
|
|
516
|
+
? withArtifactMediaUrls(row.artifact_data, urlMap)
|
|
532
517
|
: null,
|
|
533
518
|
}));
|
|
534
519
|
const last = resultRows[resultRows.length - 1];
|
|
@@ -598,12 +583,7 @@ export const scoutApi = createApi({
|
|
|
598
583
|
}
|
|
599
584
|
: null,
|
|
600
585
|
artifact_data: row.artifact_data
|
|
601
|
-
?
|
|
602
|
-
...row.artifact_data,
|
|
603
|
-
media_url: isNonEmptyStorageFilePath(row.artifact_data.file_path)
|
|
604
|
-
? urlMap.get(row.artifact_data.file_path) ?? null
|
|
605
|
-
: null,
|
|
606
|
-
}
|
|
586
|
+
? withArtifactMediaUrls(row.artifact_data, urlMap)
|
|
607
587
|
: null,
|
|
608
588
|
}));
|
|
609
589
|
const last = resultRows[resultRows.length - 1];
|
package/dist/types/db.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export type MediaType = Database["public"]["Enums"]["media_type"];
|
|
|
6
6
|
export type TagObservationType = Database["public"]["Enums"]["tag_observation_type"];
|
|
7
7
|
export type AnalysisWorkStatus = Database["public"]["Enums"]["analysis_work_status"];
|
|
8
8
|
export type EntityLifecycle = Database["public"]["Enums"]["entity_lifecycle"];
|
|
9
|
+
export type DocumentEntity = Database["public"]["Enums"]["document_entity"];
|
|
9
10
|
/** Supabase Auth user (`auth.getUser()`); not `public.users`. */
|
|
10
11
|
export type IUser = User;
|
|
11
12
|
/** Full `public.users` profile row (generated from DB). */
|
|
@@ -79,6 +80,7 @@ export type IOperatingContextEquipmentItem = Database["public"]["Tables"]["opera
|
|
|
79
80
|
export type IOperatingContext = Database["public"]["Tables"]["operating_contexts"]["Row"];
|
|
80
81
|
export type IOperatingContextPayload = Database["public"]["Tables"]["operating_context_payloads"]["Row"];
|
|
81
82
|
export type IOperatingContextRoleAssignment = Database["public"]["Tables"]["operating_context_role_assignments"]["Row"];
|
|
83
|
+
export type IOperatingContextDevice = Database["public"]["Tables"]["operating_contexts_devices"]["Row"];
|
|
82
84
|
export type IOperatingContextEquipmentRequirement = Database["public"]["Tables"]["operating_context_equipment_requirements"]["Row"];
|
|
83
85
|
export type IOperatingContextRegion = Database["public"]["Tables"]["operating_context_regions"]["Row"];
|
|
84
86
|
export type IOperatingContextRisk = Database["public"]["Tables"]["operating_context_risks"]["Row"];
|
|
@@ -119,6 +121,8 @@ export type OperatingContextPayloadCreateInput = Pick<OperatingContextPayloadIns
|
|
|
119
121
|
export type OperatingContextPayloadUpdateInput = Partial<Omit<OperatingContextPayloadCreateInput, "operating_context_id">> & LifecyclePatch;
|
|
120
122
|
export type OperatingContextRoleAssignmentCreateInput = Pick<OperatingContextRoleAssignmentInsert, "operating_context_id" | "membership_id" | "role_id" | "herd_id">;
|
|
121
123
|
export type OperatingContextRoleAssignmentUpdateInput = Partial<Pick<OperatingContextRoleAssignmentCreateInput, "membership_id" | "role_id">> & LifecyclePatch;
|
|
124
|
+
export type OperatingContextDeviceCreateInput = Pick<OperatingContextDeviceInsert, "operating_context_id" | "device_id" | "herd_id">;
|
|
125
|
+
export type OperatingContextDeviceUpdateInput = Partial<Pick<OperatingContextDeviceCreateInput, "device_id">> & LifecyclePatch;
|
|
122
126
|
export type OperatingContextEquipmentRequirementCreateInput = Pick<OperatingContextEquipmentRequirementInsert, "operating_context_id" | "equipment_item_id">;
|
|
123
127
|
export type OperatingContextEquipmentRequirementUpdateInput = Partial<Pick<OperatingContextEquipmentRequirementCreateInput, "equipment_item_id">> & LifecyclePatch;
|
|
124
128
|
export interface OperatingContextRegionCreateInput {
|
|
@@ -148,6 +152,8 @@ export type IAnalysisJob = Database["public"]["Tables"]["analysis_jobs"]["Row"];
|
|
|
148
152
|
export type IAnalysisTask = Database["public"]["Tables"]["analysis_tasks"]["Row"];
|
|
149
153
|
export type IArtifactWithMediaUrl = IArtifact & {
|
|
150
154
|
media_url?: string | null;
|
|
155
|
+
thumbnail_url?: string | null;
|
|
156
|
+
proxy_url?: string | null;
|
|
151
157
|
};
|
|
152
158
|
export type IEventWithMediaUrl = IEvent & {
|
|
153
159
|
media_url?: string | null;
|
|
@@ -222,6 +228,8 @@ export type OperatingContextPayloadInsert = Database["public"]["Tables"]["operat
|
|
|
222
228
|
export type OperatingContextPayloadUpdate = Database["public"]["Tables"]["operating_context_payloads"]["Update"];
|
|
223
229
|
export type OperatingContextRoleAssignmentInsert = Database["public"]["Tables"]["operating_context_role_assignments"]["Insert"];
|
|
224
230
|
export type OperatingContextRoleAssignmentUpdate = Database["public"]["Tables"]["operating_context_role_assignments"]["Update"];
|
|
231
|
+
export type OperatingContextDeviceInsert = Database["public"]["Tables"]["operating_contexts_devices"]["Insert"];
|
|
232
|
+
export type OperatingContextDeviceUpdate = Database["public"]["Tables"]["operating_contexts_devices"]["Update"];
|
|
225
233
|
export type OperatingContextEquipmentRequirementInsert = Database["public"]["Tables"]["operating_context_equipment_requirements"]["Insert"];
|
|
226
234
|
export type OperatingContextEquipmentRequirementUpdate = Database["public"]["Tables"]["operating_context_equipment_requirements"]["Update"];
|
|
227
235
|
export type OperatingContextRegionInsert = Database["public"]["Tables"]["operating_context_regions"]["Insert"];
|
package/dist/types/supabase.d.ts
CHANGED
|
@@ -257,9 +257,13 @@ export type Database = {
|
|
|
257
257
|
lifecycle_changed_by: string | null;
|
|
258
258
|
lifecycle_reason: string | null;
|
|
259
259
|
modality: string | null;
|
|
260
|
+
proxy_file_path: string | null;
|
|
261
|
+
proxy_generated_at: string | null;
|
|
260
262
|
segmented_at: string | null;
|
|
261
263
|
session_id: number | null;
|
|
262
264
|
tagged_at: string | null;
|
|
265
|
+
thumbnail_file_path: string | null;
|
|
266
|
+
thumbnail_generated_at: string | null;
|
|
263
267
|
timestamp_observation: string | null;
|
|
264
268
|
timestamp_observation_end: string;
|
|
265
269
|
tracked_at: string | null;
|
|
@@ -277,9 +281,13 @@ export type Database = {
|
|
|
277
281
|
lifecycle_changed_by?: string | null;
|
|
278
282
|
lifecycle_reason?: string | null;
|
|
279
283
|
modality?: string | null;
|
|
284
|
+
proxy_file_path?: string | null;
|
|
285
|
+
proxy_generated_at?: string | null;
|
|
280
286
|
segmented_at?: string | null;
|
|
281
287
|
session_id?: number | null;
|
|
282
288
|
tagged_at?: string | null;
|
|
289
|
+
thumbnail_file_path?: string | null;
|
|
290
|
+
thumbnail_generated_at?: string | null;
|
|
283
291
|
timestamp_observation?: string | null;
|
|
284
292
|
timestamp_observation_end?: string;
|
|
285
293
|
tracked_at?: string | null;
|
|
@@ -297,9 +305,13 @@ export type Database = {
|
|
|
297
305
|
lifecycle_changed_by?: string | null;
|
|
298
306
|
lifecycle_reason?: string | null;
|
|
299
307
|
modality?: string | null;
|
|
308
|
+
proxy_file_path?: string | null;
|
|
309
|
+
proxy_generated_at?: string | null;
|
|
300
310
|
segmented_at?: string | null;
|
|
301
311
|
session_id?: number | null;
|
|
302
312
|
tagged_at?: string | null;
|
|
313
|
+
thumbnail_file_path?: string | null;
|
|
314
|
+
thumbnail_generated_at?: string | null;
|
|
303
315
|
timestamp_observation?: string | null;
|
|
304
316
|
timestamp_observation_end?: string;
|
|
305
317
|
tracked_at?: string | null;
|
|
@@ -2681,6 +2693,64 @@ export type Database = {
|
|
|
2681
2693
|
}
|
|
2682
2694
|
];
|
|
2683
2695
|
};
|
|
2696
|
+
operating_contexts_devices: {
|
|
2697
|
+
Row: {
|
|
2698
|
+
device_id: number;
|
|
2699
|
+
herd_id: number;
|
|
2700
|
+
id: number;
|
|
2701
|
+
inserted_at: string;
|
|
2702
|
+
lifecycle: Database["public"]["Enums"]["entity_lifecycle"];
|
|
2703
|
+
lifecycle_changed_at: string;
|
|
2704
|
+
lifecycle_changed_by: string | null;
|
|
2705
|
+
lifecycle_reason: string | null;
|
|
2706
|
+
operating_context_id: number;
|
|
2707
|
+
};
|
|
2708
|
+
Insert: {
|
|
2709
|
+
device_id: number;
|
|
2710
|
+
herd_id: number;
|
|
2711
|
+
id?: number;
|
|
2712
|
+
inserted_at?: string;
|
|
2713
|
+
lifecycle?: Database["public"]["Enums"]["entity_lifecycle"];
|
|
2714
|
+
lifecycle_changed_at?: string;
|
|
2715
|
+
lifecycle_changed_by?: string | null;
|
|
2716
|
+
lifecycle_reason?: string | null;
|
|
2717
|
+
operating_context_id: number;
|
|
2718
|
+
};
|
|
2719
|
+
Update: {
|
|
2720
|
+
device_id?: number;
|
|
2721
|
+
herd_id?: number;
|
|
2722
|
+
id?: number;
|
|
2723
|
+
inserted_at?: string;
|
|
2724
|
+
lifecycle?: Database["public"]["Enums"]["entity_lifecycle"];
|
|
2725
|
+
lifecycle_changed_at?: string;
|
|
2726
|
+
lifecycle_changed_by?: string | null;
|
|
2727
|
+
lifecycle_reason?: string | null;
|
|
2728
|
+
operating_context_id?: number;
|
|
2729
|
+
};
|
|
2730
|
+
Relationships: [
|
|
2731
|
+
{
|
|
2732
|
+
foreignKeyName: "operating_context_device_context_fkey";
|
|
2733
|
+
columns: ["operating_context_id", "herd_id"];
|
|
2734
|
+
isOneToOne: false;
|
|
2735
|
+
referencedRelation: "operating_contexts";
|
|
2736
|
+
referencedColumns: ["id", "herd_id"];
|
|
2737
|
+
},
|
|
2738
|
+
{
|
|
2739
|
+
foreignKeyName: "operating_context_device_device_fkey";
|
|
2740
|
+
columns: ["device_id"];
|
|
2741
|
+
isOneToOne: false;
|
|
2742
|
+
referencedRelation: "devices";
|
|
2743
|
+
referencedColumns: ["id"];
|
|
2744
|
+
},
|
|
2745
|
+
{
|
|
2746
|
+
foreignKeyName: "operating_contexts_devices_lifecycle_changed_by_fkey";
|
|
2747
|
+
columns: ["lifecycle_changed_by"];
|
|
2748
|
+
isOneToOne: false;
|
|
2749
|
+
referencedRelation: "users";
|
|
2750
|
+
referencedColumns: ["id"];
|
|
2751
|
+
}
|
|
2752
|
+
];
|
|
2753
|
+
};
|
|
2684
2754
|
operators: {
|
|
2685
2755
|
Row: {
|
|
2686
2756
|
action: string | null;
|
|
@@ -4231,9 +4301,13 @@ export type Database = {
|
|
|
4231
4301
|
lifecycle_changed_by: string | null;
|
|
4232
4302
|
lifecycle_reason: string | null;
|
|
4233
4303
|
modality: string | null;
|
|
4304
|
+
proxy_file_path: string | null;
|
|
4305
|
+
proxy_generated_at: string | null;
|
|
4234
4306
|
segmented_at: string | null;
|
|
4235
4307
|
session_id: number | null;
|
|
4236
4308
|
tagged_at: string | null;
|
|
4309
|
+
thumbnail_file_path: string | null;
|
|
4310
|
+
thumbnail_generated_at: string | null;
|
|
4237
4311
|
timestamp_observation: string | null;
|
|
4238
4312
|
timestamp_observation_end: string;
|
|
4239
4313
|
tracked_at: string | null;
|
|
@@ -4263,9 +4337,13 @@ export type Database = {
|
|
|
4263
4337
|
lifecycle_changed_by: string | null;
|
|
4264
4338
|
lifecycle_reason: string | null;
|
|
4265
4339
|
modality: string | null;
|
|
4340
|
+
proxy_file_path: string | null;
|
|
4341
|
+
proxy_generated_at: string | null;
|
|
4266
4342
|
segmented_at: string | null;
|
|
4267
4343
|
session_id: number | null;
|
|
4268
4344
|
tagged_at: string | null;
|
|
4345
|
+
thumbnail_file_path: string | null;
|
|
4346
|
+
thumbnail_generated_at: string | null;
|
|
4269
4347
|
timestamp_observation: string | null;
|
|
4270
4348
|
timestamp_observation_end: string;
|
|
4271
4349
|
tracked_at: string | null;
|
|
@@ -4296,9 +4374,13 @@ export type Database = {
|
|
|
4296
4374
|
lifecycle_changed_by: string | null;
|
|
4297
4375
|
lifecycle_reason: string | null;
|
|
4298
4376
|
modality: string | null;
|
|
4377
|
+
proxy_file_path: string | null;
|
|
4378
|
+
proxy_generated_at: string | null;
|
|
4299
4379
|
segmented_at: string | null;
|
|
4300
4380
|
session_id: number | null;
|
|
4301
4381
|
tagged_at: string | null;
|
|
4382
|
+
thumbnail_file_path: string | null;
|
|
4383
|
+
thumbnail_generated_at: string | null;
|
|
4302
4384
|
timestamp_observation: string | null;
|
|
4303
4385
|
timestamp_observation_end: string;
|
|
4304
4386
|
tracked_at: string | null;
|
|
@@ -4329,9 +4411,13 @@ export type Database = {
|
|
|
4329
4411
|
lifecycle_changed_by: string | null;
|
|
4330
4412
|
lifecycle_reason: string | null;
|
|
4331
4413
|
modality: string | null;
|
|
4414
|
+
proxy_file_path: string | null;
|
|
4415
|
+
proxy_generated_at: string | null;
|
|
4332
4416
|
segmented_at: string | null;
|
|
4333
4417
|
session_id: number | null;
|
|
4334
4418
|
tagged_at: string | null;
|
|
4419
|
+
thumbnail_file_path: string | null;
|
|
4420
|
+
thumbnail_generated_at: string | null;
|
|
4335
4421
|
timestamp_observation: string | null;
|
|
4336
4422
|
timestamp_observation_end: string;
|
|
4337
4423
|
tracked_at: string | null;
|
|
@@ -4363,9 +4449,13 @@ export type Database = {
|
|
|
4363
4449
|
lifecycle_changed_by: string | null;
|
|
4364
4450
|
lifecycle_reason: string | null;
|
|
4365
4451
|
modality: string | null;
|
|
4452
|
+
proxy_file_path: string | null;
|
|
4453
|
+
proxy_generated_at: string | null;
|
|
4366
4454
|
segmented_at: string | null;
|
|
4367
4455
|
session_id: number | null;
|
|
4368
4456
|
tagged_at: string | null;
|
|
4457
|
+
thumbnail_file_path: string | null;
|
|
4458
|
+
thumbnail_generated_at: string | null;
|
|
4369
4459
|
timestamp_observation: string | null;
|
|
4370
4460
|
timestamp_observation_end: string;
|
|
4371
4461
|
tracked_at: string | null;
|
|
@@ -4397,9 +4487,13 @@ export type Database = {
|
|
|
4397
4487
|
lifecycle_changed_by: string | null;
|
|
4398
4488
|
lifecycle_reason: string | null;
|
|
4399
4489
|
modality: string | null;
|
|
4490
|
+
proxy_file_path: string | null;
|
|
4491
|
+
proxy_generated_at: string | null;
|
|
4400
4492
|
segmented_at: string | null;
|
|
4401
4493
|
session_id: number | null;
|
|
4402
4494
|
tagged_at: string | null;
|
|
4495
|
+
thumbnail_file_path: string | null;
|
|
4496
|
+
thumbnail_generated_at: string | null;
|
|
4403
4497
|
timestamp_observation: string | null;
|
|
4404
4498
|
timestamp_observation_end: string;
|
|
4405
4499
|
tracked_at: string | null;
|
|
@@ -4432,9 +4526,13 @@ export type Database = {
|
|
|
4432
4526
|
lifecycle_changed_by: string | null;
|
|
4433
4527
|
lifecycle_reason: string | null;
|
|
4434
4528
|
modality: string | null;
|
|
4529
|
+
proxy_file_path: string | null;
|
|
4530
|
+
proxy_generated_at: string | null;
|
|
4435
4531
|
segmented_at: string | null;
|
|
4436
4532
|
session_id: number | null;
|
|
4437
4533
|
tagged_at: string | null;
|
|
4534
|
+
thumbnail_file_path: string | null;
|
|
4535
|
+
thumbnail_generated_at: string | null;
|
|
4438
4536
|
timestamp_observation: string | null;
|
|
4439
4537
|
timestamp_observation_end: string;
|
|
4440
4538
|
tracked_at: string | null;
|
|
@@ -4466,9 +4564,13 @@ export type Database = {
|
|
|
4466
4564
|
lifecycle_changed_by: string | null;
|
|
4467
4565
|
lifecycle_reason: string | null;
|
|
4468
4566
|
modality: string | null;
|
|
4567
|
+
proxy_file_path: string | null;
|
|
4568
|
+
proxy_generated_at: string | null;
|
|
4469
4569
|
segmented_at: string | null;
|
|
4470
4570
|
session_id: number | null;
|
|
4471
4571
|
tagged_at: string | null;
|
|
4572
|
+
thumbnail_file_path: string | null;
|
|
4573
|
+
thumbnail_generated_at: string | null;
|
|
4472
4574
|
timestamp_observation: string | null;
|
|
4473
4575
|
timestamp_observation_end: string;
|
|
4474
4576
|
tracked_at: string | null;
|
|
@@ -4501,9 +4603,13 @@ export type Database = {
|
|
|
4501
4603
|
lifecycle_changed_by: string | null;
|
|
4502
4604
|
lifecycle_reason: string | null;
|
|
4503
4605
|
modality: string | null;
|
|
4606
|
+
proxy_file_path: string | null;
|
|
4607
|
+
proxy_generated_at: string | null;
|
|
4504
4608
|
segmented_at: string | null;
|
|
4505
4609
|
session_id: number | null;
|
|
4506
4610
|
tagged_at: string | null;
|
|
4611
|
+
thumbnail_file_path: string | null;
|
|
4612
|
+
thumbnail_generated_at: string | null;
|
|
4507
4613
|
timestamp_observation: string | null;
|
|
4508
4614
|
timestamp_observation_end: string;
|
|
4509
4615
|
tracked_at: string | null;
|