Skip to main content

Query Library Schema Reference

This document provides the complete, canonical reference for Stack9 Query Library schemas based on the official Joi validators. This is the single source of truth for all Query Library property definitions.

Base Query Library Structure

Every query library definition must have these base properties:

{
"key": "unique_query_key", // Required for save operation
"name": "Query Name", // Required: Human-readable name
"connector": "connector_type", // Required: Must match ConnectorType enum
"userParams": {}, // Optional: Parameters for the query
"module": "module_name", // Optional: Module association
"queryTemplate": {} // Required: Connector-specific schema (see below)
}

Key Validation Rules

  • Must be lowercase
  • Must be a valid token (alphanumeric and underscores only)
  • CANNOT start with 'stack9_' (reserved prefix)
  • Required for save operations, optional for run operations

Connector Types

The following connector types are supported (must match exactly):

Connector TypeValueDescription
AMAZON_DYNAMODBamazon_dynamodbAWS DynamoDB NoSQL database
AMAZON_KMSamazon_kmsAWS Key Management Service
AMAZON_S3amazon_s3AWS S3 object storage
AMAZON_OPENSEARCHamazon_opensearchAWS OpenSearch (Elasticsearch)
AZURE_BLOBazure_blobAzure Blob Storage
ELASTIC_SEARCHelastic_searchElasticsearch search engine
FIREBASEfirebaseFirebase services (Firestore, Auth)
GRAPHQLgraphqlGraphQL API endpoints
MONGO_DBmongodbMongoDB NoSQL database
MSSQLmssqlMicrosoft SQL Server
OPEN_APIopen_apiOpenAPI/Swagger APIs
POSTGRESQLpostgresqlPostgreSQL database
REDISredisRedis cache/database
REST_APIrest_apiREST/HTTP APIs
SENDGRIDsendgridSendGrid email service
STACK9_APIstack9_apiStack9 internal API (with filters)
STACK9_DBstack9_dbStack9 database (with filters)
STACK9_MONGOstack9_mongoStack9 MongoDB
STACK9_REDISstack9_redisStack9 Redis
STACK9_S3stack9_s3Stack9 S3 (with public flag)
STACK9_AZUREstack9_azureStack9 Azure (with public flag)

Connector-Specific Query Templates

Each connector type has its own specific queryTemplate schema:

AMAZON_DYNAMODB

{
"queryTemplate": {
"actionType": "create_table | get | put", // Required
"tableName": "table_name", // Required, lowercase
"bodyParams": {} // Optional, any type
}
}

AMAZON_KMS

{
"queryTemplate": {
"actionType": "sign | get_public_key", // Required
"bodyParams": {} // Optional, any type
}
}

AMAZON_S3

{
"queryTemplate": {
"actionType": "list_all | read_file | download_file | upload_file | generate_signed_url", // Required
// Conditional properties based on actionType:

// For LIST_ALL_FILES:
"bucketName": "bucket-name", // Optional
"prefix": "folder/", // Optional
"delimiter": "/", // Optional
"maxKeys": "1000", // Optional

// For READ_FILE, DOWNLOAD_FILE, GENERATE_SIGNED_URL:
"bucketName": "bucket-name", // Optional
"fileKey": "path/to/file.ext", // Optional

// For UPLOAD_FILE:
"bucketName": "bucket-name", // Optional
"bodyParams": {} // Optional
}
}

AMAZON_OPENSEARCH

{
"queryTemplate": {
"actionType": "index | search | update | update_by_query | delete | delete_by_query | bulk | indice_create | indice_delete | msearch", // Required
"indexName": "index_name", // Required, lowercase
"schemaKey": "schema_key", // Optional, lowercase
"bodyParams": {} // Optional, any type
},
"querySearchFields": ["field1", "field2"], // Optional, lowercase
"filters": [], // Optional, see Filter Schema
"filterSections": [] // Optional, see Filter Section Schema
}

AZURE_BLOB

{
"queryTemplate": {
"actionType": "list_all | read_file | download_file | generate_signed_url", // Required

// For LIST_ALL_FILES:
"prefix": "folder/", // Required when actionType is list_all

// For READ_FILE, DOWNLOAD_FILE, GENERATE_SIGNED_URL:
"filename": "file.ext" // Required for file operations
}
}
{
"queryTemplate": {
"actionType": "index | search | update | update_by_query | delete | delete_by_query | bulk | indice_create | indice_delete | msearch", // Required
"indexName": "index_name", // Required, lowercase
"bodyParams": {} // Optional, any type
},
"querySearchFields": ["field1", "field2"], // Optional, lowercase
"filters": [], // Optional, see Filter Schema
"filterSections": [] // Optional, see Filter Section Schema
}

