From fcbce4f6f6e03d5928daa8b7d91ef17999219200 Mon Sep 17 00:00:00 2001 From: Andrew Griess Date: Wed, 15 Jul 2026 10:32:51 -0500 Subject: [PATCH] Initialize catalog structure and product schema --- README.md | 45 +++++++ catalog/.gitkeep | 0 docs/field-reference.md | 33 +++++ exports/.gitkeep | 0 images/.gitkeep | 0 indexes/.gitkeep | 0 schema/product.schema.json | 243 +++++++++++++++++++++++++++++++++++++ 7 files changed, 321 insertions(+) create mode 100644 README.md create mode 100644 catalog/.gitkeep create mode 100644 docs/field-reference.md create mode 100644 exports/.gitkeep create mode 100644 images/.gitkeep create mode 100644 indexes/.gitkeep create mode 100644 schema/product.schema.json diff --git a/README.md b/README.md new file mode 100644 index 0000000..fcc49be --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# RoundCount Catalog + +RoundCount Catalog is a machine-readable ammunition product database for the RoundCount inventory system. + +The catalog stores reusable product information such as: + +- UPC +- Manufacturer SKU +- Manufacturer +- Brand +- Product name +- Caliber +- Bullet weight and type +- Case material +- Package quantity +- Ballistic information +- Product images +- Source and verification information + +Personal inventory information such as quantities, purchase prices, storage locations, and lot numbers does not belong in this repository. + +## Repository Structure + +```text +schema/ + JSON schemas used to validate catalog records + +catalog/ + Individual ammunition product records + +images/ + Product images organized by manufacturer + +indexes/ + Generated UPC, SKU, and manufacturer indexes + +exports/ + Generated combined catalog downloads + +docs/ + Catalog documentation and contribution guides + +tools/ + Validation, indexing, and export scripts +EFO diff --git a/catalog/.gitkeep b/catalog/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/field-reference.md b/docs/field-reference.md new file mode 100644 index 0000000..2dd2922 --- /dev/null +++ b/docs/field-reference.md @@ -0,0 +1,33 @@ +# Catalog Field Reference + +## Required Fields + +### `catalog_version` + +Catalog record format version. + +Current value: + +```json +1 + +Create a `.gitignore`: + +```bash +cat > .gitignore <<'EOF' +# Generated exports +/exports/* +!/exports/.gitkeep + +# Generated indexes +/indexes/* +!/indexes/.gitkeep + +# Local and temporary files +*.tmp +*.bak +*.log +.DS_Store +Thumbs.db +.vscode/ +.idea/ diff --git a/exports/.gitkeep b/exports/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/images/.gitkeep b/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/indexes/.gitkeep b/indexes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/schema/product.schema.json b/schema/product.schema.json new file mode 100644 index 0000000..99c3d43 --- /dev/null +++ b/schema/product.schema.json @@ -0,0 +1,243 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.ddr4.net/dragon757/RoundCount-Catalog/raw/branch/main/schema/product.schema.json", + "title": "RoundCount Ammunition Product", + "description": "Schema for an ammunition product in the RoundCount Catalog.", + "type": "object", + "additionalProperties": false, + "required": [ + "catalog_version", + "record_uuid", + "manufacturer", + "product_name", + "caliber", + "status", + "last_updated" + ], + "properties": { + "catalog_version": { + "type": "integer", + "const": 1 + }, + "record_uuid": { + "type": "string", + "format": "uuid" + }, + "upc": { + "type": [ + "string", + "null" + ], + "pattern": "^[0-9]{8,14}$" + }, + "sku": { + "type": [ + "string", + "null" + ], + "maxLength": 100 + }, + "manufacturer": { + "type": "string", + "minLength": 1, + "maxLength": 150 + }, + "brand": { + "type": [ + "string", + "null" + ], + "maxLength": 150 + }, + "product_name": { + "type": "string", + "minLength": 1, + "maxLength": 200 + }, + "caliber": { + "type": "string", + "minLength": 1, + "maxLength": 100 + }, + "bullet": { + "type": "object", + "additionalProperties": false, + "properties": { + "weight_gr": { + "type": [ + "number", + "null" + ], + "minimum": 0 + }, + "type": { + "type": [ + "string", + "null" + ], + "maxLength": 100 + }, + "material": { + "type": [ + "string", + "null" + ], + "maxLength": 100 + } + } + }, + "case": { + "type": "object", + "additionalProperties": false, + "properties": { + "material": { + "type": [ + "string", + "null" + ], + "maxLength": 100 + }, + "reloadable": { + "type": [ + "boolean", + "null" + ] + } + } + }, + "primer": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": [ + "string", + "null" + ], + "maxLength": 100 + }, + "sealed": { + "type": [ + "boolean", + "null" + ] + } + } + }, + "package": { + "type": "object", + "additionalProperties": false, + "properties": { + "rounds_per_box": { + "type": [ + "integer", + "null" + ], + "minimum": 1 + }, + "boxes_per_case": { + "type": [ + "integer", + "null" + ], + "minimum": 1 + } + } + }, + "ballistics": { + "type": "object", + "additionalProperties": false, + "properties": { + "muzzle_velocity_fps": { + "type": [ + "integer", + "null" + ], + "minimum": 0 + }, + "muzzle_energy_ft_lbs": { + "type": [ + "integer", + "null" + ], + "minimum": 0 + }, + "test_barrel_length_in": { + "type": [ + "number", + "null" + ], + "minimum": 0 + } + } + }, + "image": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "path": { + "type": [ + "string", + "null" + ] + }, + "sha256": { + "type": [ + "string", + "null" + ], + "pattern": "^[a-fA-F0-9]{64}$" + } + } + }, + "sources": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "url", + "type", + "verified_at" + ], + "properties": { + "url": { + "type": "string", + "format": "uri" + }, + "type": { + "type": "string", + "enum": [ + "manufacturer", + "distributor", + "retailer", + "packaging", + "other" + ] + }, + "verified_at": { + "type": "string", + "format": "date" + } + } + } + }, + "status": { + "type": "string", + "enum": [ + "draft", + "unverified", + "verified", + "discontinued", + "duplicate" + ] + }, + "last_updated": { + "type": "string", + "format": "date" + } + } +} \ No newline at end of file