Skip to content

📐 05_14_00_preset_schemas - Gramática Universal de Configuraciones

PROPÓSITO

Los Preset Schemas definen el lenguaje común que todos los componentes de AudioLab usan para expresar sus estados serializables. Como el DNA que permite a las células replicarse, estos schemas permiten que cualquier configuración sea capturada, transmitida y reconstruida perfectamente.

Cada schema es un contrato entre el presente y el futuro, garantizando que los presets de hoy funcionarán en las versiones de mañana.


CONCEPTOS CLAVE

Schema Maestro

preset_schema:
  version: "2.0.0"          # Version del schema
  type: "L0|L1|L2|L3"       # Nivel jerárquico
  module_id: "uuid"         # Identificador único del módulo

  header:
    name: "string"
    author: "string"
    created: "iso_datetime"
    modified: "iso_datetime"

  parameters:
    module_specific: {}     # Schema específico por tipo

  resources:
    samples: []
    tables: []
    impulses: []

  metadata:
    tags: []
    category: "string"
    description: "string"

Schema Evolution

  1. Additive Changes (Safe):
  2. Nuevos campos opcionales
  3. Nuevos tipos de recursos
  4. Metadata adicional

  5. Breaking Changes (Managed):

  6. Version bump mayor
  7. Migration script automático
  8. Fallback values definidos

  9. Deprecation Path:

  10. Mark deprecated en v1
  11. Warn en v2
  12. Remove en v3

VALIDACIÓN ESTRICTA

Cada preset pasa por validación multi-nivel:

  • Schema compliance - Estructura JSON/YAML válida
  • Type checking - Tipos de datos correctos
  • Range validation - Valores dentro de límites
  • Dependency verification - Recursos existen
  • Integrity check - Checksums y firmas

ESTRUCTURA

05_14_00_preset_schemas/
├── include/
│   ├── preset_schema.hpp         # Schema base
│   ├── schema_l0.hpp             # Schema para kernels L0
│   ├── schema_l1.hpp             # Schema para atoms L1
│   ├── schema_l2.hpp             # Schema para cells L2
│   ├── schema_l3.hpp             # Schema para engines L3
│   ├── schema_validator.hpp     # Validation engine
│   ├── schema_evolution.hpp     # Evolution tracking
│   └── integrity_checker.hpp    # Checksums y firmas
├── src/
│   ├── preset_schema.cpp
│   ├── schema_validator.cpp
│   ├── schema_evolution.cpp
│   └── integrity_checker.cpp
├── schemas/                      # JSON schema definitions
│   ├── base_schema_v1.json
│   ├── base_schema_v2.json
│   ├── l0_kernel_schema.json
│   ├── l1_atom_schema.json
│   ├── l2_cell_schema.json
│   └── l3_engine_schema.json
├── tests/
│   ├── test_schema_validation.cpp
│   ├── test_schema_evolution.cpp
│   ├── test_integrity.cpp
│   └── test_fuzzing.cpp
├── examples/
│   ├── example_l0_preset.json
│   ├── example_l1_preset.json
│   ├── example_l2_preset.json
│   └── example_l3_preset.json
└── docs/
    ├── SCHEMA_SPECIFICATION.md
    ├── EVOLUTION_GUIDE.md
    ├── VALIDATION_RULES.md
    └── MIGRATION_GUIDE.md

API PRINCIPAL

namespace audiolab::preset {

// Schema base
class PresetSchema {
public:
    struct Version {
        int major;
        int minor;
        int patch;

        std::string toString() const;
        static Version parse(const std::string& str);
        bool isCompatibleWith(const Version& other) const;
    };

    enum class ModuleType {
        Kernel_L0,
        Atom_L1,
        Cell_L2,
        Engine_L3
    };

    struct Header {
        std::string name;
        std::string author;
        std::chrono::system_clock::time_point created;
        std::chrono::system_clock::time_point modified;
        std::string description;
        std::vector<std::string> tags;
        std::string category;
    };

    // Construcción
    PresetSchema(Version version, ModuleType type, const std::string& module_id);

    // Accessors
    Version getVersion() const;
    ModuleType getType() const;
    std::string getModuleId() const;
    const Header& getHeader() const;

    // Mutation
    void setHeader(const Header& header);
    void addResource(const std::string& type, const std::string& path);
    void setParameter(const std::string& name, const nlohmann::json& value);

    // Serialization
    nlohmann::json toJson() const;
    static PresetSchema fromJson(const nlohmann::json& json);

    // Validation
    bool validate() const;
    std::vector<std::string> getValidationErrors() const;
};

// Validator
class SchemaValidator {
public:
    enum class ValidationLevel {
        Structure,  // JSON structure válida
        Types,      // Tipos correctos
        Ranges,     // Valores en rango
        Dependencies, // Referencias válidas
        Integrity   // Checksums
    };

