syntaxis/docs/provision/implementation-plan.md
Jesús Pérez 9cef9b8d57 refactor: consolidate configuration directories
Merge _configs/ into config/ for single configuration directory.
Update all path references.

Changes:
- Move _configs/* to config/
- Update .gitignore for new patterns
- No code references to _configs/ found

Impact: -1 root directory (layout_conventions.md compliance)
2025-12-26 18:36:23 +00:00

18 KiB

🚀 PLAN DE IMPLEMENTACIÓN - Syntaxis como TaskService Integrado

Fecha: 2025-11-20 Estado: Listo para implementación Precedencia: Arquitectura validada en SOLUTION_ARCHITECTURE_CORRECT.md


📋 Resumen Ejecutivo

Implementaremos una arquitectura de 3 capas que integra syntaxis con provisioning y provctl sin modificaciones forzadas a ninguno de los dos sistemas.

CAPA 1 (Provisioning)  → KCL TaskService (syntaxis.k)
         ↓ genera
CAPA 2 (provctl)       → TOML Config (syntaxis-dev.toml)
         ↑ consume
CAPA 3 (syntaxis)      → Presets (deployment-presets.kcl)

🎯 Objetivos Finales

  1. Syntaxis es un taskservs en provisioning - Definido como KCL, consumible por provisioning como cualquier otro servicio
  2. provctl puede gestionar syntaxis localmente - Sin cambios a provctl, usando TOML generado desde KCL
  3. Developer elige modo de deployment - Presets (local/dev/staging/prod) con UX clara
  4. Cero recompilación - Cambios en definición = solo guardar archivo KCL

📂 CAPA 1: TaskService en Provisioning

Ubicación y Estructura

/Users/Akasha/project-provisioning/provisioning/extensions/taskservs/development/syntaxis/
├── kcl/
│   ├── kcl.mod
│   ├── kcl.mod.lock
│   ├── syntaxis.k              ← SCHEMA PRINCIPAL
│   ├── dependencies.k          ← REQUISITOS DEL SISTEMA
│   └── version.k               ← VERSIONADO
├── default/
│   ├── install-syntaxis.sh     ← SCRIPT DE INSTALACIÓN
│   ├── env-syntaxis.j2         ← TEMPLATE VARIABLES (Tera)
│   ├── syntaxis-env.sh         ← SETUP ENVIROMENT
│   └── health-check.sh         ← VALIDACIÓN DE SALUD
├── examples/
│   ├── syntaxis-dev.k          ← EJEMPLO: DESARROLLO
│   ├── syntaxis-prod.k         ← EJEMPLO: PRODUCCIÓN
│   ├── syntaxis-staging.k      ← EJEMPLO: STAGING
│   └── README.md               ← GUÍA DE EJEMPLOS
├── README.md                   ← DOCUMENTACIÓN TASKSERV
└── .gitkeep

Paso 1.1: Crear estructura base

#!/bin/bash
set -e

TASKSERV_PATH="/Users/Akasha/project-provisioning/provisioning/extensions/taskservs/development/syntaxis"

# Crear directorios
mkdir -p "$TASKSERV_PATH/kcl"
mkdir -p "$TASKSERV_PATH/default"
mkdir -p "$TASKSERV_PATH/examples"

# Crear archivos vacíos
touch "$TASKSERV_PATH/kcl/kcl.mod"
touch "$TASKSERV_PATH/kcl/kcl.mod.lock"
touch "$TASKSERV_PATH/.gitkeep"

echo "✅ Estructura base creada"

Paso 1.2: Crear kcl/syntaxis.k

Basado en: /Users/Akasha/project-provisioning/provisioning/extensions/taskservs/development/n8n/kcl/n8n.k

Contenido esperado (263 líneas como n8n):

# syntaxis.k - Syntaxis Project Management Platform TaskService Schema
# Version: 1.0.0
# Patrón: Similar a n8n.k pero adaptado a servicios de syntaxis

schema Database:
    """Database configuration for Syntaxis"""
    typ: "sqlite" | "postgres" | "mysql" = "sqlite"
    host?: str
    port?: int
    user?: str = "syntaxis"
    password?: str
    path?: str = "/var/lib/syntaxis/db.sqlite"

schema Cache:
    """Cache configuration"""
    enabled: bool = False
    typ: "redis" | "memcached" = "redis"
    host?: str = "127.0.0.1"
    port?: int = 6379

schema API:
    """REST API Service"""
    enabled: bool = True
    port: int = 3000
    host: str = "127.0.0.1"
    protocol: "http" | "https" = "http"

schema TUI:
    """Terminal User Interface"""
    enabled: bool = False

schema Dashboard:
    """Web Dashboard"""
    enabled: bool = False
    port: int = 8080

schema CLI:
    """Command Line Interface"""
    enabled: bool = True

schema Syntaxis:
    """Syntaxis Project Management Platform"""
    name: str = "syntaxis"
    version: str = "1.0.0"
    work_path: str = "/var/lib/syntaxis"

    cli: CLI = { enabled = True }
    api: API = { enabled = False, port = 3000 }
    tui: TUI = { enabled = False }
    dashboard: Dashboard = { enabled = False, port = 8080 }

    db: Database = { typ = "sqlite" }
    cache: Cache = { enabled = False }

    log_level: str = "info"
    dependencies: [str] = []

schema Syntaxis_Dev(Syntaxis):
    """Development configuration"""
    api.enabled = True
    api.protocol = "http"
    api.port = 3000

    dashboard.enabled = True
    dashboard.port = 8080

    db.typ = "sqlite"
    db.path = "/var/lib/syntaxis/syntaxis-dev.db"

    log_level = "debug"
    dependencies = ["surrealdb"]

schema Syntaxis_Production(Syntaxis):
    """Production configuration"""
    api.enabled = True
    api.protocol = "https"
    api.port = 443

    dashboard.enabled = True
    dashboard.port = 8080

    db.typ = "postgres"
    db.host = "localhost"
    db.port = 5432
    db.user = "syntaxis"
    db.password = "***"

    cache.enabled = True
    cache.typ = "redis"
    cache.host = "localhost"
    cache.port = 6379

    log_level = "warn"
    dependencies = ["postgres", "redis", "nats"]

# Instancia para desarrollo
syntaxis_dev: Syntaxis = Syntaxis_Dev {
    name = "syntaxis-dev"
}

# Instancia para producción
syntaxis_prod: Syntaxis = Syntaxis_Production {
    name = "syntaxis-prod"
}

Archivos de referencia:

  • Real n8n schema: /Users/Akasha/project-provisioning/provisioning/extensions/taskservs/development/n8n/kcl/n8n.k
  • Postgres example: /Users/Akasha/project-provisioning/provisioning/extensions/taskservs/databases/postgres/kcl/postgres.k

Paso 1.3: Crear kcl/dependencies.k

# dependencies.k - System requirements for Syntaxis TaskService

schema SystemRequirement:
    name: str
    version: str
    optional: bool = False

system_requirements = [
    SystemRequirement {
        name = "rust"
        version = "1.75+"
        optional = True
    }
    SystemRequirement {
        name = "systemd"
        version = "latest"
        optional = False
    }
]

health_checks = [
    {
        type = "http"
        endpoint = "http://127.0.0.1:3000/health"
        interval_seconds = 10
        timeout_seconds = 5
    }
]

Paso 1.4: Crear default/install-syntaxis.sh

#!/bin/bash
# install-syntaxis.sh - Installation script for Syntaxis TaskService
# Template: Will be processed by Tera during provisioning build

set -e

SYNTAXIS_VERSION="{{version}}"
WORK_PATH="{{work_path}}"
LOG_LEVEL="{{log_level}}"

echo "Installing Syntaxis ${SYNTAXIS_VERSION}..."

# Create directories
mkdir -p "${WORK_PATH}"
mkdir -p /var/lib/syntaxis/db
mkdir -p /var/log/syntaxis

# Download/install binary
# (This would come from actual build/release process)
# For now: placeholder
echo "✅ Syntaxis installed to ${WORK_PATH}"
echo "✅ Log level: ${LOG_LEVEL}"

Paso 1.5: Crear default/env-syntaxis.j2

{# env-syntaxis.j2 - Environment variables template for Syntaxis #}
{# Processed by Tera during provisioning build #}

# Syntaxis Environment Configuration
export SYNTAXIS_WORK_PATH="{{ work_path }}"
export SYNTAXIS_LOG_LEVEL="{{ log_level }}"

# API Configuration
export SYNTAXIS_API_ENABLED="{{ api.enabled }}"
export SYNTAXIS_API_PORT="{{ api.port }}"
export SYNTAXIS_API_HOST="{{ api.host }}"
export SYNTAXIS_API_PROTOCOL="{{ api.protocol }}"

# Database Configuration
export SYNTAXIS_DB_TYPE="{{ db.typ }}"
{% if db.typ == "sqlite" %}
export DATABASE_URL="sqlite://{{ db.path }}"
{% elif db.typ == "postgres" %}
export DATABASE_URL="postgres://{{ db.user }}@{{ db.host }}:{{ db.port }}/syntaxis"
{% endif %}

# Cache Configuration
export SYNTAXIS_CACHE_ENABLED="{{ cache.enabled }}"
{% if cache.enabled %}
export REDIS_URL="redis://{{ cache.host }}:{{ cache.port }}"
{% endif %}

# Logging
export RUST_LOG="{{ log_level }}"

Paso 1.6: Crear examples/syntaxis-dev.k

# examples/syntaxis-dev.k - Development preset configuration

import ..kcl.syntaxis as sx

# Development configuration instance
config_dev: sx.Syntaxis = sx.Syntaxis_Dev {
    name = "syntaxis-dev"
    version = "latest"
    work_path = "/var/lib/syntaxis"
    log_level = "debug"
}

Paso 1.7: Crear examples/syntaxis-prod.k

# examples/syntaxis-prod.k - Production preset configuration

import ..kcl.syntaxis as sx

# Production configuration instance
config_prod: sx.Syntaxis = sx.Syntaxis_Production {
    name = "syntaxis-prod"
    version = "1.0.0"
    work_path = "/var/lib/syntaxis"
    log_level = "warn"
}

📂 CAPA 2: Configuración para provctl

Ubicación y Estructura

/Users/Akasha/Development/provctl/examples/stage1-extended-definitions/
├── syntaxis-local-dev.toml     ← DESARROLLO LOCAL
├── syntaxis-staging.toml       ← STAGING
├── syntaxis-prod.toml          ← PRODUCCIÓN
└── README.md                   ← DOCUMENTACIÓN

Paso 2.1: Crear syntaxis-local-dev.toml

Basado en: /Users/Akasha/Development/provctl/examples/stage1-extended-definitions/minimal-app.toml

# syntaxis-local-dev.toml
# Configuration for syntaxis in local development environment
# Consumed by: provctl
# Generated from: provisioning/extensions/taskservs/development/syntaxis/kcl/syntaxis.k

[service]
name = "syntaxis-api"
binary = "/usr/local/bin/syntaxis-api"
args = ["--bind", "127.0.0.1:3000", "--log-level", "debug"]
working_directory = "/var/lib/syntaxis"
restart_strategy = "on_failure"
restart_delay_seconds = 5

[service.env_vars]
DATABASE_URL = "sqlite:///var/lib/syntaxis/syntaxis-dev.db"
RUST_LOG = "debug"
SYNTAXIS_LOG_LEVEL = "debug"
SYNTAXIS_WORK_PATH = "/var/lib/syntaxis"

[service.user]
name = "syntaxis"
uid = 1001
gid = 1001
home = "/var/lib/syntaxis"

[[health_checks]]
type = "http"
endpoint = "http://127.0.0.1:3000/health"
interval_seconds = 10
timeout_seconds = 5
unhealthy_threshold = 3

[[data_services]]
name = "surrealdb"
type = "SurrealDB"
url = "http://127.0.0.1:8000"
required = false

[networking]
port_bindings = [
    { service_port = 3000, host_port = 3000, protocol = "tcp" }
]

[logging]
enabled = true
output_path = "/var/log/syntaxis/api.log"
level = "debug"

Paso 2.2: Crear syntaxis-prod.toml

# syntaxis-prod.toml
# Configuration for syntaxis in production environment
# Consumed by: provctl
# Generated from: provisioning/extensions/taskservs/development/syntaxis/kcl/syntaxis.k

[service]
name = "syntaxis-api"
binary = "/usr/local/bin/syntaxis-api"
args = ["--bind", "0.0.0.0:3000", "--log-level", "warn"]
working_directory = "/var/lib/syntaxis"
restart_strategy = "always"
restart_delay_seconds = 10

[service.env_vars]
DATABASE_URL = "postgres://syntaxis:***@postgres.local:5432/syntaxis"
RUST_LOG = "warn"
SYNTAXIS_LOG_LEVEL = "warn"
SYNTAXIS_WORK_PATH = "/var/lib/syntaxis"

[service.user]
name = "syntaxis"
uid = 1001
gid = 1001
home = "/var/lib/syntaxis"

[[health_checks]]
type = "http"
endpoint = "http://127.0.0.1:3000/health"
interval_seconds = 30
timeout_seconds = 10
unhealthy_threshold = 5

[[data_services]]
name = "postgres"
type = "PostgreSQL"
url = "postgres://localhost:5432"
required = true

[[data_services]]
name = "redis"
type = "Redis"
url = "redis://127.0.0.1:6379"
required = true

[networking]
port_bindings = [
    { service_port = 3000, host_port = 3000, protocol = "tcp" }
]

[logging]
enabled = true
output_path = "/var/log/syntaxis/api.log"
level = "warn"
rotation = "daily"
retention_days = 30

📂 CAPA 3: Presets en Syntaxis

Ubicación y Estructura

/Users/Akasha/Development/syntaxis/configs/
├── deployment-presets.kcl      ← PRESETS DECLARATIVOS (NUEVO)
└── database.toml               ← (Existente)

Paso 3.1: Crear deployment-presets.kcl

# configs/deployment-presets.kcl
# Deployment mode presets for Syntaxis
# Consumed by: syntaxis-installer
# Defines different deployment scenarios (local, dev, staging, production)

schema DeploymentMode:
    """Defines how syntaxis should be deployed"""
    name: str
    description: str
    services_enabled: [str]  # Which services to enable
    manager: "manual" | "provctl" | "provisioning" = "manual"
    auto_start: bool = False
    health_checks_enabled: bool = False

# LOCAL: CLI only (manual, no daemon)
mode_local: DeploymentMode = {
    name = "local"
    description = "Single machine, CLI only (manual execution)"
    services_enabled = ["cli"]
    manager = "manual"
    auto_start = False
    health_checks_enabled = False
}

# DEVELOPMENT: Full stack with provctl
mode_dev: DeploymentMode = {
    name = "dev"
    description = "Full development stack with provctl orchestration"
    services_enabled = ["cli", "api", "tui", "dashboard", "database"]
    manager = "provctl"
    auto_start = True
    health_checks_enabled = True
}

# STAGING: Multi-machine with provisioning
mode_staging: DeploymentMode = {
    name = "staging"
    description = "Staging environment on multiple machines"
    services_enabled = ["cli", "api", "dashboard", "database", "cache"]
    manager = "provisioning"
    auto_start = True
    health_checks_enabled = True
}

# PRODUCTION: HA with provisioning
mode_production: DeploymentMode = {
    name = "production"
    description = "Production environment with high availability"
    services_enabled = ["api", "dashboard", "database", "cache", "nats"]
    manager = "provisioning"
    auto_start = True
    health_checks_enabled = True
}

# All presets
deployment_modes = {
    local = mode_local
    dev = mode_dev
    staging = mode_staging
    production = mode_production
}

🔄 Paso 4: Integración - Conexión entre Capas

4.1: Generación TOML desde KCL (En provisioning build)

En provisioning CI/build pipeline (pseudocódigo):

# 1. Compilar KCL schema
kcl compile provisioning/extensions/taskservs/development/syntaxis/kcl/syntaxis.k

# 2. Generar TOML para provctl usando Tera template
for preset in dev staging prod; do
    kcl_values=$(kcl export syntaxis_$preset)
    tera --template default/env-syntaxis.j2 \
         --values $kcl_values \
         --output generated/provctl/syntaxis-${preset}.toml
done

# 3. Validar TOML generado
provctl config validate generated/provctl/syntaxis-*.toml

echo "✅ Generated TOML configurations for provctl"

4.2: Consumo en syntaxis-installer

En syntaxis-installer (pseudocódigo):

// Load deployment presets
let presets = load_kcl("syntaxis/configs/deployment-presets.kcl");

// Ask user which mode
let selected = user_choose_preset(presets);

// Check if provctl available
if provctl_available() && selected.manager == "provctl" {
    // Auto-configure with provctl
    let config = load_toml(&format!("provctl/syntaxis-{}.toml", selected.name));
    provctl::apply(config)?;
} else if selected.manager == "provisioning" {
    // Guide for provisioning setup
    println!("Use provisioning for this mode...");
} else {
    // Manual setup
    println!("Manual setup instructions...");
}

Checklist de Implementación

Fase 1: Crear TaskService (Provisioning)

  • Crear estructura base en /provisioning/extensions/taskservs/development/syntaxis/
  • Crear kcl/syntaxis.k con schemas (base + dev + prod)
  • Crear kcl/dependencies.k con requisitos
  • Crear default/install-syntaxis.sh
  • Crear default/env-syntaxis.j2 template
  • Crear ejemplos en examples/
  • Validar KCL compila sin errores
  • Documentar en README.md

Fase 2: Crear Configs provctl

  • Crear syntaxis-local-dev.toml en provctl
  • Crear syntaxis-prod.toml en provctl
  • Crear syntaxis-staging.toml en provctl
  • Validar TOML syntax
  • Probar con provctl config validate

Fase 3: Crear Presets en syntaxis

  • Crear syntaxis/configs/deployment-presets.kcl
  • Definir 4 modos (local, dev, staging, production)
  • Validar KCL compila
  • Documentar en README

Fase 4: Integración

  • Configurar generación TOML en provisioning build
  • Agregar script de validación TOML
  • Extender syntaxis-installer para leer presets
  • Implementar detección de provctl
  • Implementar flujo de aplicación automática
  • Crear tests de integración

Fase 5: Testing & Validation

  • Unit tests para cada KCL schema
  • Integration tests: KCL → TOML → provctl
  • E2E test: installer completo
  • Documentar ejemplos de uso

📊 Matrices de Decisión

¿KCL o YAML para presets?

Aspecto KCL YAML
Type-safety Nativo Ninguna
Validation Nativo Manual
Consistency Enforced ⚠️ Conventions
Learning curve ⚠️ Moderate Low
Ecosystem fit Already using ⚠️ Different

Decisión: KCL (aprovecha inversión existente en provisioning)

¿Generar TOML en build o runtime?

Aspecto Build time Runtime
Performance Fast ⚠️ Slower
Consistency Deterministic ⚠️ Variable
Debugging Static ⚠️ Dynamic
Flexibility ⚠️ Fixed Dynamic

Decisión: Build time (Option A en PROVCTL_KCL_INTEGRATION.md)


🎯 Resultado Final

Después de completar todos los pasos:

syntaxis-installer --preset dev
  ↓
1. Lee deployment-presets.kcl
2. Muestra opción: "¿Quieres desarrollo automático con provctl?"
3. Si SÍ:
   - Detecta provctl disponible
   - Carga syntaxis/configs/deployment-presets.kcl
   - Lee provisioning taskserv (syntaxis.k)
   - Obtiene config TOML generada (syntaxis-dev.toml)
   - Ejecuta: provctl config apply syntaxis-dev.toml
   - Inicia servicios automáticamente
   ✅ "Listo para usar"
4. Si NO:
   - Muestra guía manual para configuración

🔗 Documentos Relacionados

  • SOLUTION_ARCHITECTURE_CORRECT.md - Arquitectura detallada con ejemplos
  • PROVCTL_KCL_INTEGRATION.md - Respuesta a "¿Provctl necesita cambios?"
  • CURRENT_STATE_ANALYSIS.md - Análisis de estado actual
  • README_CLEAN.md - Resumen ejecutivo

📝 Notas Importantes

  1. No hay cambios a provctl - Solo consumir TOML generado
  2. No hay cambios a provisioning - Solo usar patrón existente (taskservs)
  3. No hay recompilación - Cambios en KCL = solo guardar archivo
  4. Reutilizable - Otros proyectos pueden seguir el mismo patrón
  5. Fallback graceful - Si no hay provctl/provisioning, guía manual

Siguiente paso: Proceder con Fase 1 (Crear TaskService en provisioning)