Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.withsutro.com/llms.txt

Use this file to discover all available pages before exploring further.

Actions are the functions of a SLang backend. They accept typed parameters, run backend logic, read and modify data, call modules, and return typed values.

Action Shape

An action has a name, typed parameters, a return type, optional metadata, and either a body or an external implementation.
entity User
  subject
  identity email
  fields
    email: EMAIL
    displayName: TEXT?

enum TaskStatus
  values
    todo
    in_progress
    done

entity Task
  fields
    title: TEXT
    status: TaskStatus := "todo"
    dueDate: DATE?
    completedAt: DATE_TIME?

relation User[tasks] 1 --- 0..* Task[owner]

action CreateTask(title: TEXT, dueDate?: DATE): Task
  description "Create a task for the current user."
  body
    user := @subject.entity
    task := create Task {
      owner := user
      title := title
      status := "todo"
      dueDate := dueDate
    }
    return task

action ListMyTasks(): Page<Task>
  description "Return a page of tasks owned by the current user."
  body
    user := @subject.entity
    return pageOf Task where owner == user

action CompleteTask(task: Task, completedAt: DATE_TIME): Task
  body
    update task {
      status := "done"
      completedAt := completedAt
    }
    return task

action DeleteTask(task: Task): VOID
  body
    delete task

action CloseAllOpenTasks(completedAt: DATE_TIME): NUMBER
  body
    doneStatus := "done"
    page := pageOf Task where status != doneStatus
    count := 0
    for task in page.items
      update task {
        status := "done"
        completedAt := completedAt
      }
      count := count + 1
    return count

Reading Data

Use single when the action needs one record. In HTTP contexts, a missing record is surfaced as a not-found response.
entity Todo
  fields
    title: TEXT

action GetTodo(todoId: TEXT): Todo
  body
    todo := single Todo where @id == todoId
    return todo
Use pageOf when the action returns a collection. A page exposes items, total, and offset. Iterate over page.items, not over the page object itself. where filters support a limited comparison shape. The left side must be a model field or @id. The right side must be an in-scope value, such as an action parameter or local variable, or an internal value such as @subject. Literal values are not accepted directly on the right side; assign the literal first and compare against that variable.
action ListTodoTasks(): Page<Task>
  body
    todoStatus := "todo"
    return pageOf Task where status == todoStatus

Writing Data

Use create Entity { ... } to insert a record. Use update record { ... } to patch fields on an existing record. Use delete record to remove one. When you update a variable holding an entity instance, the variable is rebound to the updated instance, so returning the same variable returns the latest fields.

Control Flow

SLang supports:
  • if / else
  • for item in array
  • while
  • break and continue
  • boolean logic with and, or, and not
  • arithmetic and comparisons for compatible primitive values
Use assert(description := "...", rule := condition) when an action should fail unless an invariant is true.