Conceito independente de linguagem que decompõe o fluxo de negócios dentro de funções de serviço em blocos declarativos (sequences).

Problema

O SSOT existente cobre apenas o exterior das funções:

SSOT existenteEscopo cobertoInterior da função?
OpenAPIRotas da API, parâmetros, schema de respostaX
SQL DDLEstrutura de tabelas, índices, constraintsX

O interior da função – o fluxo de negócios “consulta -> validação -> criação -> resposta” – não tem onde ser declarado. Só é possível entendê-lo lendo o código de implementação. O sequence preenche esse espaço vazio.

Hierarquia SSOT

O SSaC é a terceira camada, construída sobre os SSOTs existentes.

OpenAPI       → API 경계 (경로, 파라미터, 응답)
SQL DDL       → 데이터 경계 (테이블, 제약, 인덱스)
SSaC          → 함수 내부 (비즈니스 흐름, sequence 선언)
─────────────────────────────────────────────────
구현 코드      → 코드젠이 생성 (에러 핸들링, 보일러플레이트)

As três camadas acima são responsáveis pelas declarações, e o código de implementação é derivado dessas declarações. Tudo que o ser humano escreve são declarações.

Conceitos Fundamentais

sequence

Unidade de declaração tipada dos blocos de execução dentro de uma função.

Declara-se apenas o what (o que fazer); o codegen preenche o how (como fazer).

10 Tipos Fixos

TipoPapelExemplo
authorizeVerificação de permissãoConsulta de política baseada em action/resource/ID
getConsulta de recursoModel.FindByID(id) -> result
guard nilEncerra se o resultado for nullErro e encerramento se não existir
guard existsEncerra se o resultado existirErro e encerramento se já existir
postCriação de recursoModel.Create(fields…) -> result
putAtualização de recursoModel.Update(id, fields…)
deleteExclusão de recursoModel.Delete(id)
passwordComparação de senhaComparação de hash, encerramento em caso de falha
callChamada externaOperações de recurso não-CRUD, encerramento em caso de falha
responseRetorno de respostajson, view, redirect

Como os tipos são fechados, a geração de código por template matching por tipo é possível. Esta é a base que permite codegen simbólico sem LLM.

Escopo do model

O model não se limita a tabelas do banco de dados. Qualquer recurso que possa ser manipulado via CRUD é um model. Consultas ao banco, verificação de existência de arquivos e chamadas a APIs externas são todos expressos de forma uniforme com get/post/put/delete.

Exemplo de Sintaxe (Go PoC)

É um conceito independente de linguagem, mas a implementação de referência usa a sintaxe de comentários Go. Como a IA já conhece o Go AST, não há custo adicional de aprendizado.

Simples (Criação)

// @sequence get
// @model Project.FindByID
// @param ProjectID request
// @result project Project

// @sequence guard nil project
// @message "프로젝트가 존재하지 않습니다"

// @sequence post
// @model Session.Create
// @param ProjectID request
// @param Command   request
// @result session Session

// @sequence response json
// @var session
func CreateSession(w http.ResponseWriter, r *http.Request) {}

Complexo (Exclusão + Permissão + Validação + Chamada externa)

// @sequence authorize
// @action delete
// @resource project
// @id ProjectID

// @sequence get
// @model Project.FindByID
// @param ProjectID request
// @result project Project

// @sequence guard nil project
// @message "프로젝트가 존재하지 않습니다"

// @sequence get
// @model Session.CountByProjectID
// @param ProjectID request
// @result sessionCount int

// @sequence guard exists sessionCount
// @message "하위 세션이 존재하여 삭제할 수 없습니다"

// @sequence call
// @component notification
// @param project.OwnerEmail
// @param "프로젝트가 삭제됩니다"

// @sequence call
// @func cleanupProjectResources
// @param project
// @result cleaned bool

// @sequence delete
// @model Project.Delete
// @param ProjectID request

// @sequence response json
func DeleteProject(w http.ResponseWriter, r *http.Request) {}

Resultado do Codegen

Implementação derivada da declaração de sequence acima:

func CreateSession(w http.ResponseWriter, r *http.Request) {
    // get
    project, err := projectModel.FindByID(projectID)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    // guard nil
    if project == nil {
        http.Error(w, "프로젝트가 존재하지 않습니다", http.StatusNotFound)
        return
    }

    // post
    session, err := sessionModel.Create(projectID, command)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    // response json
    json.NewEncoder(w).Encode(map[string]interface{}{
        "session": session,
    })
}

Comparação de Custo de Tokens

