dublyobase-backend-builder
Skill14 starsChanged 5 months agoMITView on GitHub
Build complete Dublyobase backends through remote HTTP MCP, admin REST APIs, and public project APIs. Use when an AI agent needs to connect to a live Dublyobase instance, create projects, design Postgres collections and fields, configure rules, seed records, create app users, upload files, configure SMTP/storage/CORS/auth settings, cron jobs, backups/restores, webhooks, quotas, orgs, invitations, SaaS or ecommerce schemas, schema import, and verify a PocketBase/Supabase-style backend.
In this repository12 other files it gives its agents.
- brandkitSkill
- dublyo-deploySkill
- image-to-codeSkill
- lean-codeSkill
- mdn-web-best-practicesSkill
- moatSkill
- playwright-website-testerSkill
- dublyo-pocketbaseSkill
- saas-kitSkill
- saas-product-growthSkill
- dublyo-tag-manager-serverSkill
- design-taste-frontend-v1Skill
The file
Show its rules and text
We split this skill into the rules it gives an agent
53 rules. About 0 are common, 41 are distinctive, and 12 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈41
Distinctive · estimate
This author's own choices. Worth a look.
12
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 21
If URL or credentials are missing, ask for them.
- Distinctive: line 23
Never print full tokens, API keys, SMTP passwords, S3 secrets, database URLs, restore files, or private webhook secrets in the final answer.
- Very specific: line 28
Treat tools/list as the source of truth for MCP.
- Distinctive: line 29
Prefer project-scoped MCP tokens for app-specific schema/data work.
- Distinctive: line 30
Use admin MCP or admin REST only for instance-level settings: SMTP, storage, admin CORS, full backups/restores, MCP tokens, and super …
- Distinctive: line 32
Use dry runs where available before schema import or restore.
- Distinctive: line 34
Verify with real REST requests after MCP writes.
- Distinctive: line 98
Default admin MCP tools:
- Distinctive: line 110
Default project MCP tools:
- Distinctive: line 143
Create referenced collections before relation fields.
- Very specific: line 144
Prefer normalized tables for relations.
- Distinctive: line 148
Create collections and rules.
- Distinctive: line 151
Verify public REST flows, auth flows, file upload/download, webhooks, cron, backups, and realtime where relevant.
- Distinctive: line 194
Prefer Lucide names for portable agent output.
- Distinctive: line 228
Use lower snake_case names.
- Very specific: line 229
Do not create fields named id, created, or updated for managed Dublyobase tables.
- Distinctive: line 230
Create relation targets before relation fields.
- Very specific: line 231
Use explicit names for tenant fields: organization, workspace, owner, customer, created_by.
- Distinctive: line 232
Use status select values instead of free text for workflows.
- Distinctive: line 255
Use a multiple relation when it is simple tagging or categorization:
- Distinctive: line 259
Use a join collection when the relationship has fields:
- Distinctive: line 295
Only use org-scoped rules if the target auth context actually exposes the needed org claim or your frontend/API layer enforces organization …
- Distinctive: line 306
Use schema discovery when the user wants Dublyobase to manage or expose existing Postgres tables:
- Distinctive: line 315
Import only tables with one usable primary key for CRUD.
- Distinctive: line 324
Read-only discovery can include broad non-system schemas.
- Very specific: line 357
Use page and perPage.
- Distinctive: line 377
Use searchable fields deliberately.
- Very specific: line 387
Use mode:"append" only for multi-file fields.
- Distinctive: line 423
Create an app auth user with MCP:
- Distinctive: line 468
Use auth settings for:
- Very specific: line 529
Use roles like owner, admin, member, viewer, billing.
- Distinctive: line 541
Use API keys for frontend server-side code, trusted workers, webhooks, migrations, and seed scripts.
- Distinctive: line 566
Only update SMTP with explicit credentials.
- Distinctive: line 568
Do not print SMTP passwords.
- Distinctive: line 569
Use the project/app name in auth templates.
- Very specific: line 592
Always run settings.storage.test or POST /admin/api/settings/storage/test after changing storage.
- Very specific: line 612
Avoid * for authenticated browser apps.
- Very specific: line 640
Use http cron jobs for external automation.
- Distinctive: line 642
Keep timeouts short and retries bounded.
- Distinctive: line 643
Run a job once manually after creation.
- Distinctive: line 679
Do not run full restore automatically.
- Distinctive: line 680
Do not restore into a production database without explicit approval.
- Distinctive: line 681
Prefer project-scoped backup jobs for SaaS/ecommerce apps.
- Distinctive: line 722
Create a test record that matches the event.
- Very specific: line 723
Check deliveries endpoint for success, attempts, status code, response, and error.
- Distinctive: line 724
If possible, verify the receiver saw the request.
- Distinctive: line 730
Avoid sending sensitive fields to untrusted targets.
- Distinctive: line 731
Treat webhook.site and similar tools as temporary smoke-test receivers.
- Distinctive: line 747
Use one Dublyobase app replica for realtime-sensitive projects until database-backed or external fanout is configured.
- Distinctive: line 748
Delete events include payloads only for service subscribers.
- Distinctive: line 811
Use this pattern for B2B SaaS, team apps, dashboards, and developer platforms.
- Distinctive: line 856
Use this pattern for storefronts, marketplaces, and WooCommerce-style apps.
- Very specific: line 977
Create/list/update critical records.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Dublyobase Backend Builder
Use this skill to turn an app brief into a working Dublyobase backend. Dublyobase is a Postgres-backed PocketBase/Supabase-style backend with projects, collections, records CRUD, app auth, sessions, files, SMTP, S3-compatible storage, cron jobs, backups, schema import, realtime SSE, webhooks, request logs, quotas, app organizations, invitations, and remote HTTP MCP.
This skill is written for AI agents. It favors direct, verified backend creation over long planning. Keep changes conservative, verify every critical workflow, and never expose secrets.
Inputs
Require these before changing a live instance:
DUBLYOBASE_URL: base URL, for examplehttps://example.com.- Either
DUBLYOBASE_MCP_TOKENforPOST /mcp, or an admin bearer token for/admin/api/*. - Target project slug, or permission to create one.
- App brief: users, workflows, tenants, roles, data, permissions, files, automations, email needs, frontend origins, and sample records.
If URL or credentials are missing, ask for them. If the app brief is enough to infer a conservative schema, do not ask extra questions.
Never print full tokens, API keys, SMTP passwords, S3 secrets, database URLs, restore files, or private webhook secrets in the final answer. Mask them.
Operating Rules
- Inspect capabilities first:
GET /health,GET /ready, MCPinitialize, and MCPtools/list. - Treat
tools/listas the source of truth for MCP. Some product features may only be available through admin REST. - Prefer project-scoped MCP tokens for app-specific schema/data work.
- Use admin MCP or admin REST only for instance-level settings: SMTP, storage, admin CORS, full backups/restores, MCP tokens, and super admins.
- Make destructive operations opt-in: collection deletion, field drops, destructive schema import, restore mode, global CORS wildcard, and full-instance backup changes.
- Use dry runs where available before schema import or restore.
- Preserve existing user data. Prefer additive schema changes unless the user asked for migration or cleanup.
- Verify with real REST requests after MCP writes. A schema that exists but cannot be used from the public API is not complete.
- Final reports must include project slug, created resources, API examples, verification evidence, and remaining boundaries.
Dublyobase Surfaces
Admin UI:
GET {DUBLYOBASE_URL}/_/Admin REST:
Authorization: Bearer {admin_token}
Content-Type: application/jsonRemote HTTP MCP:
POST {DUBLYOBASE_URL}/mcp
Authorization: Bearer {DUBLYOBASE_MCP_TOKEN}
Content-Type: application/jsonPublic project API:
GET /api/projects/{slug}/collections/{collection}/records
Authorization: Bearer {app_access_token_or_api_key}Health:
GET /health
GET /readyMCP Connection
Initialize:
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"ai-agent","version":"1"}}}List tools:
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}Call a tool:
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"collections.list","arguments":{"projectSlug":"app"}}}MCP success results return text content containing JSON. Parse result.content[0].text as JSON when possible. Tool errors can appear as JSON-RPC errors or as tool results with isError=true; inspect both.
MCP Tools
Default admin MCP tools:
projects.list,projects.createcollections.list,collections.create,collections.updateschema.discover,schema.importrecords.list,records.create,records.update,records.deletefiles.upload_base64users.createsettings.smtp.update,settings.storage.update,settings.storage.testcron.list,cron.create,cron.runbackups.list,backups.create,backups.run
Default project MCP tools:
collections.list,collections.create,collections.updateschema.discover,schema.importrecords.list,records.create,records.update,records.deletefiles.upload_base64users.createbackups.list,backups.create,backups.run
Admin REST is still needed for:
- API keys
- Webhooks and webhook deliveries
- CORS settings
- Auth settings and email templates
- Project quotas and metrics
- Backup downloads and restore upload
- Request logs and audit logs
- Owner/super-admin management
Build Workflow
- Check health:
GET {DUBLYOBASE_URL}/healthGET {DUBLYOBASE_URL}/ready- Expect database and storage readiness before writes.
- Initialize MCP and call
tools/list. - Find or create the project:
- Admin MCP:
projects.list, thenprojects.createif needed. - Project MCP: use the scoped project.
- Admin REST:
GET /admin/api/projects,POST /admin/api/projects.
- Admin MCP:
- Model the backend:
- Identify app users, organizations, roles, ownership fields, public content, private tenant data, files, statuses, automation, webhooks, and frontend origins.
- Create referenced collections before relation fields.
- Prefer normalized tables for relations. Use
jsononly for flexible metadata or provider payloads. - Mark display fields as
presentable:true. - Mark only useful text/email/url/select/number/date/relation fields as
searchable:true. - Choose collection icons with
options.icon.
- Create collections and rules.
- Seed minimal records and at least one app user when the app uses auth.
- Configure auth settings, SMTP, storage, CORS, quotas, API keys, webhooks, cron, and backups only when requested or needed by the brief.
- Verify public REST flows, auth flows, file upload/download, webhooks, cron, backups, and realtime where relevant.
- Return a concise build summary with examples and proof.
Collection Design
Create a collection:
{
"projectSlug": "app",
"name": "posts",
"type": "base",
"options": {"icon": {"type": "lucide", "name": "file-text"}},
"fields": [
{"name": "title", "type": "text", "required": true, "presentable": true, "searchable": true},
{"name": "body", "type": "editor", "options": {"maxSize": 200000}},
{"name": "published", "type": "bool"},
{"name": "author", "type": "relation", "required": true, "options": {"collection": "users", "displayField": "email", "reverseName": "posts"}},
{"name": "cover", "type": "file", "options": {"multiple": false, "maxSize": 5242880, "mimeTypes": ["image/png", "image/jpeg"]}},
{"name": "created_auto", "type": "autodate", "options": {"onCreate": true}},
{"name": "updated_auto", "type": "autodate", "options": {"onCreate": true, "onUpdate": true}}
],
"listRule": "published = true",
"viewRule": "published = true || author = @request.auth.id",
"createRule": "@request.auth.role = \"authenticated\"",
"updateRule": "author = @request.auth.id",
"deleteRule": "author = @request.auth.id"
}Collection types:
base: normal table-backed collection.auth: app-user collection.view: metadata for database views; avoid writes and realtime assumptions.
Collection icon options:
{"icon":{"type":"lucide","name":"table"}}
{"icon":{"type":"emoji","value":"<real emoji character>"}}Prefer Lucide names for portable agent output. Use the emoji fallback only when the caller can provide a real emoji character.
Useful Lucide names:
- SaaS:
building-2,users,user-round,shield,key-round,credit-card,chart-no-axes-column,bell,briefcase,settings - Ecommerce:
shopping-cart,package,boxes,tag,receipt,truck,store,badge-percent,star,warehouse - Content:
file-text,book-open,message-square,image,folder,globe,calendar,mail
Field Reference
Field shape:
{"name":"field_name","type":"text","required":false,"hidden":false,"presentable":false,"searchable":false,"help":"optional","options":{}}Supported types and common options:
text: string. Options:min,max,pattern.editor: rich text/HTML string. Options:maxSize.password: bcrypt-hashed string, never returned. Options:min,max,cost.number: double precision. Options:onlyInt,min,max.bool: boolean.date: timestamp.autodate: server-managed timestamp. Options:onCreate,onUpdate.email: email string. Options:onlyDomains,exceptDomains.url: URL string. Options:min,max,pattern.select: text or text array. Required option:values. Options:minSelect,maxSelect;maxSelect > 1,multi, ormultiplemakes it multiple.json: JSONB object. Options:maxSize.relation: UUID or UUID array to another collection. Required option:collection. Options:minSelect,maxSelect,displayField,reverseName,unique,onDelete.file: JSONB metadata. Options:multiple,minSelect,maxSelect,maxSize,mimeTypes.
Naming rules:
- Use lower snake_case names.
- Do not create fields named
id,created, orupdatedfor managed Dublyobase tables. - Create relation targets before relation fields.
- Use explicit names for tenant fields:
organization,workspace,owner,customer,created_by. - Use status select values instead of free text for workflows.
Relations
Many-to-one:
{"name":"customer","type":"relation","required":true,"options":{"collection":"users","displayField":"email","reverseName":"orders"}}One-to-many:
- Store the relation on the many side.
- Example:
order_items.order -> orders, withreverseName:"items".
Strict one-to-one:
{"name":"customer","type":"relation","required":true,"options":{"collection":"users","displayField":"email","unique":true,"reverseName":"profile"}}Many-to-many:
- Use a multiple relation when it is simple tagging or categorization:
{"name":"tags","type":"relation","options":{"collection":"tags","maxSelect":20,"displayField":"name","reverseName":"products"}} - Use a join collection when the relationship has fields:
product_categories:product,category,positionorganization_memberships:organization,user,role,statussubscription_items:subscription,price,quantity
For billing, permissions, invitations, product variants, inventory, and order items, prefer join collections. They scale better and are easier to audit.
Rules
Rule values:
- Omitted rule or JSON
null: admin/service only. - Empty string
"": public. - Expression: compiled to Postgres RLS.
Supported request references:
@request.auth.id@request.auth.role@request.auth.collection
Typical roles:
anonauthenticatedservice
Common rule patterns:
published = true
owner = @request.auth.id
published = true || owner = @request.auth.id
created_by = @request.auth.idOnly use org-scoped rules if the target auth context actually exposes the needed org claim or your frontend/API layer enforces organization selection. Otherwise model org membership in collections and use service-side endpoints for sensitive multi-tenant actions.
Security defaults:
- Private user data: list/view/update/delete should require ownership or organization membership.
- Public catalog data: list/view can be public; create/update/delete should be service/admin only.
- Orders, payments, invoices, licenses, API keys, audit trails: service/admin only unless there is a clear user-owned read rule.
- Webhook logs, cron logs, backups: admin only.
Existing Postgres Tables
Use schema discovery when the user wants Dublyobase to manage or expose existing Postgres tables:
{"name":"schema.discover","arguments":{"projectSlug":"app","schema":"public"}}Import safely:
- Run
schema.discover. - Import only tables with one usable primary key for CRUD.
- First use dry run:
{"projectSlug":"app","dryRun":true,"items":[{"schema":"public","table":"customers","name":"customers"}]} - Apply with
dryRun:falseonly after reviewing the preview.
Compatibility guidance:
- Read-only discovery can include broad non-system schemas.
- CRUD import requires a usable primary key.
- Field/schema management should stay conservative unless the table is managed by Dublyobase or the user approves a migration.
- For full Dublyobase-managed editing, prefer standard
id uuid,created, andupdatedcolumns or run an explicit migration.
Records
Create:
{"name":"records.create","arguments":{"projectSlug":"app","collection":"posts","data":{"title":"Hello","published":true}}}List:
{"name":"records.list","arguments":{"projectSlug":"app","collection":"posts","page":1,"perPage":25,"sort":"-created","search":"hello","fields":"id,title,created"}}Update:
{"name":"records.update","arguments":{"projectSlug":"app","collection":"posts","id":"record-id","data":{"published":true}}}Delete:
{"name":"records.delete","arguments":{"projectSlug":"app","collection":"posts","id":"record-id"}}Pagination:
- Use
pageandperPage. - UI page sizes commonly include
10,25,100,250, and500. - For big datasets, prefer narrow
fields, indexed filters, and stable sort keys.
Filters:
- PocketBase-style:
title = "Hello" status = "paid" && total > 100 - Directus-style JSON:
{"title":{"_icontains":"hello"}} - Combined:
{"_or":[{"title":{"_icontains":"hello"}},{"status":{"_eq":"live"}}]}
Use searchable fields deliberately. Do not mark every text field searchable in large schemas.
Files
MCP upload:
{"name":"files.upload_base64","arguments":{"projectSlug":"app","collection":"products","recordId":"record-id","field":"image","filename":"image.png","dataBase64":"...","mode":"replace"}}Use mode:"append" only for multi-file fields.
Public multipart upload:
POST /api/projects/{slug}/files/{collection}/{recordId}/{field}?mode=replace
Authorization: Bearer {token}
Content-Type: multipart/form-dataResumable upload:
POST /api/projects/{slug}/files/{collection}/{recordId}/{field}/uploads
PUT /api/projects/{slug}/files/uploads/{uploadId}/chunks/{index}
POST /api/projects/{slug}/files/uploads/{uploadId}/complete
DELETE /api/projects/{slug}/files/uploads/{uploadId}Protected downloads:
POST /api/projects/{slug}/files/{collection}/{recordId}/{field}/{fileId}/token
GET /api/projects/{slug}/files/{collection}/{recordId}/{field}/{fileId}/{filename}?token={file_token}File field guidance:
- Product image: single file, images only, max 5-10 MB.
- Product gallery: multiple files, maxSelect 10-20.
- User avatar: single file, images only, low max size.
- Documents: restrict mime types, keep private rules.
- Large uploads: use resumable upload, not base64 MCP.
App Auth
Create an app auth user with MCP:
{"name":"users.create","arguments":{"projectSlug":"app","email":"user@example.com","password":"change-me-strong"}}Public app auth endpoints:
POST /api/projects/{slug}/auth/signup
POST /api/projects/{slug}/auth/login
POST /api/projects/{slug}/auth/request-otp
POST /api/projects/{slug}/auth/login-otp
POST /api/projects/{slug}/auth/refresh
POST /api/projects/{slug}/auth/logout
POST /api/projects/{slug}/auth/logout-all
GET /api/projects/{slug}/auth/sessions
DELETE /api/projects/{slug}/auth/sessions/{sessionId}
GET /api/projects/{slug}/auth/me
POST /api/projects/{slug}/auth/request-email-change
POST /api/projects/{slug}/auth/confirm-email-change
POST /api/projects/{slug}/auth/request-verification
POST /api/projects/{slug}/auth/confirm-verification
POST /api/projects/{slug}/auth/request-password-reset
POST /api/projects/{slug}/auth/confirm-password-resetHosted action pages:
GET /auth/verify
POST /auth/verify
GET /auth/reset-password
POST /auth/reset-password
GET /auth/email-change
POST /auth/email-changeAuth settings via admin REST:
GET /admin/api/projects/{slug}/auth-settings
PUT /admin/api/projects/{slug}/auth-settingsUse auth settings for:
- Access token minutes.
- Refresh token days.
- Verify token hours.
- Reset token hours.
- OTP enabled and OTP token minutes.
- Email change enabled and password requirement.
- Email templates for verification, reset, email change, OTP, and invitations.
- OAuth provider skeletons if present in current instance.
Recommended auth UX:
- Signup creates user and sends verification email when SMTP is configured.
- Login returns access and refresh tokens.
- Refresh rotates sessions.
- Logout revokes one session.
- Logout-all revokes all user sessions.
- Sessions UI lets users see and revoke devices.
- Email change requires current password, then email confirmation.
- Password reset uses one-time email token.
- OTP is optional passwordless login, not full MFA unless the app adds a second factor requirement.
App Organizations And Invitations
Public app organization endpoints:
GET /api/projects/{slug}/orgs
POST /api/projects/{slug}/orgs
GET /api/projects/{slug}/orgs/{orgId}/members
POST /api/projects/{slug}/orgs/{orgId}/invitations
POST /api/projects/{slug}/org-invitations/acceptCreate org:
{"name":"Acme Inc","slug":"acme","metadata":{"plan":"pro"}}Create invitation:
{"email":"member@example.com","role":"admin"}Accept invitation:
{"token":"invitation-token"}Recommended SaaS primitives:
- Built-in app orgs: create through
/api/projects/{slug}/orgsfor login-time organization membership and invitations. - Built-in app org members: query through
/api/projects/{slug}/orgs/{orgId}/members. - Built-in app org invitations: create and accept through the org invitation endpoints.
- Normal collection relations need normal collection metadata. If the app needs collection-level relations to tenants, create an
organizationscollection or import the built-in org table as a collection after discovery. - Billing collections should relate to organization/account, not only to a user.
- App API keys should relate to organization/account and creator.
- Use roles like
owner,admin,member,viewer,billing.
API Keys
Admin REST:
GET /admin/api/projects/{slug}/api-keys
POST /admin/api/projects/{slug}/api-keys
DELETE /admin/api/projects/{slug}/api-keys/{id}Use API keys for frontend server-side code, trusted workers, webhooks, migrations, and seed scripts. Do not expose service keys in browsers.
Recommended key types:
- Anon key: public browser reads only when rules allow it.
- Service key: server-only automation and privileged writes.
- Project-scoped MCP token: AI/backend builder operations.
SMTP And Email
MCP update:
{"name":"settings.smtp.update","arguments":{"enabled":true,"host":"smtp.example.com","port":"587","username":"user","password":"secret","from":"support@example.com"}}Admin REST:
PUT /admin/api/settings/smtp
POST /admin/api/settings/smtp/testSafety:
- Only update SMTP with explicit credentials.
- Send a test email after changing SMTP.
- Do not print SMTP passwords.
- Use the project/app name in auth templates.
- For production, make sure SPF/DKIM/DMARC are configured outside Dublyobase.
Storage
MCP update:
{"name":"settings.storage.update","arguments":{"type":"s3","s3":{"endpoint":"https://account.r2.cloudflarestorage.com","bucket":"app-files","region":"auto","accessKey":"...","secretKey":"...","prefix":"uploads","useSSL":true,"forcePathStyle":true}}}Admin REST:
PUT /admin/api/settings/storage
POST /admin/api/settings/storage/testStorage types:
local: simple single-server storage.s3: S3-compatible storage such as Cloudflare R2, Backblaze B2, MinIO, or AWS S3.
Always run settings.storage.test or POST /admin/api/settings/storage/test after changing storage.
CORS
Admin CORS:
PUT /admin/api/settings/corsProject public API CORS:
PUT /admin/api/projects/{slug}/corsRecommended defaults:
- Admin CORS: lock to
APP_URLor the trusted admin domain. - Public project CORS: lock to frontend domains for that project.
- Avoid
*for authenticated browser apps. - Allow wildcard only for intentionally public APIs with no credentials and no sensitive data.
Example:
{"publicOrigins":["https://app.example.com","https://www.example.com"],"allowWildcard":false}Cron Jobs
MCP:
{"name":"cron.create","arguments":{"projectSlug":"app","name":"daily sync","type":"http","schedule":"0 2 * * *","timezone":"UTC","enabled":true,"method":"POST","url":"https://example.com/api/sync","headers":{"Authorization":"Bearer ..."},"body":"{}","timeoutSeconds":30,"retryCount":2}}Admin REST:
GET /admin/api/cron-jobs
POST /admin/api/cron-jobs
GET /admin/api/cron-jobs/{id}/runs
POST /admin/api/cron-jobs/{id}/runGuidance:
- Use
httpcron jobs for external automation. - Include auth headers when calling private endpoints.
- Keep timeouts short and retries bounded.
- Run a job once manually after creation.
- Review run logs for status code, response, and error.
Backups And Restore
MCP:
{"name":"backups.create","arguments":{"name":"daily project backup","scope":"project","projectSlug":"app","schedule":"0 3 * * *","timezone":"UTC","enabled":true,"retentionDays":14,"retentionCount":14}}Admin REST:
GET /admin/api/backups
POST /admin/api/backups
GET /admin/api/backups/{id}/runs
POST /admin/api/backups/{id}/run
GET /admin/api/backups/{id}/runs/{runId}/download
POST /admin/api/restoresBackup scope:
project: preferred for app-specific backups.full: admin-only full instance backup.
Restore flow:
- Download or choose a backup file.
- Upload with
mode=dry_run. - Inspect the restore job result and warnings.
- Upload again with
mode=restoreonly with explicit approval and required confirmation.
Safety:
- Do not run full restore automatically.
- Do not restore into a production database without explicit approval.
- Prefer project-scoped backup jobs for SaaS/ecommerce apps.
- Storage must be configured and tested before scheduled backups.
Webhooks
Admin REST:
GET /admin/api/projects/{slug}/webhooks
POST /admin/api/projects/{slug}/webhooks
DELETE /admin/api/projects/{slug}/webhooks/{id}
GET /admin/api/projects/{slug}/webhooks/{id}/deliveriesCreate:
{
"name": "Order events",
"url": "https://example.com/webhooks/dublyobase",
"events": ["orders.create", "orders.update"],
"enabled": true,
"secret": "generated-secret"
}Event examples:
records.create,records.update,records.delete{collection}.create,{collection}.update,{collection}.deleteorders.createusers.create
Delivery headers:
X-Dublyobase-EventX-Dublyobase-DeliveryX-Dublyobase-Signature
Verify:
- Create a test record that matches the event.
- Check deliveries endpoint for
success, attempts, status code, response, and error. - If possible, verify the receiver saw the request.
Security:
- Require HTTPS for production webhook targets.
- Generate strong secrets and verify signatures on the receiver.
- Avoid sending sensitive fields to untrusted targets.
- Treat webhook.site and similar tools as temporary smoke-test receivers.
Realtime
Public SSE:
GET /api/projects/{slug}/realtime?collection=posts&events=create,update
Authorization: Bearer {api-key-or-app-token}Browser EventSource cannot set headers. Use token or access_token query only when the URL will not be logged.
Current boundary:
- Realtime fanout is in-process.
- Use one Dublyobase app replica for realtime-sensitive projects until database-backed or external fanout is configured.
- Delete events include payloads only for service subscribers.
Logs, Audit, Metrics, And Quotas
Admin REST:
GET /admin/api/audit-log?project={slug}&page=1&perPage=25
GET /admin/api/request-logs?project={slug}&page=1&perPage=25
PUT /admin/api/settings/logs
GET /admin/api/projects/{slug}/quotas
PUT /admin/api/projects/{slug}/quotas
GET /admin/api/projects/{slug}/metrics?hours=24Quota settings:
{
"enabled": true,
"requestsPerMinute": 600,
"authRequestsPerMinute": 60,
"maxAppUsers": 100000,
"maxStorageMB": 102400
}Use quotas for:
- Auth abuse protection.
- Public API abuse limits.
- Per-project user caps.
- Storage caps.
Use metrics for:
- App users.
- Active sessions.
- Organizations.
- Storage usage.
- Request totals, errors, average duration, and p95 duration.
Admins
Admin REST:
GET /admin/api/admins
POST /admin/api/admins
PATCH /admin/api/auth/email
POST /admin/api/auth/change-passwordRules:
- First admin is owner.
- Owner can create super admins with temporary passwords.
- New super admins must change password before normal admin access.
- Super admins can manage the app and change their own email/password.
- Super admins must not remove or demote the owner.
SaaS Schema Pattern
Use this pattern for B2B SaaS, team apps, dashboards, and developer platforms.
Collections:
usersauth collection: built-in app users.- Built-in app orgs: create through
/api/projects/{slug}/orgs. organizations: optional normal collection mirror for relation fields, billing records, and admin CRUD.projects: tenant-owned workspaces/resources.rolesorpermission_sets: optional role catalog.invitations: if app needs custom invite metadata beyond built-in invitations.api_keys: app-facing keys, scoped to organization/project.subscriptions: billing plan, status, current period, provider IDs.invoices: billing documents and payment state.usage_events: metered usage records.audit_events: tenant-visible app audit.notifications: user/org notifications.webhook_endpoints: customer-defined outbound webhooks if the SaaS exposes them.
Example collection fields:
{
"name": "projects",
"type": "base",
"options": {"icon": {"type": "lucide", "name": "briefcase"}},
"fields": [
{"name":"organization","type":"relation","required":true,"options":{"collection":"organizations","displayField":"name","reverseName":"projects"}},
{"name":"name","type":"text","required":true,"presentable":true,"searchable":true},
{"name":"slug","type":"text","required":true,"searchable":true},
{"name":"status","type":"select","required":true,"options":{"values":["active","archived","suspended"]}},
{"name":"settings","type":"json"},
{"name":"created_by","type":"relation","options":{"collection":"users","displayField":"email"}}
],
"listRule": "@request.auth.role = \"authenticated\"",
"viewRule": "@request.auth.role = \"authenticated\"",
"createRule": "@request.auth.role = \"authenticated\"",
"updateRule": "@request.auth.role = \"authenticated\"",
"deleteRule": null
}For high-security SaaS, do not rely only on broad authenticated rules. Add service-side endpoints or stricter org-aware rules once org claims are available in the auth context.
Ecommerce Schema Pattern
Use this pattern for storefronts, marketplaces, and WooCommerce-style apps.
Collections:
usersauth collection.customers: profile data related one-to-one to users.addresses: customer shipping/billing addresses.products: catalog.product_variants: SKU/price/inventory variant rows.categories: product hierarchy.product_categories: join collection with position.brands: optional.product_images: optional image records, or use file fields on products/variants.carts: current cart per user/session.cart_items: cart lines.orders: order header.order_items: order lines.payments: payment attempts and provider state.shipments: shipment tracking.coupons: discount definitions.coupon_redemptions: usage tracking.reviews: customer reviews.inventory_movements: stock ledger.webhook_events: payment/provider webhook audit if needed.
Recommended public rules:
- Products/categories: public list/view for active published data.
- Reviews: public list/view after approval; authenticated create.
- Carts/orders/payments/addresses: owner only or service/admin only.
- Inventory and payment provider payloads: service/admin only.
Example products:
{
"projectSlug": "shop",
"name": "products",
"type": "base",
"options": {"icon": {"type": "lucide", "name": "package"}},
"fields": [
{"name":"name","type":"text","required":true,"presentable":true,"searchable":true},
{"name":"slug","type":"text","required":true,"searchable":true},
{"name":"description","type":"editor","options":{"maxSize":200000}},
{"name":"status","type":"select","required":true,"options":{"values":["draft","active","archived"]}},
{"name":"price","type":"number","required":true,"options":{"min":0}},
{"name":"currency","type":"select","required":true,"options":{"values":["USD","EUR","GBP","AED","KWD"]}},
{"name":"image","type":"file","options":{"multiple":false,"maxSize":5242880,"mimeTypes":["image/png","image/jpeg","image/webp"]}},
{"name":"gallery","type":"file","options":{"multiple":true,"maxSelect":12,"maxSize":10485760,"mimeTypes":["image/png","image/jpeg","image/webp"]}},
{"name":"metadata","type":"json"}
],
"listRule": "status = \"active\"",
"viewRule": "status = \"active\"",
"createRule": null,
"updateRule": null,
"deleteRule": null
}Example orders:
{
"name": "orders",
"type": "base",
"options": {"icon": {"type": "lucide", "name": "receipt"}},
"fields": [
{"name":"customer","type":"relation","required":true,"options":{"collection":"users","displayField":"email","reverseName":"orders"}},
{"name":"status","type":"select","required":true,"options":{"values":["pending","paid","processing","shipped","completed","cancelled","refunded"]}},
{"name":"subtotal","type":"number","required":true,"options":{"min":0}},
{"name":"tax","type":"number","options":{"min":0}},
{"name":"shipping","type":"number","options":{"min":0}},
{"name":"total","type":"number","required":true,"options":{"min":0}},
{"name":"currency","type":"select","required":true,"options":{"values":["USD","EUR","GBP","AED","KWD"]}},
{"name":"billing_address","type":"json"},
{"name":"shipping_address","type":"json"},
{"name":"provider_payload","type":"json","hidden":true}
],
"listRule": "customer = @request.auth.id",
"viewRule": "customer = @request.auth.id",
"createRule": null,
"updateRule": null,
"deleteRule": null
}Public REST Verification
Records:
GET /api/projects/{slug}/collections/{collection}/records?page=1&perPage=25
POST /api/projects/{slug}/collections/{collection}/records
GET /api/projects/{slug}/collections/{collection}/records/{id}
PATCH /api/projects/{slug}/collections/{collection}/records/{id}
DELETE /api/projects/{slug}/collections/{collection}/records/{id}Batch:
POST /api/projects/{slug}/batchAuth:
POST /api/projects/{slug}/auth/signup
POST /api/projects/{slug}/auth/login
GET /api/projects/{slug}/auth/meFiles:
POST /api/projects/{slug}/files/{collection}/{recordId}/{field}
GET /api/projects/{slug}/files/{collection}/{recordId}/{field}/{fileId}/{filename}Always verify:
- Create/list/update critical records.
- Filter and search on configured searchable fields.
- Auth signup/login/me if auth is used.
- Owner/private rules reject another user where relevant.
- File upload and download if file fields exist.
- Webhook delivery after record create/update/delete if webhooks exist.
- Realtime event if realtime is part of the app.
- Cron run if cron jobs exist.
- Backup run if backup jobs exist.
Security Checklist
Before reporting done:
- Health and readiness are OK.
- MCP token scope is the least privilege available.
- Admin REST tokens and MCP tokens are not printed.
- SMTP, S3, webhook, database, and API secrets are redacted.
- Admin CORS is not wildcard for production.
- Project public CORS is locked to known frontend origins unless explicitly public.
- Public write rules are intentional.
- Private data has owner, organization, or service-only rules.
- Service API keys are never placed in browser examples.
- Webhook secrets are generated and signature verification is documented.
- Quotas are enabled or a reason is given.
- Auth token durations and email templates are reviewed when auth is used.
- Backup jobs are project-scoped unless full-instance backups were requested.
- Restore was only dry-run unless explicit restore approval was given.
- Realtime single-replica boundary is mentioned if realtime is used.
Completion Checklist
Before reporting done:
GET /healthandGET /readypassed.- MCP
initializeandtools/listworked when MCP is used. - Project exists.
- Collections exist with expected field types, relations, icons, rules, searchable fields, and presentable fields.
- Existing tables were discovered/imported with dry-run first when schema import is used.
- At least one create/list/update path was verified for critical collections.
- Pagination, filters, search, sort, and field selection were tested for primary lists.
- App signup/login/me was tested if the app uses auth.
- Verification, reset, email change, OTP, sessions, or org invitations were tested if configured.
- File upload/download was tested if file fields exist.
- Storage test passed if storage settings changed.
- SMTP test passed if SMTP settings changed.
- CORS settings match frontend origins.
- API keys were created only when needed and masked in output.
- Webhook delivery success was verified if webhooks exist.
- Cron run was tested if cron jobs exist.
- Backup run was tested if backup jobs exist.
- Restore stayed in dry-run unless explicitly approved.
- Metrics/quotas were checked for SaaS or production-like apps.
- Final answer includes project slug, created resources, API examples, tests performed, and remaining boundaries.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

