Skip to content

spec.yaml Format

Main structure

# spec.yaml - Complete module specification

module:
  name: "GavonaService"          # PascalCase name
  version: "1.0.0"               # Semantic versioning
  description: "Service module for managing interventions"
  dependencies:
    - "AutoCRM >= 1.0"
    - "Sales >= 1.0"

entities:
  ServiceRequest:
    # ... entity definition

workflows:
  ServiceRequestAssignment:
    # ... workflow definition

integrations:
  pohodaExport:
    # ... integration definition

Entity Definition

entities:
  ServiceRequest:
    # Basic metadata
    label: "Service request"
    labelPlural: "Service requests"
    type: "Base"                   # Base|BasePlus|Event|Person|Company
    table: "service_request"       # snake_case
    iconClass: "fas fa-wrench"
    color: "#e74c3c"

    # Field definitions
    fields:
      number:
        type: "autoincrement"
        pattern: "SRV-{YYYY}-{0000}"
        label: "Request number"
        required: true
        readonly: true

      account:
        type: "link"
        entity: "Account"
        label: "Account"
        required: true
        audited: true              # Log changes

      priority:
        type: "enum"
        options:
          - value: "Critical"
            label: "Critical"
            color: "#dc3545"
            style:
              fontWeight: "bold"
          - value: "High"
            label: "High"
            color: "#fd7e14"
          - value: "Normal"
            label: "Normal"
            color: "#0d6efd"
          - value: "Low"
            label: "Low"
            color: "#6c757d"
        default: "Normal"
        required: true

      status:
        type: "enum"
        options:
          - "New"
          - "Assigned"
          - "InProgress"
          - "WaitingParts"
          - "Completed"
          - "Invoiced"
          - "Cancelled"
        default: "New"
        required: true
        audited: true

      description:
        type: "text"
        label: "Issue description"
        required: true
        rowsMin: 3
        rowsMax: 10

      estimatedHours:
        type: "float"
        label: "Estimated hours"
        min: 0
        decimalPlaces: 1

    # Relations to other entities
    links:
      account:
        type: "belongsTo"
        entity: "Account"
        foreign: "serviceRequests"

      assignedUser:
        type: "belongsTo"
        entity: "User"
        foreign: "assignedServiceRequests"

      trips:
        type: "hasMany"
        entity: "ServiceTrip"
        foreign: "serviceRequestId"

    # UI Layouts
    layouts:
      detail:
        - panel: "default"
          label: "Basic information"
          rows:
            - ["number", "status"]
            - ["account", "priority"]
            - ["assignedUser", "estimatedHours"]

        - panel: "description"
          label: "Description"
          rows:
            - ["description"]

      list:
        columns:
          - name: "number"
            width: 120
            link: true
          - name: "account"
            width: 200
          - name: "priority"
            width: 100
          - name: "status"
            width: 120
          - name: "assignedUser"
            width: 150

      filters:
        - "status"
        - "priority"
        - "assignedUser"
        - "account"

    # Database indexes
    indexes:
      - fields: ["accountId", "status"]
      - fields: ["assignedUserId", "status"]
      - fields: ["createdAt"]

Workflow Definition

workflows:
  ServiceRequestAutoAssignment:
    trigger: "afterSave"
    entity: "ServiceRequest"
    isActive: true

    conditions:
      - type: "fieldEquals"
        field: "status"
        value: "New"

      - type: "fieldIsEmpty"
        field: "assignedUserId"

      - type: "formula"
        formula: "entity.get('priority') == 'Critical'"

    actions:
      - type: "notification"
        target: "role:Dispatcher"
        template: "critical_service_request"
        message: "New critical request: {entity.number}"

      - type: "createTask"
        entity: "Task"
        data:
          name: "Assign technician: {entity.number}"
          assignedUserId: "role:Dispatcher"
          dateEnd: "{dateAdd(now, 1, 'hour')}"
          priority: "Urgent"

      - type: "updateEntity"
        field: "status"
        value: "Assigned"
        when: "assignedUserId IS NOT NULL"

  ServiceRequestCompletion:
    trigger: "afterSave"
    entity: "ServiceRequest"

    conditions:
      - type: "fieldChanged"
        field: "status"

      - type: "fieldEquals"
        field: "status"
        value: "Completed"

    actions:
      - type: "sendEmail"
        to: "{entity.account.emailAddress}"
        template: "service_completed"

      - type: "executeFormula"
        formula: |
          entity.set('completedAt', datetime.now());
          entity.set('completedById', user.id);

➡️ Continue to Acceptance criteria.