# Bloodbank Sdk Generation

> Generate typed SDK bindings (Pydantic v2 models, TypeScript types) from the Bloodbank JSON Schema tree at `bloodbank/schemas/bloodbank/v1/**` (Draft 2020-12). Uses `datamodel-code-generator` and `json-schema-to-typescript` — NOT the deprecated hand-rolled Holyfields generators. Use when generating event-contract bindings for a Bloodbank consumer, importing typed CloudEvents envelopes into another project, or scaffolding a `bloodbank-contracts` SDK package. Trigger keywords — "bloodbank SDK", "bloodbank contracts", "Pydantic from bloodbank schemas", "TypeScript types for bloodbank events", "bloodbank.v1.* types", "event contract bindings", "datamodel-code-generator", "json-schema-to-typescript", "regenerate SDK", "CloudEvents bindings". Do NOT use for schema authoring (edit `bloodbank/schemas/` directly per `docs/event-naming.md` §12), runtime envelope validation (use `BLOODBANK_HOOK_VALIDATE=1`), schema-tree consistency (`mise run smoketest:schemas`), or generic JSON Schema codegen unrelated to Bloodbank.

- Skill: `delorenj/bloodbank-sdk-generation` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds add delorenj/bloodbank-sdk-generation`
- Raw SKILL.md: https://api.skillmd.com/api/skills/delorenj/bloodbank-sdk-generation/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: delorenj (https://skillmd.com/u/delorenj)
- Updated: 2026-08-19
- Page: https://skillmd.com/skills/delorenj/bloodbank-sdk-generation

---


# Bloodbank SDK Generation

Deterministic recipe for generating typed bindings from `bloodbank/schemas/bloodbank/v1/**`. Outputs are plain artifacts the consumer commits or vendors — this skill produces code, not an installable package.

## Prereqs

- Run from the Bloodbank repo root (the directory containing `schemas/` and `docs/event-naming.md`), or pass the schema path explicitly.
- `uvx` (from `uv`) for Python tooling, `npx` for TypeScript tooling — both are project-less, no install required.
- Validate the tree is well-formed first: `mise run validate:schemas` (or `bash scripts/validate_schemas.sh`). Skip generation if it fails — fix schemas before generating.

## Python (Pydantic v2 models)

```bash
uvx --from 'datamodel-code-generator>=0.25' datamodel-codegen \
  --input schemas/bloodbank/v1 \
  --input-file-type jsonschema \
  --output-model-type pydantic_v2.BaseModel \
  --target-python-version 3.12 \
  --use-schema-description \
  --use-field-description \
  --use-double-quotes \
  --enum-field-as-literal one \
  --output bloodbank_contracts/models.py
```

Flag rationale:

- `--input-file-type jsonschema` — required; the default `auto` mis-detects when the tree has multiple files.
- `--enum-field-as-literal one` — `properties.type.const` becomes `Literal["bloodbank.v1.<...>"]`, matching the 5-token contract.
- `--use-schema-description` / `--use-field-description` — preserves the human-readable descriptions from the JSON Schemas as Pydantic field docstrings.
- `--target-python-version 3.12` — matches the project floor; bump if the project floor moves.

The generator resolves `$ref: "../../../_common/cloudevent_base.v1.json"` correctly because all schemas live under one input root.

## TypeScript (interfaces + type unions)

```bash
npx json-schema-to-typescript \
  'schemas/bloodbank/v1/**/*.v1.json' \
  --cwd schemas \
  --bannerComment '' \
  --unreachableDefinitions \
  --additionalProperties false \
  > bloodbank_contracts/types.ts
```

Flag rationale:

- `--cwd schemas` — sets the resolver root so `$ref: "../../../_common/..."` resolves from each file's directory through the same root the schemas were authored against.
- `--bannerComment ''` — drops the autogenerated header that fights with linters.
- `--unreachableDefinitions` — emits the `_common` types even if no top-level schema references them by name, so consumers can import `CloudEventBase` directly.
- `--additionalProperties false` — matches the strict-shape default of the runtime validator.

## Verify the output

After generation, run a one-shot import smoke:

```bash
# Python
python3 -c "from bloodbank_contracts.models import *; import bloodbank_contracts.models as m; print(f'{sum(1 for n in dir(m) if not n.startswith(\"_\")):>3} symbols')"

# TypeScript (requires tsc)
npx tsc --noEmit --strict bloodbank_contracts/types.ts
```

If either fails, regenerate from a clean `validate:schemas` pass before debugging the generator output.

## Common combinations

- **Refresh + commit on schema change**: re-run both generators whenever you edit anything under `bloodbank/schemas/bloodbank/v1/`. Treat the generated files as committed artifacts the consumer holds — git diff is the drift signal.
- **One-off consumer scaffold**: a downstream project that needs the types runs both commands once, vendors the outputs, and pins via the schema-tree commit hash recorded in their changelog.
- **Future packaging**: when a second external consumer materializes, promote `bloodbank_contracts/` into a real package (`uv build` for Python, `tsc --declaration` + `package.json` for TS). See `RECOMMENDATION.md` step 5 in the Bloodbank repo.

## Gotchas

Read `references/gotchas.md` only when generation fails with a non-obvious error, output looks wrong (missing fields, broken refs, unexpected types), or you're integrating the generated code into an existing project with its own Pydantic/Zod setup.

## Out of scope

This skill produces SDK artifacts from the canonical schema tree. It does NOT cover:

- **Authoring or modifying schemas.** Edit JSON files under `bloodbank/schemas/` directly per `bloodbank/docs/event-naming.md` §12.
- **Validating envelopes at runtime.** Set `BLOODBANK_HOOK_VALIDATE=1` and rely on `services/agent-hooks/core/validate.py`, which uses a pre-loaded `referencing.Registry`.
- **Checking schema-tree consistency.** Run `mise run validate:schemas` (well-formedness + ref resolution) and `mise run smoketest:schema-contract-consistency` (validator allowlist drift).
- **The deprecated Holyfields generators** (`tools/generators/generate_pydantic.py`, `tools/generators/generate_typescript.sh`). Those are hand-rolled, locked to Holyfields' `packages/python` workspace, and superseded by the third-party tools above. Do not port them.
- **Apicurio registry uploads.** The `apicurio://holyfields/<type>/versions/1` `dataschema` URI is a registry artifact id, separate from this skill's filesystem generation path.
- **Publishing the SDK** (PyPI, npm, GitHub Packages). This skill writes files; distribution is a separate decision.
- **Zod schemas.** `json-schema-to-typescript` emits TypeScript types + interfaces, not Zod validators. If runtime TS validation is needed, layer a tool like `json-schema-to-zod` on top — but evaluate whether the type-only output is sufficient first.