Declaração de sequenceCódigo de implementação
Linhas10~15 linhas30~100 linhas
Conteúdo expressowhat (o que fazer)how (como fazer)
Error handlingNenhum (gerado pelo codegen)Totalmente incluído
Dependência de bibliotecasNenhumaimport, inicialização, chamadas
Momento da alteraçãoQuando o fluxo de negócios mudaRefletido automaticamente ao reexecutar o codegen

O que o humano mantém é apenas a declaração de sequence. Quando a declaração muda, basta reexecutar o codegen para sobrescrever o código de implementação.

Princípios de Design

early return – contrato comum de todos os tipos

A premissa que sustenta a listagem linear de sequences. Exceto response, todos os sequences encerram imediatamente em caso de falha. call não é exceção. Basta ler de cima para baixo, sem ramificações.

TipoCondição de falha
authorizeSem permissão -> return
getErro de consulta -> return
guard nilnull -> return
guard existsExiste -> return
post/put/deleteErro de DB -> return
passwordNão corresponde -> return
callFalha -> return
responseÚltimo (retorno)

Como call segue o mesmo contrato que guard, não é necessário adicionar um guard separado após call. O codegen gera automaticamente verificação de erro + early return para todos os calls.

@transaction

Metadado em nível de função. Não é um tipo de sequence (dos 10), mas declara se a função inteira deve ser envolvida em uma transação.

// @transaction
// @sequence get
// @model Account.FindByID
// @param AccountID request
// @result account Account
// ...

Combinado com a estrutura de early return, os limites da transação se tornam naturais:

@transaction declarado
  -> falha no guard -> rollback + return
  -> último sequence bem-sucedido -> commit
  -> erro ocorrido -> rollback + return

Como não há ramificações, o limite da transação também é singular: “a função inteira”. Não é necessário especificar posições de begin/end, e o codegen decide o wrapping apenas pela presença ou ausência de @transaction. Se duas transações forem necessárias, isso significa que há duas responsabilidades. Separe a função.

call – forma especial do model

call possui a mesma essência que model. Se model é a manipulação de recursos expressa via CRUD (get/post/put/delete), call é a manipulação de recursos que não pode ser expressa via CRUD. Ambos invocam operações com dependências externas e retornam em caso de falha.

Manipulação de recursos
  +-- model (CRUD)     -> get/post/put/delete
  +-- call (não-CRUD)  -> component ou func
  • @component – por registro. Quando um padrão repetitivo aparece 3 ou mais vezes, ele é promovido.
  • @func – lógica única. Implementada diretamente por pessoas ou IA.

Lógicas complexas como ramificação com convergência e processamento condicional dentro de loops não estendem o sequence, mas são delegadas ao call. Delega-se, mas o contrato permanece o mesmo – encerramento em caso de falha.

@message

Metadado opcional que pode ser anexado a qualquer tipo de sequence. Especifica a mensagem a ser transmitida ao usuário em caso de falha.

// @sequence guard nil project
// @message "프로젝트가 존재하지 않습니다"

// @sequence post
// @model Session.Create
// @param ProjectID request
// @param Command   request
// @result session Session
// @message "세션 생성에 실패했습니다"

Se @message for omitido, o codegen gera automaticamente uma mensagem padrão a partir do tipo + nome do model. Declare apenas quando uma mensagem personalizada for necessária.

Funções puras não pertencem à camada de serviço

Todos os blocos declarados em um sequence são operações com dependências externas. Funcionalidades puras como conversão de formato e cálculo de valores são tratadas internamente no model ou dentro das funções chamadas, não na camada de serviço. A função de serviço faz apenas orquestração (orchestration), e o cálculo puro pertence ao alvo da chamada.

Referência de Tipos

O SSaC não define seus próprios tipos. Ele referencia tipos derivados de SSOTs existentes.

OrigemExemplo
DB schema (SQL DDL)Project, Session
Especificação de API (OpenAPI)CreateSessionRequest
Definição de interfaceFileSystem, Cache

Convenções de Nomenclatura

CategoriaRegraExemplo
TipoPascalCase, importado do SSOTProject, Session
VariávelcamelCase, declarada via @resultproject, sessionCount
Campo de requestPascalCase, extraído da requisiçãoProjectID, Command
Variável reservadacamelCase, fornecida pelo frameworkcurrentUser, config

A diferença de maiúsculas/minúsculas entre tipos e variáveis permite distingui-los apenas pela declaração. project é uma variável, Project é um tipo.

Extensão de Linguagem

O SSaC é um conceito independente de linguagem. Go é a implementação de referência (PoC), e a partir da mesma declaração de sequence é possível gerar código em outras linguagens.

sequence 선언 (공통)
  |
  +-- Go 코드젠
  +-- Python 코드젠
  +-- TypeScript 코드젠
  +-- ...

A especificação (definição de tipos, sintaxe, regras de validação) e o codegen são separados.

A implementação de referência em Go está disponível no GitHub.