{"_id":"@bldgtyp/web-report-schemas","_rev":"3-7753918a554823f5f746f4815c7e440e","name":"@bldgtyp/web-report-schemas","dist-tags":{"latest":"0.5.0"},"versions":{"0.3.0":{"name":"@bldgtyp/web-report-schemas","version":"0.3.0","license":"GPL-3.0-or-later","_id":"@bldgtyp/web-report-schemas@0.3.0","maintainers":[{"name":"edpmay","email":"ed@bldgtyp.com"}],"homepage":"https://github.com/bldgtyp/bt-web-report-schemas#readme","bugs":{"url":"https://github.com/bldgtyp/bt-web-report-schemas/issues"},"dist":{"shasum":"695f9c6436d4fc047c9216f4610ac128a050c4de","tarball":"https://registry.npmjs.org/@bldgtyp/web-report-schemas/-/web-report-schemas-0.3.0.tgz","fileCount":6,"integrity":"sha512-HKFl5C98IPpfAGt2ZrrRVluuulXwBXmpPcC26jdlLQjUQ+T5YMU842dSPlYW7jk4CrtGVL0dUmBhzl8Wq9d7/A==","signatures":[{"sig":"MEUCIDJ5ErifqK0nSNR7MSV7gJWY+3edvrbuYUg3+w3cwVjqAiEA3WuTu78rEV9y3PnILZDyHeHTD9fuReitOoTaY20SMfI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":32022},"main":"./src-js/index.ts","type":"module","_from":"file:bldgtyp-web-report-schemas-0.3.0.tgz","types":"./src-js/index.ts","exports":{".":"./src-js/index.ts","./project.schema.json":"./schemas/project.schema.json","./manifest.schema.json":"./schemas/manifest.schema.json"},"_npmUser":{"name":"edpmay","email":"ed@bldgtyp.com"},"_resolved":"/tmp/6a4deb886933985eff321a4b85af69ac/bldgtyp-web-report-schemas-0.3.0.tgz","_integrity":"sha512-HKFl5C98IPpfAGt2ZrrRVluuulXwBXmpPcC26jdlLQjUQ+T5YMU842dSPlYW7jk4CrtGVL0dUmBhzl8Wq9d7/A==","repository":{"url":"git+https://github.com/bldgtyp/bt-web-report-schemas.git","type":"git"},"_npmVersion":"11.12.1","description":"JSON Schemas + TypeScript types for the bt-web-report platform (project.yaml, manifest.json).","directories":{},"_nodeVersion":"24.15.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/web-report-schemas_0.3.0_1779503301943_0.2178608948427807","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@bldgtyp/web-report-schemas","version":"0.4.0","license":"GPL-3.0-or-later","_id":"@bldgtyp/web-report-schemas@0.4.0","maintainers":[{"name":"edpmay","email":"ed@bldgtyp.com"}],"homepage":"https://github.com/bldgtyp/bt-web-report-schemas#readme","bugs":{"url":"https://github.com/bldgtyp/bt-web-report-schemas/issues"},"dist":{"shasum":"cab98b7c47d7605b9cb6bb4423c89bbfc52913f1","tarball":"https://registry.npmjs.org/@bldgtyp/web-report-schemas/-/web-report-schemas-0.4.0.tgz","fileCount":6,"integrity":"sha512-XuOf93o1ocVcrwJqWi0j40OtPBwn4tR8ybugitWIeiDBdOFSqhXtLc2zUWY5iliVs/4OY/R9nDhf2CA4WMBsJQ==","signatures":[{"sig":"MEUCIEhIJFYPqOCd/YTCIc7MXm/A04MKYLTqk1HFBopl1QHvAiEAintaC4jhCckocRtSjBlPGLpHqKdyIYsc9905hdPXq9M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":33638},"main":"./src-js/index.ts","type":"module","_from":"file:bldgtyp-web-report-schemas-0.4.0.tgz","types":"./src-js/index.ts","exports":{".":"./src-js/index.ts","./project.schema.json":"./schemas/project.schema.json","./manifest.schema.json":"./schemas/manifest.schema.json"},"_npmUser":{"name":"edpmay","email":"ed@bldgtyp.com"},"_resolved":"/tmp/2f247e05cce99399a63e4a287a4b0e7a/bldgtyp-web-report-schemas-0.4.0.tgz","_integrity":"sha512-XuOf93o1ocVcrwJqWi0j40OtPBwn4tR8ybugitWIeiDBdOFSqhXtLc2zUWY5iliVs/4OY/R9nDhf2CA4WMBsJQ==","repository":{"url":"git+https://github.com/bldgtyp/bt-web-report-schemas.git","type":"git"},"_npmVersion":"11.16.0","description":"JSON Schemas + TypeScript types for the bt-web-report platform (project.yaml, manifest.json).","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/web-report-schemas_0.4.0_1784586632407_0.4952460589964569","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"_id":"@bldgtyp/web-report-schemas@0.5.0","bugs":{"url":"https://github.com/bldgtyp/bt-web-report-schemas/issues"},"dist":{"shasum":"a5663072714e19e18e2f2925e680f35395f6f9bf","tarball":"https://registry.npmjs.org/@bldgtyp/web-report-schemas/-/web-report-schemas-0.5.0.tgz","fileCount":6,"integrity":"sha512-g0WP4PI868LBGbYmGjDS8dV3ZaGAz0/VqB7GJwiufhBkCwPmZxRyWSVMdeLLMnqgacfEHCFAGPvV4u+Hy5q2ow==","signatures":[{"sig":"MEUCIQDYLFlCb1SkpGn5JkpHJX5v4q7rc5OWW9UehrJ2lOA6mwIgd9kqcC8Vbn7fIn54XqgatyW8Ua1NfQr3Z46LD8scl1g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEvLiGWGf3Nb+0QwpsYFKVzRDIUvfeAS+F7fvt5uGQsfAiAZfqjhVenNmvfDaLK7qEVG7ntEvyCrOL1PIM0KjLOOvg=="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bldgtyp%2fweb-report-schemas@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":35428},"main":"./src-js/index.ts","name":"@bldgtyp/web-report-schemas","type":"module","types":"./src-js/index.ts","exports":{".":"./src-js/index.ts","./project.schema.json":"./schemas/project.schema.json","./manifest.schema.json":"./schemas/manifest.schema.json"},"gitHead":"359a8f83c8079b040f771a0a3f4a9d6608023bda","license":"GPL-3.0-or-later","version":"0.5.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:21e72bf5-5d84-4e76-af4d-0b7938cc3123"}},"homepage":"https://github.com/bldgtyp/bt-web-report-schemas#readme","repository":{"url":"git+https://github.com/bldgtyp/bt-web-report-schemas.git","type":"git"},"_npmVersion":"11.19.0","description":"JSON Schemas + TypeScript types for the bt-web-report platform (project.yaml, manifest.json).","directories":{},"maintainers":[{"name":"edpmay","email":"ed@bldgtyp.com"}],"_nodeVersion":"24.20.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/web-report-schemas_0.5.0_1789579355464_0.8166912754995859"}}},"time":{"created":"2026-05-23T02:28:21.848Z","modified":"2026-09-16T17:22:36.028Z","0.3.0":"2026-05-23T02:28:22.111Z","0.4.0":"2026-07-20T22:30:32.563Z","0.5.0":"2026-09-16T17:22:35.649Z"},"bugs":{"url":"https://github.com/bldgtyp/bt-web-report-schemas/issues"},"license":"GPL-3.0-or-later","homepage":"https://github.com/bldgtyp/bt-web-report-schemas#readme","repository":{"url":"git+https://github.com/bldgtyp/bt-web-report-schemas.git","type":"git"},"description":"JSON Schemas + TypeScript types for the bt-web-report platform (project.yaml, manifest.json).","maintainers":[{"name":"edpmay","email":"ed@bldgtyp.com"}],"readme":"# bt-web-report-schemas\n\nShared schemas for the `bt-web-report` platform. Dual-published as a Python\npackage (`bt-web-report-schemas`) and an npm package\n(`@bldgtyp/web-report-schemas`) from the same repo so the Python CLI, the\nAstro renderer, the TinaCMS editor, and the Manager UI all validate against\nidentical shapes.\n\nThe **Pydantic models in `src/bt_web_report_schemas/` are the single source\nof truth.** JSON Schemas under `schemas/` are generated artifacts; ajv-side\nand Tina-side consumers read them via the npm package's `exports` map. A\ndrift test in `tests/test_json_schema_generation.py` fails CI if the\non-disk JSON ever falls out of sync with the Pydantic source.\n\n## Contents\n\n```\nbt-web-report-schemas/\n├── src/bt_web_report_schemas/         Python (source of truth)\n│   ├── project.py                     project.yaml — top-level metadata\n│   │                                  + narrative block (grouped per-section\n│   │                                  prose-facing values plus user_defined)\n│   ├── manifest.py                    data/manifest.json — scrape output\n│   ├── phpp/                          per-version PHPP row maps (v10.6, …)\n│   └── gen_json_schemas.py            CLI: `uv run gen-json-schemas`\n│\n├── schemas/                           Generated; DO NOT hand-edit\n│   ├── project.schema.json\n│   └── manifest.schema.json\n│\n├── src-js/                            JS half\n│   ├── index.ts                       VERSION constants + helpers re-export\n│   └── var-keys.ts                    walks project.schema.json → dropdown\n│                                      options for the <Var> shortcode\n│\n└── tests/                             pytest\n    ├── test_project_schema.py         Pydantic validation rules\n    ├── test_json_schema_generation.py drift guard\n    └── test_phpp_schema.py            PHPP row-map regression\n```\n\n## Regenerating the JSON Schemas\n\nAfter editing any Pydantic model, regenerate:\n\n```bash\nuv run gen-json-schemas\n```\n\nThis writes both `schemas/project.schema.json` and\n`schemas/manifest.schema.json` deterministically (sorted keys, trailing\nnewline). Commit the diff alongside the model change. CI fails if you forget.\n\n## JS consumers\n\nImports flow through the npm package's `exports` map:\n\n```ts\n// Static schema for ajv / validation\nimport projectSchema from \"@bldgtyp/web-report-schemas/project.schema.json\";\nimport manifestSchema from \"@bldgtyp/web-report-schemas/manifest.schema.json\";\n\n// Helper: dot-path dropdown options for the <Var> shortcode\nimport { listVarKeyOptions } from \"@bldgtyp/web-report-schemas\";\nconst options = listVarKeyOptions({ stripLabelSegments: [\"Narrative\"] });\n// → [{ value: \"client_name\", label: \"Client Name\" },\n//    { value: \"narrative.climate.weather_station_name\",\n//      label: \"Climate > Weather Station Name\" }, …]\n```\n\nThe `bt-web-report-template` package consumes both: ajv reads\n`project.schema.json` in `src/data/project-schema.mjs`, and Tina's\n`tina/config.ts` feeds `listVarKeyOptions()` into the `<Var>` rich-text\ntemplate.\n\n## Python consumers\n\n```python\nfrom bt_web_report_schemas.project import Project\n\nwith open(\"project.yaml\") as f:\n    project = Project.model_validate(yaml.safe_load(f))\n```\n\n`Project` is a frozen Pydantic v2 model with `extra=\"forbid\"` — unknown\nkeys (e.g. typos like `mechancial`) fail loudly instead of silently\ndropping values.\n\n## Adding a new project.yaml field\n\nFor one-off project prose values, put them under `narrative.user_defined.*`\ninstead of changing the schema:\n\n```yaml\nnarrative:\n  user_defined:\n    cad_received_date: May 1, 2026\n```\n\nFor a reusable standard field:\n\n1. Add the field to the appropriate model in `src/bt_web_report_schemas/project.py`.\n   For narrative prose values, that's one of `CertificationNarrative`,\n   `ClimateNarrative`, `EnergyCodeNarrative`, `Co2Narrative`,\n   `WindowsNarrative`, or `MechanicalNarrative`. All narrative fields are\n   `str | None` — values flow into prose, never into calculations.\n2. Run `uv run gen-json-schemas` and commit the regenerated JSON.\n3. Add the value to the relevant `project.yaml` files.\n\nThe Tina dropdown picks up the new field automatically — no hand-editing\nof `tina/config.ts` required.\n\n## Versioning\n\n| Schema | Current | Pinned via |\n|---|---|---|\n| `Project` | `0.2.0` | `Literal[\"0.2.0\"]` on `schema_version` |\n| `Manifest` | `1.0.0` | default in `manifest.py` |\n\nSchema version is a hard equality check — bump it whenever the shape\nchanges in a way that an existing `project.yaml` wouldn't validate against.\n\nSee [`../context/repos-and-workflows.html#end-to-end`](../context/repos-and-workflows.html#end-to-end) for\nhow these schemas fit into the broader data flow.\n","readmeFilename":"README.md"}