{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://parentsvaccineguide.org/schemas/vaccine_product_ingredients.schema.json",
  "title": "Vaccine Product Ingredients (Package Insert Composition)",
  "description": "Structured composition of a branded vaccine product as stated on the FDA-approved package insert / DailyMed Section 11 DESCRIPTION. One record per branded product — never collapsed across manufacturers. Primary fields: antigens, adjuvants, excipients, preservatives, encapsulation, deliveryMethod.",
  "type": "object",
  "required": ["_meta", "products"],
  "additionalProperties": false,
  "properties": {
    "_meta": {
      "type": "object",
      "required": ["description", "lastUpdated", "sourcingRule"],
      "additionalProperties": true,
      "properties": {
        "description": { "type": "string" },
        "lastUpdated": { "type": "string", "format": "date" },
        "sourcingRule": { "type": "string" },
        "schemaVersion": { "type": "string" }
      }
    },
    "products": {
      "type": "object",
      "description": "Map of vaccine page slug (e.g. mmr-vaccine) → array of branded product composition records.",
      "additionalProperties": {
        "type": "array",
        "items": { "$ref": "#/$defs/productComposition" },
        "minItems": 1
      }
    }
  },
  "$defs": {
    "amountString": {
      "type": "string",
      "description": "Per-dose quantity exactly as stated on the label, or a clear statement when not quantified (e.g. 'trace residual', 'none', 'not individually quantified on label')."
    },
    "ingredientItem": {
      "type": "object",
      "required": ["name"],
      "additionalProperties": false,
      "properties": {
        "name": {
          "type": "string",
          "description": "Ingredient name as on the package insert (or standard pharmacopeial synonym)."
        },
        "slug": {
          "type": ["string", "null"],
          "description": "Optional link key into ingredients/ingredients_master.json when a shared safety page exists."
        },
        "amount": { "$ref": "#/$defs/amountString" },
        "role": {
          "type": "string",
          "description": "Short mechanistic role on this product (e.g. stabilizer, buffer, residual from cell culture)."
        },
        "category": {
          "type": "string",
          "enum": [
            "stabilizer",
            "buffer",
            "surfactant",
            "diluent",
            "residual_manufacturing",
            "inactivating_agent_residual",
            "antibiotic_residual",
            "culture_medium_residual",
            "lipid_component",
            "other"
          ]
        },
        "notes": { "type": "string" }
      }
    },
    "antigenItem": {
      "type": "object",
      "required": ["name", "antigenType"],
      "additionalProperties": false,
      "properties": {
        "name": {
          "type": "string",
          "description": "Antigen name / strain / component as on the label."
        },
        "antigenType": {
          "type": "string",
          "enum": [
            "live_attenuated_virus",
            "live_attenuated_bacteria",
            "inactivated_virus",
            "inactivated_bacteria",
            "toxoid",
            "subunit_protein",
            "recombinant_protein",
            "polysaccharide",
            "conjugate",
            "virus_like_particle",
            "mrna",
            "viral_vector",
            "outer_membrane_vesicle",
            "other"
          ]
        },
        "amount": { "$ref": "#/$defs/amountString" },
        "strain": { "type": "string" },
        "expressionSystem": {
          "type": "string",
          "description": "e.g. Saccharomyces cerevisiae, chick embryo cell culture, MRC-5, synthetic mRNA."
        },
        "carrierProtein": {
          "type": "string",
          "description": "For conjugates: CRM197, tetanus toxoid, OMP, etc."
        },
        "notes": { "type": "string" }
      }
    },
    "adjuvantItem": {
      "type": "object",
      "required": ["name"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string" },
        "slug": { "type": ["string", "null"] },
        "class": {
          "type": "string",
          "enum": [
            "aluminum_salt",
            "oil_in_water_emulsion",
            "tlr_agonist",
            "as01_liposomal",
            "as03",
            "as04",
            "mf59",
            "matrix_m",
            "cpg",
            "none",
            "other"
          ]
        },
        "amount": { "$ref": "#/$defs/amountString" },
        "aluminumContent": {
          "type": "string",
          "description": "Elemental aluminum per dose when applicable (label units)."
        },
        "components": {
          "type": "array",
          "description": "Sub-components of multi-part adjuvant systems (e.g. MPL + QS-21 in AS01).",
          "items": { "$ref": "#/$defs/ingredientItem" }
        },
        "notes": { "type": "string" }
      }
    },
    "preservativeItem": {
      "type": "object",
      "required": ["name", "present"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string" },
        "slug": { "type": ["string", "null"] },
        "present": {
          "type": "boolean",
          "description": "False when the label states no preservative (typical for single-dose products)."
        },
        "amount": { "$ref": "#/$defs/amountString" },
        "presentationNote": {
          "type": "string",
          "description": "e.g. multi-dose vial only; single-dose syringes contain none."
        },
        "notes": { "type": "string" }
      }
    },
    "encapsulationComponent": {
      "type": "object",
      "required": ["name", "role"],
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string" },
        "slug": { "type": ["string", "null"] },
        "role": {
          "type": "string",
          "enum": [
            "ionizable_lipid",
            "pegylated_lipid",
            "helper_phospholipid",
            "cholesterol",
            "liposomal_phospholipid",
            "saponin",
            "other"
          ]
        },
        "amount": { "$ref": "#/$defs/amountString" },
        "notes": { "type": "string" }
      }
    },
    "encapsulation": {
      "type": "object",
      "required": ["type"],
      "additionalProperties": false,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "none",
            "lipid_nanoparticle",
            "liposome",
            "virus_like_particle",
            "virosome",
            "outer_membrane_vesicle",
            "protein_nanoparticle",
            "other"
          ],
          "description": "Physical/chemical delivery vehicle distinct from classical adjuvants when applicable (e.g. LNP for mRNA)."
        },
        "description": { "type": "string" },
        "components": {
          "type": "array",
          "items": { "$ref": "#/$defs/encapsulationComponent" }
        },
        "notes": { "type": "string" }
      }
    },
    "deliveryMethod": {
      "type": "object",
      "required": ["route", "form"],
      "additionalProperties": false,
      "properties": {
        "route": {
          "type": "string",
          "enum": [
            "intramuscular",
            "subcutaneous",
            "intradermal",
            "oral",
            "intranasal",
            "intramuscular_or_subcutaneous",
            "other"
          ]
        },
        "form": {
          "type": "string",
          "enum": [
            "suspension_for_injection",
            "lyophilized_powder_for_reconstitution",
            "solution_for_injection",
            "oral_solution",
            "enteric_coated_capsule",
            "nasal_spray",
            "prefilled_syringe",
            "other"
          ]
        },
        "doseVolume": { "type": "string" },
        "presentation": {
          "type": "string",
          "description": "e.g. single-dose vial, multi-dose vial, prefilled syringe, blister of capsules."
        },
        "requiresReconstitution": { "type": "boolean" },
        "diluent": { "type": "string" },
        "notes": { "type": "string" }
      }
    },
    "source": {
      "type": "object",
      "required": ["sourceUrl", "sourceType", "lastVerified"],
      "additionalProperties": false,
      "properties": {
        "sourceUrl": {
          "type": "string",
          "format": "uri",
          "description": "Canonical DailyMed, FDA, or manufacturer PI URL."
        },
        "sourceType": {
          "type": "string",
          "enum": [
            "DailyMed",
            "FDA package insert",
            "Manufacturer prescribing information",
            "FDA review document"
          ]
        },
        "lastVerified": { "type": "string", "format": "date" },
        "section": {
          "type": "string",
          "description": "Usually '11 DESCRIPTION' or equivalent."
        },
        "setId": {
          "type": "string",
          "description": "DailyMed setid when known."
        }
      }
    },
    "productComposition": {
      "type": "object",
      "required": [
        "productId",
        "productName",
        "manufacturer",
        "vaccineSlug",
        "platform",
        "deliveryMethod",
        "encapsulation",
        "antigens",
        "adjuvants",
        "preservatives",
        "excipients",
        "source"
      ],
      "additionalProperties": false,
      "properties": {
        "productId": {
          "type": "string",
          "description": "Stable slug unique across the catalog (e.g. mmr-ii, comirnaty)."
        },
        "productName": { "type": "string" },
        "manufacturer": { "type": "string" },
        "vaccineSlug": {
          "type": "string",
          "description": "Site page key without .html (e.g. mmr-vaccine)."
        },
        "platform": {
          "type": "string",
          "enum": [
            "live_attenuated",
            "inactivated",
            "toxoid",
            "subunit",
            "conjugate",
            "recombinant_protein",
            "vlp",
            "mrna",
            "viral_vector",
            "combination",
            "other"
          ]
        },
        "deliveryMethod": { "$ref": "#/$defs/deliveryMethod" },
        "encapsulation": { "$ref": "#/$defs/encapsulation" },
        "antigens": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/antigenItem" }
        },
        "adjuvants": {
          "type": "array",
          "description": "Empty array if the product has no adjuvant (common for live and many inactivated whole-virus vaccines). Use a single item with class 'none' only when you need an explicit labeled statement; prefer empty array + notes.",
          "items": { "$ref": "#/$defs/adjuvantItem" }
        },
        "preservatives": {
          "type": "array",
          "minItems": 1,
          "description": "Always present: either present:true with amount, or present:false (no preservative).",
          "items": { "$ref": "#/$defs/preservativeItem" }
        },
        "excipients": {
          "type": "array",
          "description": "Stabilizers, buffers, surfactants, diluents, and residual manufacturing substances — everything that is not antigen, adjuvant, preservative, or encapsulation lipid system. Encapsulation lipids go under encapsulation.components, not here.",
          "items": { "$ref": "#/$defs/ingredientItem" }
        },
        "ingredientSlugs": {
          "type": "array",
          "description": "Convenience reverse-index into ingredients_master.json (union of adjuvant/preservative/excipient/encapsulation slugs).",
          "items": { "type": "string" },
          "uniqueItems": true
        },
        "source": { "$ref": "#/$defs/source" },
        "notes": { "type": "string" },
        "latex": {
          "type": "string",
          "description": "Natural rubber latex status of vial stopper / syringe tip cap when labeled."
        }
      }
    }
  }
}
