Skip to main content

Code generation pipeline

All API-facing models are auto-generated from backend Zod schemas via a two-stage pipeline. This ensures the iOS app and backend always agree on data shapes.

Two-stage codegen

Never hand-edit any .generated.swift file. Changes will be overwritten on the next generation run. If the model needs to change, update the Zod schema in the backend and regenerate.

Running the generator

This reads the Zod schemas, converts them to JSON Schema, then runs quicktype to produce Swift files with matching Codable structs.

Shared between targets

All generated files are included in both the main app target and the widget target (SightscreenWidget). This guarantees that the widget’s Live Activity rendering uses the exact same types as the main app.

Generated model files

LiveActivityModels.generated.swift

The primary generated file for Live Activity payloads. Contains the full display state hierarchy.
LiveActivityAttributes is set once at creation time and cannot change. ContentState is updated with every push. Anything that changes during a match must be in ContentState.

FollowModels.generated.swift

Models for the follow/unfollow system.

HubAPIModels.generated.swift

Models for the main hub/schedule API responses.

Hand-written models

Some models are hand-written because they contain client-side logic or do not map to a backend schema.

Auth models

Core models


Model conventions

All models (generated and hand-written) follow these conventions:

JSON decoding strategy

The app configures a shared JSONDecoder with ISO 8601 date support that handles both fractional seconds and standard formats.
The dual-format decoder exists because some backend responses include fractional seconds (e.g., 2024-03-15T10:30:00.000Z) and others do not (e.g., 2024-03-15T10:30:00Z). Both must decode correctly.

API format notes

Most transformations are handled automatically by CodingKeys enums. Only use custom init(from:) implementations for genuinely complex mappings.