> From database fields to form validation > From field specifications to display policies > From operations to API endpoints
A resource describes a type of business object: the information it holds, its relationships to other objects, and the actions available on it.
Wildo uses these definitions across data handling, APIs and standard forms.
You decide the business rules and the user experience.
A shared model for the work around each object
Keep data and interactions aligned
Shared field rules and declared operations connect your data, standard forms and API actions, reducing separate definitions to maintain as the application evolves.
Keep documents with the work
File fields connect attachments and generated documents to their records. People can find the supporting material alongside the business object it belongs to.
Make the experience your own
You choose the business rules, access policies and screen layouts. Extend standard behavior with custom actions and components where your product needs something specific.
Example: One task, several ways to work with it
A task’s title rule guides its standard form and API validation. Its declared actions make it available to people and integrations. A configured PDF template can turn its information into an attached summary.
For engineers
What does a resource look like in code?
You define its fields in a Zod schema, choose its operations in a resource configuration, and connect it to other resources through relationships. A resource is the combination of those decisions; it is not just a database table or a TypeScript type.
Describe values and the interactions they support
These selected fields come from Wonder Todos’ Todos_BaseSchema. They show ordinary values, a repeated group and a conditional field together. Other fields and source comments are omitted; this is the body of a schema, not a standalone module.
title: z.string().min(1).max(200).isSummaryField(),
description: z.string().max(1000).optional(),
status: z.enum(Todos_Status).default(Todos_Status.PENDING).isSummaryField(),
priority: z.enum(Todos_Priority).default(Todos_Priority.MEDIUM).isSummaryField(),
dueDate: z.date().optional().isSummaryField(),
checklist: z.array(z.object({
label: z.string().min(1).max(200),
done: z.boolean().default(false),
})).optional(),
reminder: z.object({
enabled: z.boolean().default(false),
leadTimeMinutes: z.number().int().min(0).max(10080).default(30)
.showWhen({ conditions: { field: 'enabled', value: true } }),
}).optional(),
The title’s underlined requirement participates in request validation and standard field validation. isSummaryField() marks a value for summary representations; it does not grant permission to read the record.
The first highlighted group defines repeated checklist entries, each with its own label and completion flag. Standard form rendering can present those entries as editable rows. The second group keeps reminder settings together: showWhen makes the lead-time control relevant when the sibling enabled value is true. That presentation rule is separate from authorization.
Declare how the object can be accessed
The resource configuration connects mainSchema: Todos_Schema to its operations and relationships. This is the actual READ declaration from todos.resources-config.ts, with comments omitted:
[CoreResourceOperation.READ]: {
variants: [
{
variantType: ResourceOperationVariantType.API_CALL,
isDefault: true,
roles: [CORE_ORG_ROLES.ORG_MEMBER],
riskLevel: ResourceOperationRiskLevel.LOW,
mcp: { exposed: true, servers: ['support'], description: 'Fetch a single todo by its id, including its title, description, status, priority, assignee, and due date.' },
}
]
},
The API variant exposes the standard read operation. The role declaration gates the caller; relationship and resource scope still determine which record the caller can access. The MCP setting additionally publishes this operation on the configured support server, with a description for its tool catalogue. It does not make the operation public or create a separate business implementation.
A field change and an access-policy change therefore have different homes. The schema describes values and metadata; the operation defines the action and its admission rules. Frontend behavior chooses how people encounter that action.
Which declaration drives which behavior?
A resource combines several declarations with distinct responsibilities. Sharing the model means connecting these inputs, rather than putting every decision into one schema.
| You declare | Wildo uses it for | You still decide |
|---|---|---|
| Fields and field metadata | Synthesized operation inputs, validation, storage metadata and standard controls | Meaning, accepted values and presentation choices |
| Operations and relationships | Available actions, request contracts, contextual routes and configured access checks | Business policy, eligible relationships and custom action logic |
| Collection query settings | Search, filters, ordering, pagination and source-operation exports | Which questions the collection supports |
| File fields and storage configuration | Upload integration, saved references and resource-specific serving | Storage, scanning, sharing and lifecycle policies |
| Generated file fields and registered templates | PDF rendering and attachment to the resource | Layout, rendering context and when to regenerate |
The API and configured standard interface consume these definitions. Custom request contracts and custom components are explicit authoring choices: they need to preserve the intended field rules and interaction behavior.
Where do I customize the application?
Choose the screen arrangement in UI behavior and add custom components where the product needs them. Give a business action its own operation contract, then add a handler for its specific logic. You can extend the normal write behavior or replace it explicitly; the choice determines which responsibilities your handler takes on.
How does a definition change reach the application?
A shared declaration gives the framework’s consumers one source to read. It does not make every update a live change. PostgreSQL schema changes need migrations; deployed code needs publication. Labels and API documentation have their own generation steps. Existing PDFs stay unchanged until regeneration is requested.
Keep those steps in the application’s development workflow. Verify the generated contracts and configured interface alongside any custom handlers that use them. Transaction coverage depends on handler mode and participating resources; audit emission depends on the operation’s risk and shape.
The domains below explain these connections in detail: defining objects and actions, working with data, managing attachments, and producing or reading documents.
A shared foundation across your application.
The resource system connects business definitions with the behavior built around them: storing and finding records, exposing actions, managing attachments and producing documents.
Shared declarations keep those parts aligned. Your application chooses its business rules, access policies and experience; Wildo supplies the common mechanisms they build on.