Creating Documents
Documents are structured data containers in Loopstack that enable user input, data validation, and form rendering in the Loopstack Studio. Theyβre essential for capturing and displaying structured information within your workflows.
Creating a Document
A document is created by extending the Document base class and decorating it with @BlockConfig. Documents define the schema for structured data and optionally include UI configuration for form rendering.
Basic Document Definition
TypeScript
import { z } from 'zod';
import { Document } from '@loopstack/core';
import { BlockConfig } from '@loopstack/shared';
import { Expose } from 'class-transformer';
@BlockConfig({
properties: z.object({
title: z.string().min(1, "Title is required"),
description: z.string().optional(),
dueDate: z.string().datetime(),
priority: z.enum(['low', 'medium', 'high']).default('medium'),
assignees: z.array(z.string()).default([]),
}),
configFile: __dirname + '/task.document.yaml',
})
export class TaskDocument extends Document {
@Expose()
title: string;
@Expose()
description?: string;
@Expose()
dueDate: string;
@Expose()
priority: 'low' | 'medium' | 'high';
@Expose()
assignees: string[];
}Key Components
@BlockConfig Decorator
- Defines the document structure and validation rules using Zod schema
- Links the document class to its YAML configuration via
configFile - Specifies validation constraints for each property
@Expose() Decorator
- Makes properties accessible in document and workflow templates
- Enables property access via template variables like
${ document.title }
YAML Config
ui.propertiesDefine how each field is rendered in the Studio frontendwidgetSpecifies the input type (text, textarea, select, date, etc.)- Custom display options like labels, placeholders, and validation messages
Registering the Document
Documents must be imported in your workflow or module to be available for use.
workflow.ts
import { TaskDocument } from './documents/task.document';
import { CreateDocument } from '@loopstack/core';
@BlockConfig({
imports: [
TaskDocument,
CreateDocument,
],
configFile: __dirname + '/task-workflow.yaml',
})
export class TaskWorkflow extends Workflow {}Using Documents in Workflows
Creating Document Instances
Use the CreateDocument tool to instantiate documents in your workflow:
transitions:
- id: initialize_task
from: start
to: task_created
call:
- tool: CreateDocument
args:
document: TaskDocument
validate: strict
update:
content:
title: "Review quarterly reports"
description: "Analyze Q4 performance metrics"
dueDate: "2025-12-31T23:59:59Z"
priority: "high"
assignees: ["alice@example.com", "bob@example.com"]
tags: ["quarterly", "review"]Validation Modes
Documents support three validation modes:
strict(default): Throws an error and halts workflow execution if validation failssafe: Marks the document as invalid but allows workflow to continueskip: Bypasses validation entirely (use sparingly)
transitions:
- id: create_with_safe_validation
from: start
to: processing
call:
- tool: CreateDocument
args:
document: TaskDocument
validate: safe # Won't stop workflow on validation errors
update:
content:
title: "New Task"Capturing User Input
Combine documents with manual transitions to collect user input through forms:
transitions:
- id: display_form
from: start
to: awaiting_input
call:
- tool: CreateDocument
args:
document: TaskDocument
update:
content:
title: ""
- id: process_input
from: awaiting_input
to: task_saved
when: manual
call:
- id: save_task
tool: CreateDocument
args:
document: TaskDocument
validate: strict
update:
content: ${ ctx.payload.transition.payload }
assign:
savedTask: ${ result.data }Available UI Widgets
Documents support various widget types for different data formats:
Available UI Widgets
Documents support various widget types for different data formats:
| Widget | Description | Best For |
|---|---|---|
text | Single-line text input | Short text, names, titles, email, url, numbers |
textarea | Multi-line text input with fixed height | Descriptions, notes, long text |
textarea-expand | Multi-line text input with expandable height | Long-form content that varies in length |
select | Dropdown selection | Single choice from predefined options |
radio | Radio button group | Single choice with visible options |
checkbox | Boolean checkbox | Yes/no, true/false values |
switch | Toggle switch | Enable/disable, on/off states |
slider | Numeric slider | Numeric values within a defined range |
code-view | Code display field | Read-only code snippets or formatted text |