FIREBASE

{
"queryTemplate": {
"actionType": "query_firestore | get_documents | get_document_by_id | get_collections | get_user_by_email | get_user_by_uid | create_user | delete_user", // Required

// For QUERY_FIRESTORE:
"firestoreCollection": "collection_name", // Optional
"firestoreOrderBy": "field_name", // Optional
"firestoreOrderDirection": "asc | desc", // Optional
"firestoreWhere": [ // Optional
{
"key": "field_name", // Required
"value": "any_value", // Required
"operation": "< | <= | == | != | >= | > | array-contains | in | not-in | array-contains-any" // Required
}
],
"limit": 100, // Optional, number
"startAt": "cursor_value", // Optional
"endAt": "cursor_value", // Optional

// For GET_DOCUMENT_BY_ID:
"firestoreCollection": "collection_name", // Optional
"docId": "document_id", // Optional

// For GET_DOCUMENTS:
"firestoreCollection": "collection_name", // Optional

// For GET_COLLECTIONS:
"docId": "document_id", // Optional

// For GET_USER_BY_EMAIL:
"email": "user@example.com", // Optional, must be valid email

// For GET_USER_BY_UID, DELETE_USER:
"uid": "user_uid", // Optional

// For CREATE_USER:
"userOptions": {} // Optional, object
}
}

GRAPHQL

{
"queryTemplate": {
"query": "query { ... }", // Required: GraphQL query string
"variables": "variable_string", // Optional: Variables as string
"headerParams": {}, // Optional: HTTP headers
"cookiesParams": {} // Optional: Cookies
}
}

MONGO_DB

{
"queryTemplate": {
"method": "find | find_one | count | list_collections | insert_one", // Required
"collection": "collection_name", // Optional

// For FIND:
"query": "{ field: value }", // Optional
"projection": "{ field: 1 }", // Optional
"sortBy": "{ field: -1 }", // Optional
"skip": "0", // Optional
"limit": "10", // Optional

// For FIND_ONE:
"query": "{ field: value }", // Optional
"projection": "{ field: 1 }", // Optional
"skip": "0", // Optional

// For COUNT, LIST_COLLECTIONS, INSERT_ONE:
"query": "{ field: value }" // Optional
}
}

MSSQL

{
"queryTemplate": {
"query": "SELECT * FROM table WHERE ..." // Required: SQL query string
}
}

OPEN_API

{
"queryTemplate": {
"method": "get | post | put | delete | patch", // Required
"path": "/api/endpoint", // Required: API path
"bodyParams": {}, // Optional: Request body
"queryParams": {}, // Optional: Query parameters
"pathParams": {} // Optional: Path parameters
}
}

POSTGRESQL

{
"queryTemplate": {
"query": "SELECT * FROM table WHERE ..." // Required: SQL query string
}
}

REDIS

{
"queryTemplate": {
"type": "raw | gui", // Required

// For type = "raw":
"rawCommand": "GET key", // Optional: Raw Redis command

// For type = "gui":
"command": "get | set | del", // Optional: Command type
"key": "redis_key", // Optional (required for GET)

// For SET command:
"value": "redis_value", // Optional
"ttl": "3600" // Optional: TTL in seconds
}
}

REST_API

{
"queryTemplate": {
"method": "get | post | put | delete | patch", // Required, lowercase
"path": "/api/endpoint", // Optional: API path
"bodyType": "json | raw | form-data", // Required for POST/PUT, lowercase
"bodyParams": "string or array", // Optional: String for RAW/JSON, Array for FORM_DATA
// For FORM_DATA bodyParams:
// [
// {
// "key": "field_name", // Required
// "value": "field_value", // Required
// "operation": "text | file" // Required for form-data
// }
// ]
"cookiesParams": {}, // Optional: Cookies
"headerParams": {} // Optional: Headers
}
}

SENDGRID

