Helmetsan is a WordPress-based, AI-assisted helmet data platform with:
helmetsan-coreplugin (ERP-style operations, ingestion, GitHub sync, analytics, go-live gates)helmetsan-themeGeneratePress child theme (frontend presentation layer)docs/architecture and technical documentation
helmetsan-core/WordPress pluginhelmetsan-theme/WordPress themedata/GitHub source datasets (brands, helmets, accessories, motorcycles, safety standards, dealers, distributors, pricing, offers, marketplaces, currencies, recommendations, comparisons, geo, schemas)scripts/deployment, seeding, and enrichment scriptsdocs/architecture and TDD docs
- Copy plugin to WordPress plugins:
wp-content/plugins/helmetsan-core
- Copy theme to WordPress themes:
wp-content/themes/helmetsan-theme
- Activate plugin:
wp plugin activate helmetsan-core
- (Optional) Activate theme:
wp theme activate helmetsan-theme
The catalog now uses a deterministic data processing pipeline. Variants are no longer randomly generated at ingestion time but are explicitly defined in the seed generator.
- Colorways: Defined per-model in a structured data source:
- Today:
scripts/create_helmets_seed.php(PHP array, legacy). - Recommended going forward: JSON under
data/helmets/(e.g.data/helmets/master.json) loaded via--source-json.
- Today:
- SKU: Generated as
{BRAND_PREFIX}-{MODEL_PREFIX}-{COLOR_CODE}(e.g.,SHO-RF14-MBK). - IDs: Slugs are now deterministic based on color name (e.g.,
shoei_rf_1400_matte-black). - Pricing: Base price defined at model level; variants have specific
price_adjdeltas (e.g., +$50 for Graphics).
- Color Family: 10 primary buckets for checking/filtering (Black, White, Red, Blue, Green, Yellow/Hi-Viz, Orange, Grey/Silver, Multi/Graphic, Carbon).
- Finish:
matteorgloss. - Type: Full Face, Modular, Open Face, etc.
Full command list: See docs/COMMANDS_REFERENCE.md for all scripts and WP-CLI commands with run locations (repo root vs server).
The pipeline is automated via scripts/reseed.sh.
./scripts/reseed.sh # Full cycle: Generate -> Deploy -> Ingest
./scripts/reseed.sh --skip-deploy # Just generate and ingest locally/remotelyConfigure providers under Helmetsan → AI: free/low-cost (Groq, Gemini, Mistral, OpenRouter, Hugging Face, Together, Fireworks, Cohere) and premium (OpenAI, Anthropic, Perplexity). Each provider has a “Best for” note in the admin. See docs/ai-module.md and docs/ai-seeder-enrichment-roadmap.md for seeder robustness, fill-missing, SEO relations, cross-linking, and provider details.
Seed SEO fields for helmets, brands, and accessories. Optional AI-generated meta descriptions (uses any configured free provider). See docs/seo-seed-plan.md for details.
On server (from WordPress root /var/www/helmetsan.com/public):
wp helmetsan seo seed # Template-only, all types
wp helmetsan seo seed --use-ai # With AI descriptions (set API keys in Helmetsan → AI or wp-config)
wp helmetsan seo seed --use-ai --limit=5 # Test runAfter ingesting seed data you can run (in order): fill-missing (AI fills blank meta and taxonomy terms only), SEO seed (overwrites Yoast title/meta/focus kw), then cross-link (overwrites suggested internal links). See docs/enrichment-process.md for the full flow, which fields are filled per entity type, and how to update or enrich all helmets, accessories, and brands. Optional scheduled enrichment (fill-missing + SEO seed for helmets) under Helmetsan → Scheduler → AI Enrichment.
wp helmetsan ai fill-missing --post-type=all --limit=0 # Fill only blank fields (all types)
wp helmetsan seo seed --use-ai --post-type=all # Overwrite SEO for all
wp helmetsan ai cross-link --post-type=all --limit=0 # Overwrite link suggestionsAI-generated catalog data: Use the same plugin AI credentials to generate new helmet models (master format) instead of editing PHP/JSON in the IDE: wp helmetsan ai generate-seed --count=10 --brand=HJC [--output=helmets/generated.json]. Merge the output into data/helmets/master.json, then run the seed script and ingest. See docs/data-flow.md (workflow 5) and docs/COMMANDS_REFERENCE.md (§4.3).
If filtering by category on /accessories/ (e.g. Audio Kits) shows "Nothing Found", seed terms and backfill so every accessory has at least one accessory_category term:
wp helmetsan seed-accessory-categories # Create/update category terms (correct slugs)
wp helmetsan backfill-accessory-categories # Assign category from type/parent_category/subcategorySee docs/accessories-categories-and-filters.md for the full category list, type→category mapping, helmet-type compatibility, and optional compatible_helmets JSON.
To completely wipe the database (required for schema changes):
ssh root@helmetsan.com "wp --path=/var/www/helmetsan.com/public eval-file ../reset_helmets.php --allow-root"| Term | Meaning |
|---|---|
| Seed | The generated JSON array of helmet variants (output of create_helmets_seed.php). |
| ingest-seed | CLI command that ingests that seed array into WordPress (wp helmetsan ingest-seed). |
| SEO seed | Populating Yoast title, meta description, and focus keyword (template or AI); wp helmetsan seo seed. |
| Reseed | Full pipeline: generate seed → deploy → ingest-seed (e.g. ./scripts/reseed.sh). |
| Sync | GitHub pull/push of JSON under data/; ingestion is the process of applying JSON to posts/meta. |
The helmet catalog is managed through a seed → deploy → ingest pipeline.
./scripts/reseed.sh # Generate → Deploy → Ingest
./scripts/reseed.sh --dry-run # Validate + deploy, no DB writes
./scripts/reseed.sh --validate # Just validate locallyPreferred: Maintain catalog data in data/helmets/master.json (see data/helmets/master.example.json) and generate the seed from it so you don’t edit the large PHP array:
# 1. Generate seed JSON (preferred: from JSON source)
php scripts/create_helmets_seed.php --source-json=data/helmets/master.json --output=helmetsan-core/seed-data/helmets_seed.json --stats
# Or from the in-file PHP array (legacy):
# php scripts/create_helmets_seed.php --output=helmetsan-core/seed-data/helmets_seed.json --stats
# 2. Validate (checks IDs, descriptions, type distribution)
php scripts/create_helmets_seed.php --validate
# 3. Deploy to server
bash scripts/deploy.sh
# 4. Ingest on server
ssh root@helmetsan.com "wp --path=/var/www/helmetsan.com/public helmetsan ingest-seed --allow-root"
# Optional: also ingest curated per-helmet JSONs from data/helmets (richer data, marketplace links)
ssh root@helmetsan.com "wp --path=/var/www/helmetsan.com/public helmetsan ingest --path=data/helmets --allow-root"To grow the catalog with richer data (more models, brands, accessories and optional detail fields):
- Helmets
- Use
data/helmets/master.json(same shape asdata/helmets/master.example.json) with the seed generator. The example file shows optional model-level fields:helmet_family,model_year,features,product_details,sizing_fit,identifiers, and per-colorwaymarketplace_links/identifiers. These are passed through to the generated seed and ingested. - To switch from the in-file PHP array to JSON: run
php scripts/create_helmets_seed.php --export-master=data/helmets/master.json
to dump the current master to JSON, then maintaindata/helmets/master.jsonand use--source-json=data/helmets/master.jsonfor future runs.
- Use
- Brands
data/brands/master.example.jsonis a reference for the full brand profile shape (see alsodata/schemas/brand.schema.json). Add or edit files underdata/brands/<slug>.jsonfor more brands with detailed profiles; ingest withwp helmetsan ingest-brandsor via Helmetsan → Data.
- Accessories
data/accessories/master.example.jsonis a reference for the full accessory shape (seedata/schemas/accessory.schema.json). Add or edit files underdata/accessories/<slug>.jsonfor more accessories with compatibility and features; ingest withwp helmetsan ingest --path=data/accessoriesor via Helmetsan → Data.
See docs/json-and-github.md for JSON workflow and docs/data-flow.md for the full data-flow concept.
| Command | Description |
|---|---|
wp helmetsan ingest-seed |
Ingest a seed JSON array file (main workflow) |
wp helmetsan ingest --path=<dir> |
Ingest per-file JSONs from data root (helmets, accessories) |
wp helmetsan ingest-brands |
Ingest brand JSONs from data root / brands |
wp helmetsan ingest-seed --dry-run |
Validate without writing to DB |
wp helmetsan unlock-ingestion |
Force-remove stale ingestion lock |
wp helmetsan seed-accessory-categories |
Create accessory_category terms (fixes /accessory-category/bluetooth-headsets/ etc.) |
Dashboard: Use Helmetsan > Data / Reseed to run helmet seed, path-based helmets, accessories, and brands from the admin UI (with optional dry run).
- Ingestion is upsert-only: Items are matched by
_helmet_unique_id(or brand/accessory equivalent). Re-running seed or path ingest only creates new items and updates existing ones; it never deletes posts. Your existing 1400+ helmets and 70+ brands stay intact; new or changed seed data is merged in. - Hash-based skip: Unchanged payloads are skipped (no duplicate work). See
docs/ingestion-unique-ids-and-hash.mdfor unique IDs and skip behaviour per entity type. - Batch size: Default seed batch size is 25 (
--batch-size=25). Use a smaller value if you hit lock timeouts; ingestion disables PHP time limit for long runs. - Yoast SEO: During bulk ingestion, Yoast indexable creation is temporarily suppressed to avoid MySQL lock timeouts. After a full reseed, run Yoast’s indexation from SEO > Tools if you need fresh indexables for imported content.
The plugin supports pull/push sync with a GitHub data repository path (default data/). JSON in the repo under data/ (brands, helmets, accessories, etc.) is the source for sync pull; the seed generator can use a JSON file (e.g. data/helmets/master.json) via --source-json instead of the in-file PHP array. See docs/json-and-github.md for how JSON context and GitHub sync fit together.
Set credentials in Helmetsan → GitHub and validate with:
wp helmetsan health --format=jsonwp helmetsan sync pull --profile=pull+brands --dry-run(or--profile=pull+helmets,--profile=pull+all)
Use the Go Live gate from WordPress Admin (Helmetsan > Go Live) or CLI:
wp helmetsan go-live checklist
It provides objective score, critical blockers, and per-check diagnostics.
| Metric | Value | Status |
|---|---|---|
| Brands in Catalog | 73 | ✅ |
| Helmets Indexed | 1,412 | ✅ Live |
| Parent Models | 297 | ✅ |
| Logo Coverage | 67% (49/73) | 🎨 Enriched |
| Last Sync | 2026-02-23 | 📡 Active |
Stats generated automatically by
scripts/update_stats.php
This repository is licensed under the MIT License. See LICENSE.