Skip to content
Alvo is pre-v0.1: the image runs from its edge tag, and no NuGet package or release is published yet.Pre-v0.1: no release yet.Roadmap and status

Examples

Every example descriptor in the repository: what it shows, whether it applies, and how to run it.

Each example lives under examples/ in the repository and is validated against the descriptor schema on every build. The ones that apply also ship inside the image, under /alvo/examples/, so the Quick start’s compose file serves any of them with ALVO_DESCRIPTOR and no clone. Each summary comes from examples/README.md, which also lists the keys the schema declares but this build refuses at apply.

The admin dashboard’s demo backend (see bike-workshop/README.md): a bicycle repair and rental workshop over eight entities, exercising every field type, declared formats, literal defaults, all three onDeletes, computed fields (one reading a rollup), count/sum rollups, hidden/readOnly as CEL, before-hooks (reject and mutate), email and webhook after-hooks, access levels and role-differentiated rules. scripts/demo-admin starts the host over it and seeds realistic data from bike-workshop/seed/ through the public API.

Applies: yes

Entities: technicians, customers, bikes, parts, service_orders, order_lines, rental_fleet, rentals

Roles a key needs: manager, reception, technician

Tenancy: single-tenant

Descriptor: examples/bike-workshop/bike-workshop.alvo.json

In the image at /alvo/examples/bike-workshop/bike-workshop.alvo.json. Serve it with the quick start’s compose file, from the directory that holds it; the down deletes the database of the descriptor it served before:

Terminal window
docker compose -f docker-compose.quickstart.yml down --volumes
ALVO_DESCRIPTOR=/alvo/examples/bike-workshop/bike-workshop.alvo.json docker compose -f docker-compose.quickstart.yml up --wait

The quick start’s demo key holds only the built-in roles admin and authenticated, so it authenticates here; for keys with this example’s own roles, use an override as Run your own descriptor shows.

The runnable complex demo (see field-service/README.md) and the fixture the test/teapie-field-service end-to-end suite drives: a multi-tenant field-service dispatch backend over three entities — regions (tenancy: global, shared reference data) and the tenant-scoped customers and work_orders. It exercises tenancy, audit on one entity and its absence on another (so If-Match is honoured on one and refused with 412 on the other), hidden and readOnly fields, role-differentiated and row-level rules, an operation with no rule at all, ref with onDelete: restrict, one field of each type, and built-in and declared formats. Its own stack is docker-compose.field-service.yml, with one dev key per role and tenant.

Applies: yes

Entities: regions, customers, work_orders

Roles a key needs: dispatcher, technician

Tenancy: multi-tenant (tenancy.enabled: true)

Descriptor: examples/field-service/field-service.alvo.json

In the image at /alvo/examples/field-service/field-service.alvo.json. Serve it with the quick start’s compose file, from the directory that holds it; the down deletes the database of the descriptor it served before:

Terminal window
docker compose -f docker-compose.quickstart.yml down --volumes
ALVO_DESCRIPTOR=/alvo/examples/field-service/field-service.alvo.json docker compose -f docker-compose.quickstart.yml up --wait

The quick start’s demo key belongs to no tenant, so there only the entities marked tenancy: global answer; the header of docker-compose.quickstart.yml says how to give the key a tenant. The example’s own stack, docker-compose.field-service.yml, has one dev key per role and tenant and runs from a clone of the repository. Generate a secret for each key and start it, as its README describes:

Terminal window
export ALVO_FS_DISPATCHER_NORTH_SECRET="$(openssl rand -hex 16)"
export ALVO_FS_TECH_NORTH_SECRET="$(openssl rand -hex 16)"
export ALVO_FS_SPARE_NORTH_SECRET="$(openssl rand -hex 16)"
export ALVO_FS_DISPATCHER_SOUTH_SECRET="$(openssl rand -hex 16)"
export ALVO_FS_ADMIN_SECRET="$(openssl rand -hex 16)"
docker compose --env-file examples/field-service/demo-identities.env -f docker-compose.field-service.yml up --build --wait

