{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "FOXY Planner — protocolo de comandos",
  "version": "1.0",
  "envelope": {
    "type": "object",
    "required": [
      "version",
      "source",
      "commands"
    ],
    "properties": {
      "version": {
        "type": "string",
        "const": "1.0"
      },
      "source": {
        "type": "string",
        "enum": [
          "chatgpt",
          "claude",
          "codex",
          "gemini",
          "agent",
          "ui",
          "unknown"
        ]
      },
      "intent": {
        "type": "string",
        "description": "O que o lote pretende, em uma frase. Vai para o histórico."
      },
      "confirmDestructive": {
        "type": "boolean",
        "default": false,
        "description": "Obrigatório em comandos que exigem confirmação. Quem libera é o humano."
      },
      "commands": {
        "type": "array",
        "minItems": 1,
        "items": {
          "$ref": "#/commands"
        }
      }
    }
  },
  "batch": {
    "description": "Todo envelope já é um lote: vários comandos rodam em ordem numa requisição. Um create declara \"ref\" e os comandos seguintes apontam para ele com \"ref:apelido\". Se qualquer comando falhar, os anteriores são desfeitos — o lote é tudo ou nada.",
    "example": {
      "version": "1.0",
      "source": "chatgpt",
      "intent": "Campanha de agosto da TURAZZA",
      "commands": [
        {
          "command": "create_project",
          "ref": "camp",
          "params": {
            "title": "Campanha de Agosto",
            "workspace": "TURAZZA"
          }
        },
        {
          "command": "create_card",
          "params": {
            "title": "Roteiro",
            "column": "Conteúdo TURAZZA / A fazer",
            "project": "ref:camp"
          }
        }
      ]
    }
  },
  "aliases": {
    "create_task": "create_subtask",
    "update_task": "update_subtask",
    "delete_project": "archive_project",
    "delete_workspace": "archive_workspace"
  },
  "validation_rules": [
    "A versão do protocolo precisa bater.",
    "Todo campo obrigatório precisa estar presente e com o tipo certo.",
    "Todo campo do tipo entity precisa ser encontrado, e encontrado uma vez só.",
    "Nome ambíguo é recusado; use o id ou a forma \"Board / Coluna\".",
    "Duplicidade é recusada: workspace com nome repetido, projeto repetido no mesmo workspace, card repetido na mesma coluna, apelido ref repetido.",
    "Conflito é recusado: mover card para a coluna onde já está, update sem campo para alterar, subtarefa sem card nem projeto.",
    "Comando destrutivo sem confirmDestructive: true é recusado.",
    "Qualquer problema aborta o lote inteiro; nada é executado pela metade."
  ],
  "rules": [
    "Ler o manual antes de operar.",
    "Pesquisar antes de criar.",
    "Não duplicar objetos.",
    "Não excluir sem confirmação explícita.",
    "Preferir arquivamento a exclusão.",
    "Nunca exibir senhas nos logs.",
    "Validar o resultado após executar."
  ],
  "commands": {
    "create_workspace": {
      "type": "object",
      "title": "create_workspace",
      "description": "Cria um workspace (cliente ou marca) dentro de uma unidade.",
      "target": "workspace",
      "effect": "create",
      "requires_confirmation": false,
      "properties": {
        "name": {
          "description": "Nome do workspace.",
          "type": "string",
          "examples": [
            "NOVA MARCA"
          ]
        },
        "business_unit": {
          "description": "Unidade dona do workspace (MELLOW, FOXY, PESSOAL). Sem isto fica \"sem unidade\".",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um business_unit criado antes no mesmo lote."
        },
        "workspace_kind": {
          "description": "Natureza do workspace.",
          "type": "string",
          "enum": [
            "client_or_brand",
            "product_base",
            "client_implementation",
            "internal",
            "personal"
          ],
          "default": "client_or_brand"
        },
        "description": {
          "description": "Descrição livre.",
          "type": "string"
        }
      },
      "required": [
        "name"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "create_workspace",
          "ref": "nova-marca",
          "params": {
            "name": "NOVA MARCA",
            "business_unit": "MELLOW",
            "workspace_kind": "client_or_brand"
          }
        }
      ]
    },
    "update_workspace": {
      "type": "object",
      "title": "update_workspace",
      "description": "Renomeia um workspace ou muda a unidade/natureza dele.",
      "target": "workspace",
      "effect": "update",
      "requires_confirmation": false,
      "properties": {
        "workspace": {
          "description": "Workspace alvo.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um workspace criado antes no mesmo lote."
        },
        "name": {
          "description": "Novo nome.",
          "type": "string"
        },
        "business_unit": {
          "description": "Nova unidade.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um business_unit criado antes no mesmo lote."
        },
        "workspace_kind": {
          "description": "Nova natureza.",
          "type": "string",
          "enum": [
            "client_or_brand",
            "product_base",
            "client_implementation",
            "internal",
            "personal"
          ]
        },
        "description": {
          "description": "Nova descrição.",
          "type": "string"
        }
      },
      "required": [
        "workspace"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "update_workspace",
          "params": {
            "workspace": "PRO ACE",
            "name": "POSTO 011"
          }
        }
      ]
    },
    "archive_workspace": {
      "type": "object",
      "title": "archive_workspace",
      "description": "Tira um workspace da navegação. Não apaga nada e é reversível.",
      "target": "workspace",
      "effect": "archive",
      "requires_confirmation": true,
      "confirmation_reason": "Some da navegação inteira: sidebar, dashboard, missões, calendário e financeiro deixam de mostrar o conteúdo.",
      "properties": {
        "workspace": {
          "description": "Workspace alvo.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um workspace criado antes no mesmo lote."
        },
        "archived": {
          "description": "false para desarquivar.",
          "type": "boolean",
          "default": true
        }
      },
      "required": [
        "workspace"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "archive_workspace",
          "params": {
            "workspace": "OUTROS"
          }
        }
      ]
    },
    "create_project": {
      "type": "object",
      "title": "create_project",
      "description": "Cria um projeto dentro de um workspace. Projeto é uma missão no banco.",
      "target": "project",
      "effect": "create",
      "requires_confirmation": false,
      "properties": {
        "title": {
          "description": "Nome do projeto.",
          "type": "string",
          "examples": [
            "Campanha Agosto"
          ]
        },
        "workspace": {
          "description": "Workspace dono.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um workspace criado antes no mesmo lote."
        },
        "parent_project": {
          "description": "Projeto-pai, quando este é um subprojeto (a \"pasta\" que agrupa).",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um project criado antes no mesmo lote."
        },
        "objective": {
          "description": "Objetivo do projeto.",
          "type": "string"
        },
        "description": {
          "description": "Descrição livre.",
          "type": "string"
        },
        "status": {
          "description": "Status.",
          "type": "string",
          "enum": [
            "planning",
            "active",
            "paused",
            "completed",
            "cancelled"
          ],
          "default": "planning"
        },
        "mission_type": {
          "description": "Tipo.",
          "type": "string",
          "enum": [
            "pontual",
            "continuo",
            "recorrente",
            "campanha"
          ],
          "default": "pontual"
        },
        "priority": {
          "description": "Prioridade.",
          "type": "string",
          "enum": [
            "low",
            "medium",
            "high",
            "critical"
          ],
          "default": "medium"
        },
        "start_date": {
          "description": "Início (YYYY-MM-DD).",
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        "end_date": {
          "description": "Prazo (YYYY-MM-DD).",
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        "next_action": {
          "description": "Próxima ação. Todo projeto ativo deveria ter uma.",
          "type": "string"
        },
        "next_action_due_date": {
          "description": "Prazo da próxima ação.",
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        "estimated_hours": {
          "description": "Horas estimadas, usadas no cálculo de sobrecarga.",
          "type": "number"
        }
      },
      "required": [
        "title",
        "workspace"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "create_project",
          "ref": "campanha-agosto",
          "params": {
            "title": "Campanha Agosto",
            "workspace": "TURAZZA",
            "status": "active",
            "next_action": "Fechar roteiro"
          }
        }
      ]
    },
    "update_project": {
      "type": "object",
      "title": "update_project",
      "description": "Altera campos de um projeto existente.",
      "target": "project",
      "effect": "update",
      "requires_confirmation": false,
      "properties": {
        "project": {
          "description": "Projeto alvo.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um project criado antes no mesmo lote."
        },
        "title": {
          "description": "Novo nome.",
          "type": "string"
        },
        "objective": {
          "description": "Novo objetivo.",
          "type": "string"
        },
        "description": {
          "description": "Nova descrição.",
          "type": "string"
        },
        "status": {
          "description": "Novo status.",
          "type": "string",
          "enum": [
            "planning",
            "active",
            "paused",
            "completed",
            "cancelled"
          ]
        },
        "priority": {
          "description": "Nova prioridade.",
          "type": "string",
          "enum": [
            "low",
            "medium",
            "high",
            "critical"
          ]
        },
        "start_date": {
          "description": "Novo início.",
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        "end_date": {
          "description": "Novo prazo.",
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        "next_action": {
          "description": "Nova próxima ação.",
          "type": "string"
        },
        "next_action_due_date": {
          "description": "Novo prazo da próxima ação.",
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        "estimated_hours": {
          "description": "Novas horas estimadas.",
          "type": "number"
        }
      },
      "required": [
        "project"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "update_project",
          "params": {
            "project": "Campanha Agosto",
            "next_action": "Aprovar roteiro com o cliente"
          }
        }
      ]
    },
    "archive_project": {
      "type": "object",
      "title": "archive_project",
      "description": "Conclui um projeto (status completed). Ele passa a viver em Arquivados.",
      "target": "project",
      "effect": "archive",
      "requires_confirmation": false,
      "properties": {
        "project": {
          "description": "Projeto alvo.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um project criado antes no mesmo lote."
        },
        "status": {
          "description": "Como encerrar.",
          "type": "string",
          "enum": [
            "completed",
            "cancelled"
          ],
          "default": "completed"
        }
      },
      "required": [
        "project"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "archive_project",
          "params": {
            "project": "Campanha Agosto"
          }
        }
      ]
    },
    "create_card": {
      "type": "object",
      "title": "create_card",
      "description": "Cria um card. Precisa de uma coluna; informe a coluna ou o projeto e o board.",
      "target": "card",
      "effect": "create",
      "requires_confirmation": false,
      "properties": {
        "title": {
          "description": "Título do card.",
          "type": "string",
          "examples": [
            "Roteiro"
          ]
        },
        "column": {
          "description": "Coluna onde o card nasce. Use \"Board / Coluna\" quando o nome da coluna se repetir.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um column criado antes no mesmo lote."
        },
        "project": {
          "description": "Projeto ao qual o card pertence.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um project criado antes no mesmo lote."
        },
        "description": {
          "description": "Descrição.",
          "type": "string"
        },
        "card_type": {
          "description": "Tipo do card.",
          "type": "string",
          "enum": [
            "content",
            "financial",
            "task",
            "mixed",
            "recording",
            "campaign",
            "meeting",
            "credential"
          ],
          "default": "task"
        },
        "status": {
          "description": "Status.",
          "type": "string",
          "enum": [
            "planned",
            "in_production",
            "scheduled",
            "posted",
            "cancelled"
          ],
          "default": "planned"
        },
        "production_stage": {
          "description": "Etapa de produção.",
          "type": "string",
          "enum": [
            "idea",
            "recording",
            "editing",
            "approval",
            "scheduled",
            "posted"
          ]
        },
        "start_date": {
          "description": "Data de início (YYYY-MM-DD).",
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        "end_date": {
          "description": "Data de entrega (YYYY-MM-DD).",
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        }
      },
      "required": [
        "title",
        "column"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "create_card",
          "params": {
            "title": "Roteiro",
            "column": "A fazer",
            "project": "ref:campanha-agosto",
            "card_type": "task"
          }
        }
      ]
    },
    "update_card": {
      "type": "object",
      "title": "update_card",
      "description": "Altera campos de um card. Para trocar de coluna use move_card.",
      "target": "card",
      "effect": "update",
      "requires_confirmation": false,
      "properties": {
        "card": {
          "description": "Card alvo.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um card criado antes no mesmo lote."
        },
        "title": {
          "description": "Novo título.",
          "type": "string"
        },
        "description": {
          "description": "Nova descrição.",
          "type": "string"
        },
        "status": {
          "description": "Novo status.",
          "type": "string",
          "enum": [
            "planned",
            "in_production",
            "scheduled",
            "posted",
            "cancelled"
          ]
        },
        "card_type": {
          "description": "Novo tipo.",
          "type": "string",
          "enum": [
            "content",
            "financial",
            "task",
            "mixed",
            "recording",
            "campaign",
            "meeting",
            "credential"
          ]
        },
        "production_stage": {
          "description": "Nova etapa.",
          "type": "string",
          "enum": [
            "idea",
            "recording",
            "editing",
            "approval",
            "scheduled",
            "posted"
          ]
        },
        "start_date": {
          "description": "Nova data de início.",
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        "end_date": {
          "description": "Nova data de entrega.",
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        "project": {
          "description": "Vincular a outro projeto.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um project criado antes no mesmo lote."
        }
      },
      "required": [
        "card"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "update_card",
          "params": {
            "card": "Roteiro",
            "status": "in_production"
          }
        }
      ]
    },
    "move_card": {
      "type": "object",
      "title": "move_card",
      "description": "Move um card para outra coluna e/ou posição.",
      "target": "card",
      "effect": "update",
      "requires_confirmation": false,
      "properties": {
        "card": {
          "description": "Card a mover.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um card criado antes no mesmo lote."
        },
        "column": {
          "description": "Coluna de destino.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um column criado antes no mesmo lote."
        },
        "position": {
          "description": "Posição na coluna. Sem isto, vai para o fim.",
          "type": "number"
        }
      },
      "required": [
        "card",
        "column"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "move_card",
          "params": {
            "card": "Roteiro",
            "column": "Concluído"
          }
        }
      ]
    },
    "create_subtask": {
      "type": "object",
      "title": "create_subtask",
      "description": "Cria uma subtarefa dentro de um card ou de um projeto.",
      "target": "subtask",
      "effect": "create",
      "requires_confirmation": false,
      "properties": {
        "title": {
          "description": "Título da subtarefa.",
          "type": "string"
        },
        "card": {
          "description": "Card dono. Informe card ou project.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um card criado antes no mesmo lote."
        },
        "project": {
          "description": "Projeto dono. Informe card ou project.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um project criado antes no mesmo lote."
        },
        "description": {
          "description": "Detalhe.",
          "type": "string"
        },
        "due_date": {
          "description": "Prazo (YYYY-MM-DD).",
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        "position": {
          "description": "Ordem. Sem isto, vai para o fim.",
          "type": "number"
        }
      },
      "required": [
        "title"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "create_subtask",
          "params": {
            "title": "Levantar referências",
            "card": "Roteiro"
          }
        }
      ]
    },
    "update_subtask": {
      "type": "object",
      "title": "update_subtask",
      "description": "Altera ou conclui uma subtarefa.",
      "target": "subtask",
      "effect": "update",
      "requires_confirmation": false,
      "properties": {
        "subtask": {
          "description": "Subtarefa alvo.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um subtask criado antes no mesmo lote."
        },
        "title": {
          "description": "Novo título.",
          "type": "string"
        },
        "description": {
          "description": "Novo detalhe.",
          "type": "string"
        },
        "is_completed": {
          "description": "true conclui, false reabre.",
          "type": "boolean"
        },
        "due_date": {
          "description": "Novo prazo.",
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        }
      },
      "required": [
        "subtask"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "update_subtask",
          "params": {
            "subtask": "Levantar referências",
            "is_completed": true
          }
        }
      ]
    },
    "create_contract": {
      "type": "object",
      "title": "create_contract",
      "description": "Cria um contrato para um cliente da operação, com um ou mais itens de receita.",
      "target": "contract",
      "effect": "create",
      "requires_confirmation": true,
      "confirmation_reason": "Mexe em valores financeiros e altera o recorrente mensal conhecido.",
      "properties": {
        "client": {
          "description": "Cliente da operação (casa por nome ou alias).",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um workspace criado antes no mesmo lote."
        },
        "name": {
          "description": "Nome do contrato.",
          "type": "string"
        },
        "items": {
          "description": "Itens de receita no formato \"Nome|valor|tipo\", com valor em reais e tipo em service/hosting/barter/sporadic/future_product/internal. Hospedagem entra como item separado do serviço.",
          "type": "array",
          "items": {
            "type": "string"
          },
          "examples": [
            [
              "Comunicação e marketing|3000|service",
              "Hospedagem|49.90|hosting"
            ]
          ]
        },
        "confirmed_schedule": {
          "description": "Blocos fixos combinados, em texto.",
          "type": "string"
        },
        "billing_notes": {
          "description": "Observações de cobrança.",
          "type": "string"
        }
      },
      "required": [
        "client",
        "name",
        "items"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "create_contract",
          "params": {
            "client": "FILTROS SA",
            "name": "Google Ads + hospedagem",
            "items": [
              "Gestão de Google Ads|600|service",
              "Hospedagem|49.90|hosting"
            ]
          }
        }
      ]
    },
    "update_contract": {
      "type": "object",
      "title": "update_contract",
      "description": "Altera um contrato existente.",
      "target": "contract",
      "effect": "update",
      "requires_confirmation": true,
      "confirmation_reason": "Mexe em valores financeiros e altera o recorrente mensal conhecido.",
      "properties": {
        "contract": {
          "description": "Contrato alvo.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um contract criado antes no mesmo lote."
        },
        "name": {
          "description": "Novo nome.",
          "type": "string"
        },
        "status": {
          "description": "Novo status.",
          "type": "string",
          "enum": [
            "active",
            "paused",
            "archived"
          ]
        },
        "confirmed_schedule": {
          "description": "Novos blocos fixos.",
          "type": "string"
        },
        "billing_notes": {
          "description": "Novas observações.",
          "type": "string"
        }
      },
      "required": [
        "contract"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "update_contract",
          "params": {
            "contract": "Google Ads + hospedagem",
            "status": "paused"
          }
        }
      ]
    },
    "add_access": {
      "type": "object",
      "title": "add_access",
      "description": "Dá a um membro acesso a um board específico.",
      "target": "board",
      "effect": "create",
      "requires_confirmation": true,
      "confirmation_reason": "Altera permissões: muda o que uma pessoa enxerga no sistema.",
      "properties": {
        "user": {
          "description": "Membro (e-mail ou id).",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um user criado antes no mesmo lote."
        },
        "board": {
          "description": "Board liberado.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um board criado antes no mesmo lote."
        }
      },
      "required": [
        "user",
        "board"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "add_access",
          "params": {
            "user": "pessoa@exemplo.com",
            "board": "Conteúdo TURAZZA"
          }
        }
      ]
    },
    "update_access": {
      "type": "object",
      "title": "update_access",
      "description": "Muda o papel de um membro dentro de um workspace.",
      "target": "user",
      "effect": "update",
      "requires_confirmation": true,
      "confirmation_reason": "Altera permissões: muda o que uma pessoa pode fazer no sistema.",
      "properties": {
        "user": {
          "description": "Membro (e-mail ou id).",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um user criado antes no mesmo lote."
        },
        "workspace": {
          "description": "Workspace.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um workspace criado antes no mesmo lote."
        },
        "role": {
          "description": "Novo papel.",
          "type": "string",
          "enum": [
            "admin",
            "member",
            "viewer"
          ]
        }
      },
      "required": [
        "user",
        "workspace",
        "role"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "update_access",
          "params": {
            "user": "pessoa@exemplo.com",
            "workspace": "TURAZZA",
            "role": "admin"
          }
        }
      ]
    },
    "assign_user": {
      "type": "object",
      "title": "assign_user",
      "description": "Atribui um membro a um card.",
      "target": "card",
      "effect": "create",
      "requires_confirmation": false,
      "properties": {
        "user": {
          "description": "Membro (e-mail ou id).",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um user criado antes no mesmo lote."
        },
        "card": {
          "description": "Card.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um card criado antes no mesmo lote."
        }
      },
      "required": [
        "user",
        "card"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "assign_user",
          "params": {
            "user": "pessoa@exemplo.com",
            "card": "Roteiro"
          }
        }
      ]
    },
    "add_comment": {
      "type": "object",
      "title": "add_comment",
      "description": "Comenta em um card.",
      "target": "card",
      "effect": "create",
      "requires_confirmation": false,
      "properties": {
        "card": {
          "description": "Card.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um card criado antes no mesmo lote."
        },
        "content": {
          "description": "Texto do comentário.",
          "type": "string"
        }
      },
      "required": [
        "card",
        "content"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "add_comment",
          "params": {
            "card": "Roteiro",
            "content": "Cliente aprovou o gancho na reunião de quarta."
          }
        }
      ]
    },
    "link_client_drive_folder": {
      "type": "object",
      "title": "link_client_drive_folder",
      "description": "Define a pasta oficial do cliente no Google Drive.",
      "target": "workspace",
      "effect": "update",
      "requires_confirmation": false,
      "properties": {
        "workspace": {
          "description": "Cliente alvo.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um workspace criado antes no mesmo lote."
        },
        "folder_url": {
          "description": "Link da pasta no Drive, ou o id dela. Link de arquivo não serve.",
          "type": "string",
          "examples": [
            "https://drive.google.com/drive/folders/145nwW10PWhibuZQLPENFX4oNDeBZN7yo"
          ]
        },
        "folder_name": {
          "description": "Nome da pasta como está no Drive. Só para conferência na tela.",
          "type": "string"
        }
      },
      "required": [
        "workspace",
        "folder_url"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "link_client_drive_folder",
          "params": {
            "workspace": "FILTROS S.A.",
            "folder_url": "https://drive.google.com/drive/folders/145nwW10PWhibuZQLPENFX4oNDeBZN7yo",
            "folder_name": "FILTROS S.A."
          }
        }
      ]
    },
    "unlink_client_drive_folder": {
      "type": "object",
      "title": "unlink_client_drive_folder",
      "description": "Remove o vínculo de pasta do cliente. Não apaga nada no Drive.",
      "target": "workspace",
      "effect": "update",
      "requires_confirmation": false,
      "properties": {
        "workspace": {
          "description": "Cliente alvo.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um workspace criado antes no mesmo lote."
        }
      },
      "required": [
        "workspace"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "unlink_client_drive_folder",
          "params": {
            "workspace": "FILTROS S.A."
          }
        }
      ]
    },
    "link_project_drive_folder": {
      "type": "object",
      "title": "link_project_drive_folder",
      "description": "Define a pasta do projeto no Google Drive.",
      "target": "project",
      "effect": "update",
      "requires_confirmation": false,
      "properties": {
        "project": {
          "description": "Projeto alvo.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um project criado antes no mesmo lote."
        },
        "folder_url": {
          "description": "Link da pasta no Drive, ou o id dela. Pode ser a mesma pasta do cliente.",
          "type": "string"
        },
        "folder_name": {
          "description": "Nome da pasta como está no Drive.",
          "type": "string"
        }
      },
      "required": [
        "project",
        "folder_url"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "link_project_drive_folder",
          "params": {
            "project": "Campanha Agosto",
            "folder_url": "https://drive.google.com/drive/folders/1abcDEF_ghiJKL234"
          }
        }
      ]
    },
    "unlink_project_drive_folder": {
      "type": "object",
      "title": "unlink_project_drive_folder",
      "description": "Remove o vínculo de pasta do projeto. Não apaga nada no Drive.",
      "target": "project",
      "effect": "update",
      "requires_confirmation": false,
      "properties": {
        "project": {
          "description": "Projeto alvo.",
          "type": "string",
          "$comment": "Aceita id (UUID), nome exato, ou \"ref:apelido\" de um project criado antes no mesmo lote."
        }
      },
      "required": [
        "project"
      ],
      "additionalProperties": false,
      "examples": [
        {
          "command": "unlink_project_drive_folder",
          "params": {
            "project": "Campanha Agosto"
          }
        }
      ]
    }
  }
}