Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Preparing Ring Platform content
Preparing Ring Platform content
Preparing Ring Platform content
Ring white-labels share one platform codebase: ring-platform.org. Verticals are selected by preset name in ring-config.json. Typed catalogs live under features/*/presets/<preset>.ts (and home under components/pages/home-presets/<preset>.tsx).
| Source | What lives there | When it wins |
|---|---|---|
Platform (ring-platform.org) | Shared niches (platform, agricultural, …) | Base of every build |
Clone project dir (e.g. ring-greenfood-live) | Branding, ring-config.json, custom <preset>.ts + registry overlays | Overwrite on collision after platform copy |
Use ringdom-clone-build (ringdom-mcp):
ring-platform.org → build tmp (skips node_modules / .next / .git)Do not expect a thin overlay alone to be a runnable app — merge first.
| Tier | What | Where |
|---|---|---|
| 1 — data | Category lists, badge tokens, labels | ring-config.json maps + locales/ |
| 2 — typed logic | Entity catalogs, zod/forms, niche field UIs | features/*/presets/<preset>.ts (platform and/or clone overlay) |
GreenFood sets entities / productFields / productBadges to "agricultural" and home.preset to "mvm-landing".
All use the configured *.preset string. If a singular key is unset, entities and productBadges fall back to productFields.preset, then "platform" — no hard-coded niche if/else.
getEntitiesPreset() → features/entities/presets registrygetHomePreset() → components/pages/home-presets registrygetProductFieldsPreset() / getProductFieldsPresets()getProductBadgesPreset() / getProductBadgesPresets()Rule: preset names appear in ring-config + the registry map. Consumers call getEntityTypes() / getEntityTypeList() — never import agricultural.ts directly.
Custom niche on a clone: add features/entities/presets/<name>.ts in the clone project, overlay index.ts to register it, set entities.preset to that name, then ringdom-clone-build.
Bundle discipline: sync catalogs are lightweight UI lists. Heavy ERP field catalogs live in *-erp.ts modules loaded only via async loadErpEntityTypes().
presets/<name>.ts): ids, emoji, English fallback names/descriptionslocales/*/modules/entities.json → types.<id> + types.<id>Desccomponents/entities/entity-type-icons.tsx TYPE_VISUALS mapuseEntityTypeLabel() / useEntityTypeDescription() — i18n first, catalog fallbackfeatures/entities/presets/<name>.ts (+ optional <name>-erp.ts)ENTITIES_PRESET_REGISTRY (+ ERP_CATALOG_REGISTRY if needed)components/pages/home-presets/<name>.tsxproductFieldsPresets / productBadgesPresetslocales/*/modules/entities.jsonring-config.template.jsonTarget roster: platform, agricultural, then tourism, sport, business, pet, auto, connect, technopark, manufacturing.
.reggie-propagate-exclude.json protects overlay-only paths from being overwritten by Reggie:
ring-config.jsonpublic/logo*.svg, favicon.ico, public/branding/locales/{en,uk,ru}/config.json, vendor.jsonfeatures/*/presets/<clone-only>.ts (+ registry overlay) when not upstreamed yetlib/overlay/registry.ts only (maps). Do not exclude lib/overlay/types.ts or lib/overlay/runtime.ts — those are platform SSOT.| Path | Owner | Role |
|---|---|---|
lib/overlay/types.ts | Platform | Contracts |
lib/overlay/runtime.ts | Platform | loadOverlayMessages / resolveOverlayHomeRail |
lib/overlay/registry.ts | Platform empty maps; clone overlays maps | Domain feature loaders |
Consumers import from @/lib/overlay/runtime. Clones never duplicate loaders in registry.ts.
Operator checklist (calculator / Order Lab): Ringization playbook.
Propagation source remains ring-platform.org → clones for shared code. Clone-local custom presets stay in the clone dir and win at ringdom-clone-build.
if (productPreset === 'agricultural') in accessorscustom-types.ts / overrides.ts without a named preset moduleswitch (vertical) in feature code — use the registryRing white-labels share one platform codebase: ring-platform.org. Verticals are selected by preset name in ring-config.json. Typed catalogs live under features/*/presets/<preset>.ts (and home under components/pages/home-presets/<preset>.tsx).
| Source | What lives there | When it wins |
|---|---|---|
Platform (ring-platform.org) | Shared niches (platform, agricultural, …) | Base of every build |
Clone project dir (e.g. ring-greenfood-live) | Branding, ring-config.json, custom <preset>.ts + registry overlays | Overwrite on collision after platform copy |
Use ringdom-clone-build (ringdom-mcp):
ring-platform.org → build tmp (skips node_modules / .next / .git)Do not expect a thin overlay alone to be a runnable app — merge first.
| Tier | What | Where |
|---|---|---|
| 1 — data | Category lists, badge tokens, labels | ring-config.json maps + locales/ |
| 2 — typed logic | Entity catalogs, zod/forms, niche field UIs | features/*/presets/<preset>.ts (platform and/or clone overlay) |
GreenFood sets entities / productFields / productBadges to "agricultural" and home.preset to "mvm-landing".
All use the configured *.preset string. If a singular key is unset, entities and productBadges fall back to productFields.preset, then "platform" — no hard-coded niche if/else.
getEntitiesPreset() → features/entities/presets registrygetHomePreset() → components/pages/home-presets registrygetProductFieldsPreset() / getProductFieldsPresets()getProductBadgesPreset() / getProductBadgesPresets()Rule: preset names appear in ring-config + the registry map. Consumers call getEntityTypes() / getEntityTypeList() — never import agricultural.ts directly.
Custom niche on a clone: add features/entities/presets/<name>.ts in the clone project, overlay index.ts to register it, set entities.preset to that name, then ringdom-clone-build.
Bundle discipline: sync catalogs are lightweight UI lists. Heavy ERP field catalogs live in *-erp.ts modules loaded only via async loadErpEntityTypes().
presets/<name>.ts): ids, emoji, English fallback names/descriptionslocales/*/modules/entities.json → types.<id> + types.<id>Desccomponents/entities/entity-type-icons.tsx TYPE_VISUALS mapuseEntityTypeLabel() / useEntityTypeDescription() — i18n first, catalog fallbackfeatures/entities/presets/<name>.ts (+ optional <name>-erp.ts)ENTITIES_PRESET_REGISTRY (+ ERP_CATALOG_REGISTRY if needed)components/pages/home-presets/<name>.tsxproductFieldsPresets / productBadgesPresetslocales/*/modules/entities.jsonring-config.template.jsonTarget roster: platform, agricultural, then tourism, sport, business, pet, auto, connect, technopark, manufacturing.
.reggie-propagate-exclude.json protects overlay-only paths from being overwritten by Reggie:
ring-config.jsonpublic/logo*.svg, favicon.ico, public/branding/locales/{en,uk,ru}/config.json, vendor.jsonfeatures/*/presets/<clone-only>.ts (+ registry overlay) when not upstreamed yetlib/overlay/registry.ts only (maps). Do not exclude lib/overlay/types.ts or lib/overlay/runtime.ts — those are platform SSOT.| Path | Owner | Role |
|---|---|---|
lib/overlay/types.ts | Platform | Contracts |
lib/overlay/runtime.ts | Platform | loadOverlayMessages / resolveOverlayHomeRail |
lib/overlay/registry.ts | Platform empty maps; clone overlays maps | Domain feature loaders |
Consumers import from @/lib/overlay/runtime. Clones never duplicate loaders in registry.ts.
Operator checklist (calculator / Order Lab): Ringization playbook.
Propagation source remains ring-platform.org → clones for shared code. Clone-local custom presets stay in the clone dir and win at ringdom-clone-build.
if (productPreset === 'agricultural') in accessorscustom-types.ts / overrides.ts without a named preset moduleswitch (vertical) in feature code — use the registryRing white-labels share one platform codebase: ring-platform.org. Verticals are selected by preset name in ring-config.json. Typed catalogs live under features/*/presets/<preset>.ts (and home under components/pages/home-presets/<preset>.tsx).
| Source | What lives there | When it wins |
|---|---|---|
Platform (ring-platform.org) | Shared niches (platform, agricultural, …) | Base of every build |
Clone project dir (e.g. ring-greenfood-live) | Branding, ring-config.json, custom <preset>.ts + registry overlays | Overwrite on collision after platform copy |
Use ringdom-clone-build (ringdom-mcp):
ring-platform.org → build tmp (skips node_modules / .next / .git)Do not expect a thin overlay alone to be a runnable app — merge first.
| Tier | What | Where |
|---|---|---|
| 1 — data | Category lists, badge tokens, labels | ring-config.json maps + locales/ |
| 2 — typed logic | Entity catalogs, zod/forms, niche field UIs | features/*/presets/<preset>.ts (platform and/or clone overlay) |
GreenFood sets entities / productFields / productBadges to "agricultural" and home.preset to "mvm-landing".
All use the configured *.preset string. If a singular key is unset, entities and productBadges fall back to productFields.preset, then "platform" — no hard-coded niche if/else.
getEntitiesPreset() → features/entities/presets registrygetHomePreset() → components/pages/home-presets registrygetProductFieldsPreset() / getProductFieldsPresets()getProductBadgesPreset() / getProductBadgesPresets()Rule: preset names appear in ring-config + the registry map. Consumers call getEntityTypes() / getEntityTypeList() — never import agricultural.ts directly.
Custom niche on a clone: add features/entities/presets/<name>.ts in the clone project, overlay index.ts to register it, set entities.preset to that name, then ringdom-clone-build.
Bundle discipline: sync catalogs are lightweight UI lists. Heavy ERP field catalogs live in *-erp.ts modules loaded only via async loadErpEntityTypes().
presets/<name>.ts): ids, emoji, English fallback names/descriptionslocales/*/modules/entities.json → types.<id> + types.<id>Desccomponents/entities/entity-type-icons.tsx TYPE_VISUALS mapuseEntityTypeLabel() / useEntityTypeDescription() — i18n first, catalog fallbackfeatures/entities/presets/<name>.ts (+ optional <name>-erp.ts)ENTITIES_PRESET_REGISTRY (+ ERP_CATALOG_REGISTRY if needed)components/pages/home-presets/<name>.tsxproductFieldsPresets / productBadgesPresetslocales/*/modules/entities.jsonring-config.template.jsonTarget roster: platform, agricultural, then tourism, sport, business, pet, auto, connect, technopark, manufacturing.
.reggie-propagate-exclude.json protects overlay-only paths from being overwritten by Reggie:
ring-config.jsonpublic/logo*.svg, favicon.ico, public/branding/locales/{en,uk,ru}/config.json, vendor.jsonfeatures/*/presets/<clone-only>.ts (+ registry overlay) when not upstreamed yetlib/overlay/registry.ts only (maps). Do not exclude lib/overlay/types.ts or lib/overlay/runtime.ts — those are platform SSOT.| Path | Owner | Role |
|---|---|---|
lib/overlay/types.ts | Platform | Contracts |
lib/overlay/runtime.ts | Platform | loadOverlayMessages / resolveOverlayHomeRail |
lib/overlay/registry.ts | Platform empty maps; clone overlays maps | Domain feature loaders |
Consumers import from @/lib/overlay/runtime. Clones never duplicate loaders in registry.ts.
Operator checklist (calculator / Order Lab): Ringization playbook.
Propagation source remains ring-platform.org → clones for shared code. Clone-local custom presets stay in the clone dir and win at ringdom-clone-build.
if (productPreset === 'agricultural') in accessorscustom-types.ts / overrides.ts without a named preset moduleswitch (vertical) in feature code — use the registry
{
"entities": { "preset": "platform" },
"home": { "preset": "platform" },
"productFields": { "preset": "platform" },
"productBadges": { "preset": "platform" },
"productFieldsPresets": {
"platform": { "storeCategories": ["commerce", "education", "…"] },
"agricultural": { "storeCategories": ["organic-produce", "honey-sweets", "…"] }
},
"productBadgesPresets": {
"platform": { "productBadges": ["new", "featured", "popular"] },
"agricultural": { "productBadges": ["organic", "local", "regenerative"] }
}
}
ringdom-clone-build({ project_name: "ring-greenfood-live", dry_run?: true })
→ .ringdom-build/<project>/<timestamp>
features/entities/presets/
types.ts # EntityTypeCatalog contract
platform.ts # export const entityTypes (26 industries)
agricultural.ts # healthy-living UI catalog (lightweight)
agricultural-erp.ts # heavy ERP field catalogs — async-only via loadErpEntityTypes()
index.ts # ENTITIES_PRESET_REGISTRY + getEntityTypes()
components/pages/
home.tsx # platform default landing
home-presets/mvm-landing.tsx # multi-vendor-marketplace e-commerce landing
home-content-resolver.tsx # HOME_PRESET_REGISTRY + getHomePreset()
ensure ring-config: entities/productFields/productBadges = agricultural, home = mvm-landing
keep branding + locale deltas in ring-greenfood-live
ringdom-clone-build({ project_name: "ring-greenfood-live" })
build/deploy from .ringdom-build/ring-greenfood-live/<stamp>
{
"entities": { "preset": "platform" },
"home": { "preset": "platform" },
"productFields": { "preset": "platform" },
"productBadges": { "preset": "platform" },
"productFieldsPresets": {
"platform": { "storeCategories": ["commerce", "education", "…"] },
"agricultural": { "storeCategories": ["organic-produce", "honey-sweets", "…"] }
},
"productBadgesPresets": {
"platform": { "productBadges": ["new", "featured", "popular"] },
"agricultural": { "productBadges": ["organic", "local", "regenerative"] }
}
}
ringdom-clone-build({ project_name: "ring-greenfood-live", dry_run?: true })
→ .ringdom-build/<project>/<timestamp>
features/entities/presets/
types.ts # EntityTypeCatalog contract
platform.ts # export const entityTypes (26 industries)
agricultural.ts # healthy-living UI catalog (lightweight)
agricultural-erp.ts # heavy ERP field catalogs — async-only via loadErpEntityTypes()
index.ts # ENTITIES_PRESET_REGISTRY + getEntityTypes()
components/pages/
home.tsx # platform default landing
home-presets/mvm-landing.tsx # multi-vendor-marketplace e-commerce landing
home-content-resolver.tsx # HOME_PRESET_REGISTRY + getHomePreset()
ensure ring-config: entities/productFields/productBadges = agricultural, home = mvm-landing
keep branding + locale deltas in ring-greenfood-live
ringdom-clone-build({ project_name: "ring-greenfood-live" })
build/deploy from .ringdom-build/ring-greenfood-live/<stamp>
{
"entities": { "preset": "platform" },
"home": { "preset": "platform" },
"productFields": { "preset": "platform" },
"productBadges": { "preset": "platform" },
"productFieldsPresets": {
"platform": { "storeCategories": ["commerce", "education", "…"] },
"agricultural": { "storeCategories": ["organic-produce", "honey-sweets", "…"] }
},
"productBadgesPresets": {
"platform": { "productBadges": ["new", "featured", "popular"] },
"agricultural": { "productBadges": ["organic", "local", "regenerative"] }
}
}
ringdom-clone-build({ project_name: "ring-greenfood-live", dry_run?: true })
→ .ringdom-build/<project>/<timestamp>
features/entities/presets/
types.ts # EntityTypeCatalog contract
platform.ts # export const entityTypes (26 industries)
agricultural.ts # healthy-living UI catalog (lightweight)
agricultural-erp.ts # heavy ERP field catalogs — async-only via loadErpEntityTypes()
index.ts # ENTITIES_PRESET_REGISTRY + getEntityTypes()
components/pages/
home.tsx # platform default landing
home-presets/mvm-landing.tsx # multi-vendor-marketplace e-commerce landing
home-content-resolver.tsx # HOME_PRESET_REGISTRY + getHomePreset()
ensure ring-config: entities/productFields/productBadges = agricultural, home = mvm-landing
keep branding + locale deltas in ring-greenfood-live
ringdom-clone-build({ project_name: "ring-greenfood-live" })
build/deploy from .ringdom-build/ring-greenfood-live/<stamp>