{
"queryTemplate": {
"actionType": "send_email", // Required
"queryParams": {}, // Optional
"bodyParams": { // Optional, but must have one of: text, html, templateId, or content
"from": "sender@example.com or {email, name}", // Required
"replyTo": "reply@example.com or {email, name}", // Optional
"sendAt": 1234567890, // Optional: Unix timestamp
"to": "recipient@example.com or [{email, name}]", // Optional
"cc": "cc@example.com or [{email, name}]", // Optional
"bcc": "bcc@example.com or [{email, name}]", // Optional
"subject": "Email Subject", // Optional
"text": "Plain text content", // One of these required
"html": "<p>HTML content</p>", // One of these required
"templateId": "template_id", // One of these required
"content": [ // One of these required
{
"type": "text/plain", // Required
"value": "content" // Required
}
],
"dynamicTemplateData": {}, // Optional: Template variables
"attachments": [ // Optional
{
"content": "base64_content", // Required
"filename": "file.pdf", // Required
"type": "application/pdf", // Optional
"disposition": "attachment", // Optional
"contentId": "content_id" // Optional
}
]
}
}
}

STACK9_API

Same as OPEN_API plus:

{
"queryTemplate": {
"method": "get | post | put | delete | patch", // Required
"path": "/api/endpoint", // Required
"bodyParams": {}, // Optional
"queryParams": {}, // Optional
"pathParams": {} // Optional
},
"querySearchFields": ["field1", "field2"], // Optional, lowercase
"filters": [], // Optional, see Filter Schema
"filterSections": [] // Optional, see Filter Section Schema
}

STACK9_DB

{
"queryTemplate": {
"query": "SELECT * FROM table WHERE ..." // Optional: SQL query
},
"querySearchFields": ["field1", "field2"], // Optional, lowercase
"filters": [], // Optional, see Filter Schema
"filterSections": [] // Optional, see Filter Section Schema
}

STACK9_MONGO

Same as MONGO_DB (no additional properties).

STACK9_REDIS

Same as REDIS (no additional properties).

STACK9_S3

Same as AMAZON_S3 plus:

{
"queryTemplate": {
// ... all AMAZON_S3 properties ...
"isPublic": false // Optional: Make files publicly accessible
}
}

STACK9_AZURE

Same as AZURE_BLOB plus:

{
"queryTemplate": {
// ... all AZURE_BLOB properties ...
"isPublic": false // Optional: Make files publicly accessible
}
}

Filter Schema

Filters are available for: stack9_api, stack9_db and opensearch connector types.

Filters provide powerful data refinement capabilities in Stack9 applications. They are rendered automatically by the GridBuilder component in list views and simpleCrud screens.

For comprehensive filter examples and patterns, see Query Filters and Search.

{
"filters": [
{
"key": "filter_key", // Required: Unique identifier
"name": "Filter Name", // Required: Display name
"sequence": 1, // Required: Display order
"filterSectionKey": "section_key", // Optional: Must match a filterSection key
"typeFilter": "FilterType", // Required: See Filter Types below
"typeQueryFilter": "compare | between | array", // Required
"useSubquery": false, // Required: boolean
"field": "entity_field", // Required for most filter types
"dataSource": { // Required for selection filters
"type": "queryDistinct | query | static", // Required

// For type = "query":
"query": {}, // Required: Query object
"labelProp": "display_field", // Required
"valueProp": "value_field", // Required

// For type = "queryDistinct":
"query": {}, // Required: Query object

// For type = "static":
"options": [ // Required
{
"label": "Option Label", // Required
"value": "option_value" // Required
}
]
}
}
]
}

Filter Types (S9FilterTypes)

TypeDescriptionUI ComponentRequires fieldRequires dataSourcetypeQueryFilter
SingleDropDownSingle selection dropdownDropdown menuYesYescompare
MultiDropDownMultiple selection dropdownMulti-select dropdownYesYesarray
CheckboxesCheckbox groupCheckbox listYesYesarray
RadioButtonsRadio button groupRadio buttonsYesYescompare
BooleanValueTrue/False filterYes/No/Any selectorYesNocompare
DateRangeValueDate range pickerDate range inputsYesNobetween
NumericRangeValueNumber range inputMin/max number inputsYesNobetween
StringCompareValueString comparisonText input with operatorsYesNocompare
NumericCompareValueNumber comparisonNumber input with operatorsYesNocompare
DateCompareValueDate comparisonDate picker with operatorsYesNocompare
CustomComponentFilterCustom filter componentCustom React componentYesNoVaries

