Data Validation Schemas
Relevant source files
The following files were used as context for generating this wiki page:
Data validation in the Glimpse project is primarily handled using Zod for runtime type checking and Prisma for database schema enforcement. These schemas ensure that analytics events sent from client-side SDKs conform to a specific structure before being processed by the background workers or persisted in the PostgreSQL database. The project follows a "Type Safe" architecture, sharing schema definitions between the API and internal packages to maintain data integrity across the ingestion pipeline.
Sources: PROJECT_OUTLINE.md:144, app/api/controller/event.controller.ts:1-5
Core Validation Architecture
Glimpse utilizes a multi-layered validation strategy. Incoming requests are first validated at the API controller level using Zod. Validated data is then augmented with metadata (such as IP addresses and User Agents) before being queued for asynchronous processing. Finally, the database layer enforces relational constraints and data types defined in the Prisma schema.
Ingestion Validation Flow
The following diagram illustrates how data flows from a client request through the validation layers:
The API controller uses EventSchema.safeParse(body) to validate incoming JSON. If validation fails, it returns a formatted list of Zod issues including the path and error message.
Sources: app/api/controller/event.controller.ts:18-40, PROJECT_OUTLINE.md:108-118
Zod Runtime Schemas
The project defines its primary runtime validation logic in packages/shared/zod.schema.ts. This file contains the EventSchema, which is the blueprint for every analytics event tracked by the system.
EventSchema Structure
The EventSchema is a comprehensive object covering project identification, user sessions, and environmental context.
| Field | Type | Description |
|---|---|---|
projectId | String | Unique identifier for the project being tracked. |
event | String | The name of the event (e.g., "Page View", "Button Click"). |
timestamp | Number | Epoch timestamp of when the event occurred. |
anonymousId | String | UUID for anonymous user tracking. |
sessionId | String | Unique identifier for the current user session. |
traits | Object (Optional) | User-specific attributes like email or name. |
properties | Record | Custom key-value pairs associated with the event. |
context | Object | Metadata regarding URL, screen size, user agent, and network. |
Sources: packages/shared/zod.schema.ts:3-50
Extended Event Schema
For internal processing, the ExtendedEventSchema extends the base schema to include server-side metadata captured during the request.
export const ExtendedEventSchema = EventSchema.extend({
meta: z.object({
ip: z.string().optional(),
userAgent: z.string()
})
})
Sources: packages/shared/zod.schema.ts:54-59
Database Schema (Prisma)
The database schema reflects the validated Zod objects but adds persistence-specific fields such as auto-incrementing IDs, received timestamps, and geolocation data generated during processing.
Event Model Relationships
The Event model is the central entity in the database, indexed heavily for performance across project IDs and various user identifiers.
Database Model Definition
The Event model in schema.prisma includes fields for geolocation that are populated by the worker after the initial Zod validation at the API level.
| Field | Type | Constraints |
|---|---|---|
id | BigInt | Primary Key, Autoincrement |
projectId | String | Indexed |
occurredAt | DateTime | Indexed |
receivedAt | DateTime | Default: now() |
ip | String | Optional |
country | String | Optional (Added by Worker) |
lat / lon | Float | Optional (GeoIP data) |
Sources: packages/db/prisma/schema.prisma:18-50
Worker-Level Validation & Transformation
The eventWorker.ts process performs final checks and transformations before data is flushed to the database. It ensures that critical identifiers like sessionId and anonymousId exist, generating them if they were missed by the client SDK.
Validation Logic in Worker
- Identifier Generation: Uses
crypto.randomUUIDv7()ifsessionIdoranonymousIdare missing. - Geo-Lookup: Validates the IP address metadata and performs a lookup to append location data.
- Buffer Validation: Collects events into a
BufferDataarray. Once theMAX_BUFFER_SIZE(100) is reached or theBUFFER_FLUSH_INTERVAL(1000ms) passes, it flushes validated data to Postgres usingprisma.event.createMany.
Sources: app/workers/eventWorker.ts:63-115, app/workers/eventWorker.ts:25-27
Conclusion
Data validation in Glimpse is a serialized process that transitions from flexible client-side input to rigid database storage. By using Zod in a shared package, the system ensures that the API controller, background workers, and database all operate on a unified definition of what constitutes a valid "Event." This structure prevents malformed data from entering the analytics pipeline and provides clear error feedback to client applications.