Service Sequences as Code — generiert Servicecode aus Go-Kommentar-DSL.

Servicelogik ist eine Reihe von Entscheidungen: Welches Modell abfragen, wogegen schützen, wann ablehnen, was zurückgeben. Diese Entscheidungen gehören dem, der das Geschäft versteht — aber sie werden in Boilerplate begraben, über Schichten verstreut und bei Rewrites verloren.

SSaC bewahrt diese Entscheidungen als deklarative Spezifikation. Sie deklarieren was passiert und in welcher Reihenfolge. Das Tool generiert die Implementierung.

specs/service/*.go  →  ssac validate  →  ssac gen  →  artifacts/service/*.go

GitHub

Kernidee

Jede Servicefunktion ist eine Sequenz von Schritten. Jeder Schritt folgt einem Binärvertrag: Erfolg → nächste Zeile, Fehler → return. Das ist keine Abstraktion, die wir erfunden haben — so funktioniert Servicelogik bereits. SSaC macht es explizit.

10 feste Sequenztypen decken alle Serviceschicht-Operationen ab, die diesem Vertrag folgen. Was nicht passt, wird an call delegiert. Die Menge ist designbedingt geschlossen.

Kein LLM, keine Inferenz — reine symbolische Codegenerierung aus Templates. Die Spezifikation ist die Quelle der Wahrheit.

Beispiel

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

// @sequence guard nil project
// @message "project not found"

// @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) {}

Diese 10-Zeilen-Deklaration generiert folgenden Code:

func CreateSession(w http.ResponseWriter, r *http.Request) {
    projectID := r.FormValue("ProjectID")
    command := r.FormValue("Command")

    project, err := projectModel.FindByID(projectID)
    if err != nil {
        http.Error(w, "Project lookup failed", http.StatusInternalServerError)
        return
    }

    if project == nil {
        http.Error(w, "project not found", http.StatusNotFound)
        return
    }

    session, err := sessionModel.Create(projectID, command)
    if err != nil {
        http.Error(w, "Session creation failed", http.StatusInternalServerError)
        return
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(map[string]interface{}{
        "session": session,
    })
}

Sequenztypen (10)

TypRolle
authorizeBerechtigungsprüfung (OPA, etc.)
getRessourcensuche
guard nilBeenden wenn null
guard existsBeenden wenn vorhanden
postRessourcenerstellung
putRessourcenaktualisierung
deleteRessourcenlöschung
passwordPasswortvergleich
callExterner Aufruf (@component / @func)
responseAntwort zurückgeben (json)

Codegen-Funktionen

/api/reservations:
  get:
    operationId: ListReservations
    x-pagination:
      style: offset
      defaultLimit: 20
      maxLimit: 100
    x-sort:
      allowed: [start_at, created_at]
      default: start_at
      direction: desc
    x-filter:
      allowed: [status, room_id]
    x-include:
      allowed: [room, user]

Lizenz

MIT — GitHub