Common Use Cases by Filter Type

  • SingleDropDown: Status, type, single category selection
  • MultiDropDown: Tags, multiple categories, features
  • Checkboxes: Payment methods, preferences, options
  • BooleanValue: Active/inactive, featured, in stock
  • DateRangeValue: Creation dates, transaction periods, date filtering
  • NumericRangeValue: Price ranges, quantities, scores
  • StringCompareValue: Names, IDs, codes, text fields
  • NumericCompareValue: Exact IDs, specific quantities

Filter Data Source Types

TypeDescription
queryDistinctGet distinct values from query
queryGet options from query with label/value mapping
staticHardcoded list of options

Filter Section Schema

{
"filterSections": [
{
"key": "section_key", // Required: Unique identifier
"name": "Section Name", // Required: Display name
"sequence": 1, // Required: Display order
"collapsed": false // Optional: Start collapsed
}
]
}

HTTP Operations

Available for REST_API, OPEN_API, and STACK9_API:

OperationValue
GETget
POSTpost
PUTput
DELETEdelete
PATCHpatch

Body Types

Available for REST_API:

TypeValueDescription
JSONjsonJSON payload
RAWrawRaw text payload
FORM_DATAform-dataMultipart form data

Complete Examples

Example 1: Stack9 API Query with Filters

{
"key": "getcustomerlist",
"name": "getCustomerList",
"connector": "stack9_api",
"queryTemplate": {
"method": "post",
"path": "/customer/search",
"bodyParams": {
"$where": { "is_active": true }
}
},
"querySearchFields": ["name", "email"],
"filterSections": [
{
"key": "basic_filters",
"name": "Basic Filters",
"sequence": 1
}
],
"filters": [
{
"key": "status_filter",
"name": "Status",
"sequence": 1,
"filterSectionKey": "basic_filters",
"typeFilter": "SingleDropDown",
"typeQueryFilter": "compare",
"useSubquery": false,
"field": "status",
"dataSource": {
"type": "static",
"options": [
{ "label": "Active", "value": "active" },
{ "label": "Inactive", "value": "inactive" }
]
}
}
],
"userParams": {
"customerId": ""
}
}

Example 2: MongoDB Query

{
"key": "findproducts",
"name": "findProducts",
"connector": "mongodb",
"queryTemplate": {
"method": "find",
"collection": "products",
"query": "{ category: '{{category}}' }",
"projection": "{ name: 1, price: 1 }",
"sortBy": "{ price: -1 }",
"limit": "20"
},
"userParams": {
"category": "electronics"
}
}

Example 3: SendGrid Email

{
"key": "sendwelcomeemail",
"name": "sendWelcomeEmail",
"connector": "sendgrid",
"queryTemplate": {
"actionType": "send_email",
"bodyParams": {
"from": {
"email": "noreply@company.com",
"name": "Company Name"
},
"to": "{{userEmail}}",
"subject": "Welcome to Our Platform",
"templateId": "d-abc123def456",
"dynamicTemplateData": {
"firstName": "{{firstName}}",
"activationLink": "{{activationLink}}"
}
}
},
"userParams": {
"userEmail": "",
"firstName": "",
"activationLink": ""
}
}

Example 4: S3 File Upload

{
"key": "uploadfile",
"name": "uploadFile",
"connector": "stack9_s3",
"queryTemplate": {
"actionType": "upload_file",
"bucketName": "my-bucket",
"bodyParams": {
"key": "uploads/{{fileName}}",
"body": "{{fileContent}}",
"contentType": "{{contentType}}"
},
"isPublic": true
},
"userParams": {
"fileName": "",
"fileContent": "",
"contentType": "application/pdf"
}
}

Important Notes

  1. Connector type values must match exactly - Use lowercase with underscores (e.g., amazon_s3, not AMAZON_S3 or AmazonS3)
  2. Query keys cannot start with 'stack9_' - This prefix is reserved for system queries
  3. Conditional properties - Many properties are only valid for specific action types or methods
  4. Case sensitivity - Most string properties that will become database fields must be lowercase
  5. Required vs Optional - Properties marked as "Required" in the validator will cause validation errors if missing
  6. Type safety - The validator enforces strict typing for all properties

Validation Operations

The validator supports two operations that affect validation rules:

  • SAVE: Requires the key property
  • RUN: The key property is optional

This reference is generated from the official QueryLibrarySchemaValidator.ts and represents the authoritative schema definitions for Stack9 Query Library.