    struct ValidationResult {
        bool success;
        std::vector<std::string> errors;
        std::vector<std::string> warnings;
        ValidationLevel level_reached;
    };

    ValidationResult validate(const PresetSchema& schema,
                            ValidationLevel max_level = ValidationLevel::Integrity);

    // Validación por nivel
    bool validateStructure(const nlohmann::json& json);
    bool validateTypes(const PresetSchema& schema);
    bool validateRanges(const PresetSchema& schema);
    bool validateDependencies(const PresetSchema& schema);
    bool validateIntegrity(const PresetSchema& schema);
};

// Evolution tracking
class SchemaEvolution {
public:
    struct ChangeSet {
        enum class Type { Added, Modified, Deprecated, Removed };
        Type type;
        std::string field_path;
        std::string description;
        PresetSchema::Version since_version;
    };

    // Track evolution
    void registerChange(const ChangeSet& change);
    std::vector<ChangeSet> getChanges(PresetSchema::Version from,
                                      PresetSchema::Version to);

    // Deprecation
    bool isDeprecated(const std::string& field_path,
                     PresetSchema::Version version);
    bool isRemoved(const std::string& field_path,
                  PresetSchema::Version version);
};

// Integrity checker
class IntegrityChecker {
public:
    // Checksums
    std::string calculateChecksum(const PresetSchema& schema);
    bool verifyChecksum(const PresetSchema& schema, const std::string& checksum);

    // Signatures (opcional para presets comerciales)
    std::string sign(const PresetSchema& schema, const std::string& private_key);
    bool verify(const PresetSchema& schema, const std::string& signature,
               const std::string& public_key);
};

} // namespace audiolab::preset

EJEMPLOS DE USO

Crear schema básico

using namespace audiolab::preset;

// Create schema
PresetSchema schema(
    PresetSchema::Version{1, 0, 0},
    PresetSchema::ModuleType::Atom_L1,
    "atom_svf_filter_001"
);

// Set header
PresetSchema::Header header;
header.name = "Warm LP Filter";
header.author = "AudioLab";
header.created = std::chrono::system_clock::now();
header.description = "Smooth lowpass with resonance";
header.tags = {"filter", "lowpass", "warm"};
header.category = "Filters";

schema.setHeader(header);

// Add parameters
schema.setParameter("cutoff", 1000.0);
schema.setParameter("resonance", 0.7);
schema.setParameter("drive", 1.2);

// Validate
if (!schema.validate()) {
    auto errors = schema.getValidationErrors();
    for (const auto& error : errors) {
        std::cerr << "Validation error: " << error << std::endl;
    }
}

// Serialize
auto json = schema.toJson();
std::cout << json.dump(2) << std::endl;

Validar preset existente

// Load from file
auto json = loadJsonFile("presets/my_preset.json");

// Parse
auto schema = PresetSchema::fromJson(json);

// Validate
SchemaValidator validator;
auto result = validator.validate(schema);

if (result.success) {
    std::cout << "Preset válido!" << std::endl;
} else {
    std::cout << "Errores encontrados:" << std::endl;
    for (const auto& error : result.errors) {
        std::cout << "  - " << error << std::endl;
    }
}

// Warnings (deprecations, etc)
if (!result.warnings.empty()) {
    std::cout << "Advertencias:" << std::endl;
    for (const auto& warning : result.warnings) {
        std::cout << "  ! " << warning << std::endl;
    }
}

Track schema evolution

SchemaEvolution evolution;

// Register changes
evolution.registerChange({
    SchemaEvolution::ChangeSet::Type::Added,
    "parameters.filter_type",
    "Added filter type selection",
    {1, 1, 0}
});

evolution.registerChange({
    SchemaEvolution::ChangeSet::Type::Deprecated,
    "parameters.old_cutoff",
    "Use 'cutoff' instead",
    {1, 2, 0}
});

// Query changes
auto changes = evolution.getChanges({1, 0, 0}, {2, 0, 0});
for (const auto& change : changes) {
    std::cout << change.description << std::endl;
}

MÉTRICAS DE ÉXITO

  • ✅ Schemas completos para L0-L3
  • ✅ Validation engine <10ms por preset
  • ✅ >90% test coverage
  • ✅ Zero schema violations en production
  • ✅ 100% backward compatibility tracking

PRÓXIMOS PASOS

  1. Implementar schema base
  2. Crear schemas específicos L0-L3
  3. Implementar validation engine
  4. Crear evolution tracker
  5. Implementar integrity checker
  6. Tests exhaustivos
  7. Documentación completa

REFERENCIAS