This document provides guidance for AI agents working on the meshery/schemas repository to avoid common mistakes and follow established patterns.
CRITICAL: When modifying schema YAML files, only commit the schema files themselves. Do NOT commit:
- Go files in
models/directory - TypeScript files in
typescript/generated/directory - TypeScript files in
dist/directory - Generated OpenAPI YAML files (
merged-openapi.yml,cloud_openapi.yml,meshery_openapi.yml)
These files are auto-generated by the build process and should not be manually committed.
Each construct directory contains an api.yml file that serves as the index file for that construct. This file:
- References all subschemas - Aggregates and references all related schema definitions for the construct
- Defines API endpoints - Contains all REST API operations (GET, POST, PUT, DELETE) for that construct
- Acts as the entry point - Used by code generators (oapi-codegen, openapi-typescript) to produce Go structs and TypeScript types
Other YAML/JSON files in the same directory (e.g., model.yaml, component.yaml, model_core.yml) contain subschemas - individual schema definitions that are referenced by api.yml.
Use: ../../v1alpha1/core/api.yml#/components/schemas/<schema_name>
Do NOT use: ../../core.json#/definitions/<definition_name> (deprecated)
The core.json file is deprecated. All references should use the OpenAPI YAML format from v1alpha1/core/api.yml.
-
Property names
- Use camelCase for property fields (e.g.,
schemaVersion,displayName,componentsCount). - Identifier fields use lowerCamelCase with "Id" suffix (e.g.,
modelId,registrantId,categoryId). - Enums use lowercase words (e.g.,
enabled,ignored,duplicate).
- Use camelCase for property fields (e.g.,
-
OpenAPI schema names
- PascalCase nouns under
components/schemas(e.g.,Model,Component). - Files/folders are lowercase:
<construct>.yml,api.yml,templates/<construct>_template.(json|yaml). api.ymlis the index file for each construct (contains schema refs and API endpoints).- Other YAML files (e.g.,
<construct>.yaml,<construct>_core.yml) contain subschemas.
- PascalCase nouns under
-
Endpoints and operations
- Paths are under
/apiwith kebab-case, plural nouns (e.g.,/api/workspaces,/api/environments). - Path params are camelCase (e.g.,
{subscriptionId},{connectionId}). - Non-CRUD actions append a verb segment (e.g.,
.../register,.../export,.../cancel); legacy lowerCamelCase may appear (e.g.,.../upgradePreview). operationIdis camelCase VerbNoun (e.g.,registerMeshmodels).
- Paths are under
-
Versioning
schemaVersionuses group/version (e.g.,models.meshery.io/v1beta1,components.meshery.io/v1beta1).- Version strings follow k8s-style (
v1,v1alpha1,v1beta1); semver fields use standard SemVer.
- Timestamps:
../../v1alpha1/core/api.yml#/components/schemas/created_at - Timestamps:
../../v1alpha1/core/api.yml#/components/schemas/updated_at - UUID:
../../v1alpha1/core/api.yml#/components/schemas/uuid - Version String:
../../v1alpha1/core/api.yml#/components/schemas/versionString - Semver String:
../../v1alpha1/core/api.yml#/components/schemas/semverString
When adding created_at and updated_at fields to schemas:
created_at:
$ref: ../../v1alpha1/core/api.yml#/components/schemas/created_at
x-order: 14
updated_at:
$ref: ../../v1alpha1/core/api.yml#/components/schemas/updated_at
x-order: 15Do NOT include additional x-oapi-codegen-extra-tags when using the reference - these are already defined in the core schema.
Templates are manually defined files located in the templates/ subdirectory within each schema folder. You can have multiple template files for different variants or use cases.
When updating schema YAML files, also update the corresponding template files in the templates/ subdirectory (e.g., templates/<construct>_template.json or templates/<construct>_template.yaml) with default values:
{
"created_at": "0001-01-01T00:00:00Z",
"updated_at": "0001-01-01T00:00:00Z"
}You can add additional variant templates as needed (e.g., <construct>_minimal_template.json, <construct>_full_template.yaml).
For schemas in v1alpha3 directory, adjust the path accordingly:
created_at:
$ref: ../v1alpha1/core/api.yml#/components/schemas/created_at
updated_at:
$ref: ../v1alpha1/core/api.yml#/components/schemas/updated_atmake setup # Install dependencies
make build # Build all schemas (generates Go, TypeScript, OpenAPI files)go test ./... # Run Go testsThe build process automatically generates:
- Go structs from schema YAML files via
oapi-codegen→models/<version>/<package>/ - TypeScript type definitions (
.d.tsfiles) →typescript/generated/<version>/<package>/ - TypeScript schema exports (
*Schema.tsfiles) →typescript/generated/<version>/<package>/ - Merged OpenAPI YAML files from individual schema components →
_openapi_build/ - Built distribution files →
dist/
While Go structs are auto-generated, you often need to add helper files (*_helper.go or helpers.go) for:
- SQL Driver Compatibility - Implement
Scan()andValue()methods - Entity Interface - Implement
entity.Entityfor database CRUD operations - GORM Table Names - Define
TableName()method - Utility Methods - Conversion helpers, validation, business logic
Helper File Location:
models/v1beta1/model/
├── model.go # Auto-generated (do NOT edit)
└── model_helper.go # Manual: Entity interface, TableName, SQL drivers
Key Patterns:
// model_helper.go - This is not autogenerated.
package model
// TableName for GORM
func (m ModelDefinition) TableName() string {
return "model_dbs"
}
// SQL Scanner interface
func (m *MyType) Scan(value interface{}) error {
mapVal := core.Map{}
err := mapVal.Scan(value)
if err != nil {
return err
}
return core.MapToStruct(mapVal, m)
}
// SQL Valuer interface
func (m MyType) Value() (driver.Value, error) {
mapVal, err := core.StructToMap(m)
if err != nil {
return nil, err
}
return core.Map(mapVal).Value()
}Important:
- ✅ DO commit helper files (they are NOT auto-generated)
- ✅ Add
// This is not autogenerated.at the top - ✅ Use
sync.Mutexfor thread-safeCreate()methods - ❌ Do NOT edit generated
.gofiles directly
schemas/
├── constructs/
│ ├── v1alpha1/
│ │ └── core/
│ │ └── api.yml # Core schema definitions (use this!)
│ ├── v1alpha3/
│ │ ├── relationship/
│ │ │ ├── api.yml # Index file: refs subschemas + API endpoints
│ │ │ ├── relationship_core.yml # Subschema: core relationship definitions
│ │ │ └── templates/
│ │ │ └── relationship_template.json
│ │ └── relationship.yaml # Subschema definitions
│ ├── v1beta1/
│ │ ├── model/
│ │ │ ├── api.yml # Index file: refs subschemas + API endpoints
│ │ │ ├── model.yaml # Subschema: model data definitions
│ │ │ ├── model_core.yml # Subschema: core model definitions
│ │ │ └── templates/ # Manually defined templates
│ │ │ ├── model_template.json
│ │ │ └── model_template.yaml
│ │ └── component/
│ │ ├── api.yml # Index file: refs subschemas + API endpoints
│ │ ├── component.yaml # Subschema: component data definitions
│ │ └── templates/
│ │ ├── component_template.json
│ │ └── component_template.yaml
│ └── core.json # DEPRECATED - do not use
├── models/ # Auto-generated Go code (do NOT commit)
├── typescript/
│ ├── index.ts # Manually maintained - public API surface
│ ├── generated/ # Auto-generated TypeScript (do NOT commit)
│ │ ├── v1alpha1/
│ │ │ ├── capability/
│ │ │ │ ├── Capability.d.ts # Type definitions
│ │ │ │ └── CapabilitySchema.ts # Schema as JS object
│ │ │ └── core/
│ │ ├── v1alpha2/
│ │ │ └── catalog/
│ │ └── v1beta1/
│ │ ├── component/
│ │ ├── model/
│ │ ├── pattern/ # Contains Design schema
│ │ ├── environment/
│ │ ├── workspace/
│ │ └── ...
│ └── rtk/ # RTK Query client configs
└── dist/ # Built output (do NOT commit)
├── index.js
├── index.d.ts
├── cloudApi.js
├── mesheryApi.js
└── generated/ # Built schema exports
└── v1beta1/
└── model/
└── ModelSchema.js
The typescript/index.ts file is manually maintained and defines the public API surface:
- Import paths should use
./generated/<version>/<package>/<Name>(without.d.tsextension) - Schema imports use
./generated/<version>/<package>/<Name>Schema - Type references use the actual schema property names (often lowercase, e.g.,
environment,workspace)
// Type imports (from .d.ts files, no extension needed)
import { components as ModelComponents } from "./generated/v1beta1/model/Model";
// Schema imports (from *Schema.ts files)
import ModelDefinitionV1Beta1OpenApiSchema from "./generated/v1beta1/model/ModelSchema";
// Type exports using indexed access
export namespace v1beta1 {
export type Model = ModelComponents["schemas"]["ModelDefinition"];
export type Environment = EnvironmentComponents["schemas"]["environment"]; // Note: lowercase
}When importing schemas directly from the built package, use the constructs path:
// Direct schema imports use 'constructs' (not 'generated')
import ModelSchema from "@meshery/schemas/dist/constructs/v1beta1/model/ModelSchema";
import ComponentSchema from "@meshery/schemas/dist/constructs/v1beta1/component/ComponentSchema";- ❌ Committing generated Go code in
models/directory - ❌ Committing generated TypeScript code in
typescript/generated/directory - ❌ Committing built files in
dist/directory - ❌ Using deprecated
core.jsonreferences - ❌ Adding redundant
x-oapi-codegen-extra-tagswhen using schema references - ❌ Forgetting to update template files in the
templates/subdirectory with default values - ❌ Not testing the build process after schema changes
- ❌ Placing template files outside the
templates/subdirectory - ❌ Using
.d.tsextension in TypeScript import paths - ❌ Assuming schema property names are PascalCase (check actual generated
.d.tsfiles)
- Modified only schema JSON/YAML files (not generated code)
- Updated corresponding template files in
templates/subdirectory with default values - Used non-deprecated
v1alpha1/core/api.ymlreferences - If adding new schemas, referenced them from
api.yml(the construct index file) - Removed redundant tags when using schema references
- Ran
make buildsuccessfully - Ran
go test ./...successfully - Ran
npm run buildsuccessfully - Verified only schema JSON/YAML files are in the commit
- If updating
typescript/index.ts, verified import paths are correct
If you're unsure about any schema modification:
- Check existing schemas for patterns (e.g.,
environment.yaml,connection.yaml) - Look at
v1alpha1/core/api.ymlfor available core schema definitions - Examine any construct's
api.ymlto see how subschemas are referenced and endpoints are defined - Check generated
.d.tsfiles for actual type/property names - Review this document for guidelines
- Test your changes with
make buildbefore committing