feat(camera): add camera management functionality and data flow documentation
- Implemented camera slice in Redux store for managing camera state. - Added new tables in PostgreSQL for camera devices, lending, and audit logs. - Created camera-related schemas in contracts for validation. - Developed camera data flow documentation outlining ingest and read processes. - Introduced async thunks for fetching, creating, lending, returning, and updating cameras.
This commit is contained in:
1 parent
7923ba1b8d
commit
d3b6c5032f
11 files changed
+2524
-114
No files matched your search
@@ -0,0 +1,128 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const cameraHealthSchema = z.enum(['online', 'offline', 'unknown']);
|
||||
|
||||
export const cameraDeviceSchema = z.object({
|
||||
cameraId: z.string().min(1),
|
||||
name: z.string().min(1),
|
||||
location: z.string().min(1),
|
||||
model: z.string().min(1).nullable(),
|
||||
notes: z.string().min(1).nullable(),
|
||||
isActive: z.boolean(),
|
||||
});
|
||||
|
||||
export const cameraDeviceUpdateSchema = z
|
||||
.object({
|
||||
name: z.string().min(1).optional(),
|
||||
location: z.string().min(1).optional(),
|
||||
model: z.string().min(1).nullable().optional(),
|
||||
notes: z.string().min(1).nullable().optional(),
|
||||
isActive: z.boolean().optional(),
|
||||
})
|
||||
.refine((value) => Object.keys(value).length > 0, {
|
||||
message: 'At least one field is required',
|
||||
});
|
||||
|
||||
export const cameraAuditActionSchema = z.enum([
|
||||
'camera_created',
|
||||
'camera_lent',
|
||||
'camera_returned',
|
||||
'camera_updated',
|
||||
'camera_activated',
|
||||
'camera_deactivated',
|
||||
'camera_soft_deleted',
|
||||
]);
|
||||
|
||||
export const cameraAuditLogSchema = z.object({
|
||||
id: z.number().int().positive(),
|
||||
cameraId: z.string().min(1),
|
||||
action: cameraAuditActionSchema,
|
||||
actor: z.string().min(1),
|
||||
metadata: z.record(z.unknown()),
|
||||
createdAt: z.string().datetime(),
|
||||
});
|
||||
|
||||
export const cameraAuditLogListSchema = z.object({
|
||||
items: z.array(cameraAuditLogSchema),
|
||||
});
|
||||
|
||||
export const cameraRuntimePayloadSchema = z.object({
|
||||
fps: z.number().int().nonnegative(),
|
||||
bitrateKbps: z.number().int().positive(),
|
||||
recording: z.boolean(),
|
||||
scene: z.string().min(1),
|
||||
});
|
||||
|
||||
export const cameraLatestStatusSchema = z.object({
|
||||
cameraId: z.string().min(1),
|
||||
lastSeen: z.string().datetime().nullable(),
|
||||
health: cameraHealthSchema,
|
||||
payload: cameraRuntimePayloadSchema.nullable(),
|
||||
});
|
||||
|
||||
export const cameraLendInfoSchema = z.object({
|
||||
borrower: z.string().min(1),
|
||||
dueDate: z.string().datetime(),
|
||||
purpose: z.string().min(1).optional(),
|
||||
lentAt: z.string().datetime(),
|
||||
});
|
||||
|
||||
export const cameraListItemSchema = z.object({
|
||||
cameraId: z.string().min(1),
|
||||
name: z.string().min(1),
|
||||
location: z.string().min(1),
|
||||
model: z.string().min(1).nullable(),
|
||||
notes: z.string().min(1).nullable(),
|
||||
isActive: z.boolean(),
|
||||
latest: cameraLatestStatusSchema,
|
||||
lend: cameraLendInfoSchema.nullable(),
|
||||
});
|
||||
|
||||
export const cameraListResponseSchema = z.object({
|
||||
items: z.array(cameraListItemSchema),
|
||||
});
|
||||
|
||||
export const cameraLendRequestSchema = z.object({
|
||||
borrower: z.string().min(1),
|
||||
dueDate: z.string().datetime(),
|
||||
purpose: z.string().min(1).optional(),
|
||||
});
|
||||
|
||||
export const cameraCreateRequestSchema = z.object({
|
||||
cameraId: z.string().min(1),
|
||||
name: z.string().min(1),
|
||||
location: z.string().min(1),
|
||||
model: z.string().min(1).nullable().optional(),
|
||||
notes: z.string().min(1).nullable().optional(),
|
||||
isActive: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const cameraReturnResponseSchema = z.object({
|
||||
cameraId: z.string().min(1),
|
||||
returned: z.boolean(),
|
||||
});
|
||||
|
||||
export const cameraSimulateIngestResponseSchema = z.object({
|
||||
accepted: z.boolean(),
|
||||
writes: z.object({
|
||||
mongo: z.boolean(),
|
||||
redis: z.boolean(),
|
||||
postgres: z.boolean(),
|
||||
}),
|
||||
latest: cameraLatestStatusSchema,
|
||||
});
|
||||
|
||||
export type CameraHealth = z.infer<typeof cameraHealthSchema>;
|
||||
export type CameraDevice = z.infer<typeof cameraDeviceSchema>;
|
||||
export type CameraDeviceUpdate = z.infer<typeof cameraDeviceUpdateSchema>;
|
||||
export type CameraAuditAction = z.infer<typeof cameraAuditActionSchema>;
|
||||
export type CameraAuditLog = z.infer<typeof cameraAuditLogSchema>;
|
||||
export type CameraRuntimePayload = z.infer<typeof cameraRuntimePayloadSchema>;
|
||||
export type CameraLatestStatus = z.infer<typeof cameraLatestStatusSchema>;
|
||||
export type CameraLendInfo = z.infer<typeof cameraLendInfoSchema>;
|
||||
export type CameraListItem = z.infer<typeof cameraListItemSchema>;
|
||||
export type CameraListResponse = z.infer<typeof cameraListResponseSchema>;
|
||||
export type CameraLendRequest = z.infer<typeof cameraLendRequestSchema>;
|
||||
export type CameraCreateRequest = z.infer<typeof cameraCreateRequestSchema>;
|
||||
export type CameraReturnResponse = z.infer<typeof cameraReturnResponseSchema>;
|
||||
export type CameraSimulateIngestResponse = z.infer<typeof cameraSimulateIngestResponseSchema>;
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './device-status.js';
|
||||
export * from './camera.js';
|
||||
export * from './greeting.js';
|
||||
export * from './presence.js';
|
||||
export * from './telemetry.js';
|
||||
Reference in new issue
Block a user