Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.veloiq.dev/llms.txt

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

A VeloIQ module is a Python package that lives under backend/app/modules/. Each module owns one domain concept — its models, generated API, custom endpoints, and admin views. On startup, the framework scans app/modules/*/ and registers every module it finds automatically. You never add import statements to main.py.

Module directory layout

modules/orders/
├── __init__.py
├── models.py           # SQLModel table classes — you write this
├── api.py              # AUTO-GENERATED CRUD — do not edit
├── custom_api.py       # custom endpoints — you write this
└── admin/
    └── admin_views.py  # SQLAdmin view — you write this

Creating a module

Use the CLI to scaffold a new module:
veloiq add-module orders
Add optional flags to include extra files in the scaffold:
FlagEffect
--with-custom-apiCreates custom_api.py with a starter router
--with-adminCreates admin/admin_views.py with a starter ModelView
veloiq add-module orders --with-custom-api --with-admin

models.py

Define your entities by inheriting from one of the framework base classes (FrameworkModel, TimestampedModel, or StandardModel). See Models for the full reference on base classes, field types, and relationships.

api.py — generated CRUD endpoints

After running veloiq generate, each module has an api.py that creates a complete CRUD router for your model:
# AUTO-GENERATED — do not edit. Run `veloiq generate` to update.
from veloiq_framework.crud import create_crud_router
from .models import Order

router = create_crud_router(Order)
create_crud_router generates these endpoints automatically:
MethodPathAction
GET/orderPaginated list (?_start=0&_end=25)
GET/order/{id}Single record
POST/orderCreate
PUT/order/{id}Full update
DELETE/order/{id}Delete
List responses include x-total-count and content-range headers to support the Refine data provider pagination convention.
Do not edit api.py. It is overwritten every time you run veloiq generate. Put all custom logic in custom_api.py instead.

custom_api.py — custom endpoints

For business-specific endpoints, create custom_api.py in the module directory and import router from the generated api.py. Add routes to that router and the framework loader picks them up automatically.
from fastapi import Depends, HTTPException
from sqlmodel import Session, select

from veloiq_framework import get_session
from .api import router
from .models import Order


@router.post("/{order_id}/confirm")
def confirm_order(order_id: int, session: Session = Depends(get_session)):
    order = session.get(Order, order_id)
    if order is None:
        raise HTTPException(404, f"Order {order_id} not found")
    order.status = "confirmed"
    session.add(order)
    session.commit()
    session.refresh(order)
    return order.model_dump()


@router.get("/pending")
def list_pending(session: Session = Depends(get_session)):
    rows = session.exec(select(Order).where(Order.status == "pending")).all()
    return [r.model_dump() for r in rows]
The framework imports both api.py and custom_api.py on startup — you don’t need to register the router anywhere else.

admin/admin_views.py — back-office views

Add an SQLAdmin ModelView to expose your model in the admin panel at /admin/.
from sqladmin import ModelView
from app.modules.orders.models import Order

class OrderAdmin(ModelView, model=Order):
    column_list = [Order.id, Order.reference, Order.status, Order.total]
    column_searchable_list = [Order.reference]
    column_sortable_list = [Order.total, Order.created_at]
    icon = "fa-solid fa-receipt"

Frontend schema files

veloiq generate creates a TypeScript schema file for each module that the DynamicResource UI component reads to render list, detail, create, and edit views.
FileDescription
{module}Schema.gen.tsAuto-generated field definitions — do not edit
{module}Schema.manual.tsYour overrides and extensions — you write this
To customise or extend the generated schema, create {module}Schema.manual.ts in the same directory and merge it into {module}Schema.ts. Refer to the @veloiq/ui documentation for the ModelDef and FieldDef type reference.

Module auto-loading

On every startup, create_veloiq_app() scans app/modules/*/ and, for each subdirectory that contains an __init__.py, imports models.py, api.py, and custom_api.py (if present) and registers any ModelView classes found in admin/admin_views.py. Because of this automatic discovery, main.py never grows beyond a single line:
app = create_veloiq_app()
Pass a VeloIQConfig instance to create_veloiq_app() when you need to configure roles, the database URL, or other settings. The defaults work for local development with SQLite.

Models

Define fields, base classes, and relationships

Access Control

Apply RBAC and ReBAC to your modules and fields