generated from john/python-template
Begin planning V2
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
## TypeScript Zod schemas
|
||||
|
||||
Here are the TypeScript Zod schemas matching your V2 PostgreSQL database definition.
|
||||
|
||||
These schemas cover:
|
||||
1. Database Entities: Pure runtime validators representing rows fetched directly from PostgreSQL.
|
||||
2. AI Payload Extensions: The structured document output stored inside job.ai_metadata.
|
||||
3. Insert/Create Schemas: Utility types derived with .omit() for creating new records where auto-generated columns (id, created_at, updated_at, etc.) are handled by PostgreSQL defaults.
|
||||
|
||||
---
|
||||
|
||||
```
|
||||
import { z } from "zod";
|
||||
|
||||
// ==========================================
|
||||
// 1. ATOMIC & REUSABLE SCHEMAS
|
||||
// ==========================================
|
||||
|
||||
export const UUIDSchema = z.string().uuid();
|
||||
export const ISODateTimeSchema = z.coerce.date();
|
||||
|
||||
export const BoundingBoxSchema = z.object({
|
||||
ymin: z.number().min(0).max(1000),
|
||||
xmin: z.number().min(0).max(1000),
|
||||
ymax: z.number().min(0).max(1000),
|
||||
xmax: z.number().min(0).max(1000),
|
||||
});
|
||||
|
||||
export const BlockTypeSchema = z.enum([
|
||||
"heading",
|
||||
"paragraph",
|
||||
"table",
|
||||
"margin_note",
|
||||
"signature",
|
||||
"footnote",
|
||||
"header",
|
||||
]);
|
||||
|
||||
// ==========================================
|
||||
// 2. PAGE-LEVEL AI METADATA SCHEMA (job_source.ai_metadata)
|
||||
// ==========================================
|
||||
|
||||
export const TranscribedBlockSchema = z.object({
|
||||
text: z.string(),
|
||||
confidence: z.number().min(0).max(1),
|
||||
blockType: BlockTypeSchema,
|
||||
boundingBox: BoundingBoxSchema.optional(),
|
||||
});
|
||||
|
||||
export const PageAIMetadataSchema = z.object({
|
||||
detectedLanguage: z.string().optional(),
|
||||
overallConfidence: z.number().min(0).max(1),
|
||||
blocks: z.array(TranscribedBlockSchema),
|
||||
inputTokens: z.number().optional(),
|
||||
outputTokens: z.number().optional(),
|
||||
extractedEntities: z.record(z.string(), z.unknown()).optional(),
|
||||
});
|
||||
|
||||
export type PageAIMetadata = z.infer<typeof PageAIMetadataSchema>;
|
||||
|
||||
// ==========================================
|
||||
// 3. TABLE ENTITY SCHEMAS
|
||||
// ==========================================
|
||||
|
||||
// --- PERSON TABLE ---
|
||||
export const PersonSchema = z.object({
|
||||
id: UUIDSchema,
|
||||
fullName: z.string().min(1),
|
||||
displayName: z.string().nullable().optional(),
|
||||
maidenName: z.string().nullable().optional(),
|
||||
birthDate: z.string().nullable().optional(),
|
||||
birthDateRaw: z.string().nullable().optional(),
|
||||
birthPlace: z.string().nullable().optional(),
|
||||
deathDate: z.string().nullable().optional(),
|
||||
deathDateRaw: z.string().nullable().optional(),
|
||||
deathPlace: z.string().nullable().optional(),
|
||||
biography: z.string().nullable().optional(),
|
||||
portraitPath: z.string().nullable().optional(),
|
||||
metadata: z.record(z.string(), z.unknown()).default({}),
|
||||
createdAt: ISODateTimeSchema,
|
||||
updatedAt: ISODateTimeSchema,
|
||||
});
|
||||
|
||||
// --- DOCUMENT TABLE ---
|
||||
export const DocumentSchema = z.object({
|
||||
id: UUIDSchema,
|
||||
name: z.string().min(1),
|
||||
documentType: z.string().nullable().optional(),
|
||||
documentDate: z.string().nullable().optional(),
|
||||
documentDateRaw: z.string().nullable().optional(),
|
||||
locationCreated: z.string().nullable().optional(),
|
||||
notes: z.string().nullable().optional(),
|
||||
archiveIdentifier: z.string().nullable().optional(),
|
||||
createdAt: ISODateTimeSchema,
|
||||
updatedAt: ISODateTimeSchema,
|
||||
});
|
||||
|
||||
// --- DOCUMENT_PERSON JUNCTION ---
|
||||
export const PersonRoleSchema = z.enum(["author", "recipient"]);
|
||||
|
||||
export const DocumentPersonSchema = z.object({
|
||||
id: UUIDSchema,
|
||||
documentId: UUIDSchema,
|
||||
personId: UUIDSchema,
|
||||
role: PersonRoleSchema,
|
||||
createdAt: ISODateTimeSchema,
|
||||
});
|
||||
|
||||
// --- JOB TABLE ---
|
||||
export const JobStatusSchema = z.enum([
|
||||
"queued",
|
||||
"processing",
|
||||
"completed",
|
||||
"partial_success",
|
||||
"failed",
|
||||
]);
|
||||
|
||||
export const JobSchema = z.object({
|
||||
id: UUIDSchema,
|
||||
documentId: UUIDSchema,
|
||||
status: JobStatusSchema.default("queued"),
|
||||
retryCount: z.number().int().nonnegative().default(0),
|
||||
provider: z.string(),
|
||||
model: z.string(),
|
||||
promptName: z.string().nullable().optional(),
|
||||
dateCreated: ISODateTimeSchema,
|
||||
dateUpdated: ISODateTimeSchema,
|
||||
});
|
||||
|
||||
// --- SOURCE TABLE ---
|
||||
export const SourceSchema = z.object({
|
||||
id: UUIDSchema,
|
||||
documentId: UUIDSchema,
|
||||
pageNumber: z.number().int().positive().default(1),
|
||||
uploadName: z.string(),
|
||||
filename: z.string(),
|
||||
filePath: z.string(),
|
||||
rawTranscription: z.string().nullable().optional(),
|
||||
revisedText: z.string().nullable().optional(),
|
||||
dateUploaded: ISODateTimeSchema,
|
||||
dateRevised: ISODateTimeSchema.nullable().optional(),
|
||||
});
|
||||
|
||||
// --- JOB_SOURCE JUNCTION (Page Execution Output) ---
|
||||
export const JobSourceStatusSchema = z.enum([
|
||||
"pending",
|
||||
"transcribed",
|
||||
"failed",
|
||||
]);
|
||||
|
||||
export const JobSourceSchema = z.object({
|
||||
id: UUIDSchema,
|
||||
jobId: UUIDSchema,
|
||||
sourceId: UUIDSchema,
|
||||
status: JobSourceStatusSchema.default("pending"),
|
||||
rawTranscription: z.string().nullable().optional(),
|
||||
aiMetadata: PageAIMetadataSchema.nullable().optional(),
|
||||
rawApiResponse: z.record(z.string(), z.unknown()).nullable().optional(),
|
||||
errorDetail: z.string().nullable().optional(),
|
||||
executedAt: ISODateTimeSchema,
|
||||
});
|
||||
|
||||
export type Person = z.infer<typeof PersonSchema>;
|
||||
export type Document = z.infer<typeof DocumentSchema>;
|
||||
export type DocumentPerson = z.infer<typeof DocumentPersonSchema>;
|
||||
export type Job = z.infer<typeof JobSchema>;
|
||||
export type Source = z.infer<typeof SourceSchema>;
|
||||
export type JobSource = z.infer<typeof JobSourceSchema>;
|
||||
```
|
||||
Reference in New Issue
Block a user