A support desk’s tickets: an enum priority and status with literal defaults, a decimal estimate and a computed field over it, audit, role-differentiated rules, and two before-hooks (a mutate that trims the title with trim, a reject for a high-priority ticket without a body). It declares the roles admin and agent. It is the end state of the docs site’s tutorial (Tutorial: your first backend) and the source of the README’s “See it” section.

Applies: yes

Entities: tickets

Roles a key needs: admin, agent

Tenancy: single-tenant

Descriptor: examples/help-desk/help-desk.alvo.json

In the image at /alvo/examples/help-desk/help-desk.alvo.json. Serve it with the quick start’s compose file, from the directory that holds it; the down deletes the database of the descriptor it served before:

Terminal window
docker compose -f docker-compose.quickstart.yml down --volumes
ALVO_DESCRIPTOR=/alvo/examples/help-desk/help-desk.alvo.json docker compose -f docker-compose.quickstart.yml up --wait

The quick start’s demo key holds only the built-in roles admin and authenticated, so it authenticates here; for keys with this example’s own roles, use an override as Run your own descriptor shows.

The smallest real backend, and the one to start from: two owned entities (projects, tasks), ownership rules, an enum, audit, one composite index. It deliberately leaves out rollups, defaults and hooks, because the smallest starting point is the point; the other examples show those.

Applies: yes

Entities: projects, tasks

Roles a key needs: none declared; authenticated is enough

Tenancy: single-tenant

Descriptor: examples/simple-tasks/tasks.alvo.json

In the image at /alvo/examples/simple-tasks/tasks.alvo.json. Serve it with the quick start’s compose file, from the directory that holds it; the down deletes the database of the descriptor it served before:

Terminal window
docker compose -f docker-compose.quickstart.yml down --volumes
ALVO_DESCRIPTOR=/alvo/examples/simple-tasks/tasks.alvo.json docker compose -f docker-compose.quickstart.yml up --wait

The quick start’s demo key holds only the built-in roles admin and authenticated, so it authenticates here; for keys with this example’s own roles, use an override as Run your own descriptor shows.

The demo the root docker-compose.yml serves: owners, their vehicles, and periodic roadworthiness inspections. Exercises two ref chains (vehicles.owner_id → owners, inspections.vehicle_id → vehicles, the latter onDelete: cascade), a composite index on each of vehicles and inspections, audit on both owners and vehicles, and a renamedFrom on vehicles.plate (was license_plate).

Applies: yes

Entities: owners, vehicles, inspections

Roles a key needs: inspector, admin

Tenancy: single-tenant

Descriptor: examples/vehicle-registry/vehicles.alvo.json

In the image at /alvo/examples/vehicle-registry/vehicles.alvo.json. Serve it with the quick start’s compose file, from the directory that holds it; the down deletes the database of the descriptor it served before:

Terminal window
docker compose -f docker-compose.quickstart.yml down --volumes
ALVO_DESCRIPTOR=/alvo/examples/vehicle-registry/vehicles.alvo.json docker compose -f docker-compose.quickstart.yml up --wait

The quick start’s demo key holds only the built-in roles admin and authenticated, so it authenticates here; for keys with this example’s own roles, use an override as Run your own descriptor shows.

A format showcase, not a runnable backend (see complex-crm/NOT-RUNNABLE.md): a CRM written in the v1 format, exercising most of the surface including keys this build refuses, which is exactly why applying it fails. It is the schema corpus’s one full-surface fixture, covering multi-tenancy (tenancy.enabled + a global lookup table), dynamic-entities governance (dynamicEntities.defaultRules + quotas), rollup.via, a computed field reading a rollup (gross_total), a declarative formats entry (sk-ico) referenced by a field, field-level per-role masking (hidden as CEL), tagged {"$cel": …} values, renamedFrom, templates, outbound webhooks, a batch-delivery automation rule, a scheduled rule delegating to a function, and x- keys. It is a real bundle: crm.alvo.json alongside templates/invoice-issued.html (referenced via bodyFile) and functions/remind-stale-deals.csx (referenced via script).

Applies: no — why

Entities: countries, companies, contacts, deals, invoices, invoice_items

Roles a key needs: sales, manager, finance

Tenancy: multi-tenant (tenancy.enabled: true)

Descriptor: examples/complex-crm/crm.alvo.json