# Build a Full-Stack SaaS with Database, Auth and a Tested User Journey

Canonical: https://uvilno.com/guides/how-to-build-a-full-stack-saas-with-database-and-auth
Updated: 2026-10-27

Plan typed records, isolated accounts, real CRUD, transactional automations and optional AI in Uvilno. Verify persistence and payment boundaries before launch.

Written by the Uvilno team. Examples illustrate workflows; confirm service availability before launch.

## Define one complete product loop

Start with a task someone will repeat: sign in, find a customer, record the next follow-up and return later to see it. A small SaaS does not need every dashboard pattern at once. Describe the audience, the records that person owns and the result they expect after each action. Keep a separate list of exclusions such as organization sharing, calendar synchronization or live subscriptions. This gives the builder an implementable scope and gives you a concrete way to decide whether the result is useful beyond its first screen.

Name the project for your own organization without turning that name into the entire AI request. Opening a draft or adjusting its brief does not start generation. Write the actual product requirements in the conversation, use Plan when the scope needs discussion, and approve a build deliberately. Planning, enhancement and generation may consume their documented usage. There is no reliable universal ten-minute promise for an application with data, identity and operational requirements; the time needed depends on the specific work and the checks it must pass.

- Choose one repeatable task.
- Write its success and failure outcomes.
- Define private versus deliberately shared data.
- List integrations and features excluded from the first release.

## Declare the records and routes before building views

For a client tracker, begin with customers and followups. Customers might contain a required name and optional company, while followups contain a title, a supported status, a date and a reference to a customer. Declare the schema, field types and reference relationship in the project’s data contract. Require private visitor ownership unless the use case deliberately needs a public catalog. Keep real transactional collections empty at launch; use fictional demonstration rows only when clearly disclosed and separated from real customer activity.

Map the routes to those records. Home explains the product, Login and Register establish the app identity, Customers exposes the list, a detail route shows context, Activity explains committed changes and Profile contains supported account controls. Ask for shared navigation and a shared data controller rather than separate disconnected arrays on each page. The contract-first workflow helps subsequent files agree on names and destinations, but it still needs review. A declared route that is never reachable or a field that changes meaning across pages remains an application defect.

A bounded client-follow-up contract

| Area | First implementation | Acceptance check |
| --- | --- | --- |
| Customers | Private typed name/company records | A saved edit survives reload |
| Follow-ups | Private title/status/date plus customer reference | Invalid or unavailable references fail clearly |
| Activity | Scoped entries from declared record actions | One create produces the intended committed entry |
| Accounts | Project-specific visitor identity | Another visitor cannot read private rows |

## Connect every record action to the same saved state

Ask the generated application to call Uvilno.db for list, get, create, update and remove operations. Its forms should validate input before sending and preserve unsaved values when a write fails. Lists, details and calculated counters should derive from the returned records, with subscriptions refreshing active views. Those subscriptions currently poll the managed service while active; they are not a promise of WebSocket realtime delivery. A local mirror can improve continuity, but it must never be presented as proof that a server write succeeded.

Test persistence through the actual interface. Create a recognizable customer, edit one field, navigate away, reload and find the saved result. Remove a disposable record with a meaningful confirmation and verify the list and count update. Try missing required fields, a failed request and a conflicting revision. The owner’s App Data manager offers a separate view of actual collection rows without an AI generation call. Use it to corroborate the result, while remembering that the owner data manager and a generated visitor administration screen are different access paths.

Example brief:

Keep the customer routes and existing palette. Wire the Add customer drawer to Uvilno.db('customers').create, disable duplicate submission while saving, retain input on failure, and update the subscribed list only after the acknowledged operation. Test creating a customer, reloading and editing its company.

## Verify the real identity and authorization boundary

Generated-app accounts must belong to the project, independently of the Uvilno creator account. Test registration, sign-in, the signed-out state and sign-out using disposable visitors. If email confirmation is required, follow the real confirmation process rather than treating an account form as immediate approval. Preserve a clear distinction between the person building the app and the people using it. Signing into a generated app with a different provider account should never silently replace the creator’s platform session or authorize access to the builder workspace.

Then test two-account isolation: a second visitor should not see or directly obtain the first visitor's private customer records. The Guest/Member/Admin preview selector changes presentation only and can expose alternate layouts for design review; it does not change the actual app session or database authority. Team administrators, shared organizations and invitation rules require explicit server-side implementation. Do not infer those permissions from a visible management drawer, a hidden button or a client-side role value. Review the authorization model appropriate to your intended users before adding real business information.

## Add one automation whose effect you can trace

A useful first automation is a follow-up activity entry. Define the trigger and bounded action in the validated schema: when a follow-up record is created, create a scoped activity row and optionally record an in-app notification. These actions run in the original record transaction with the same ownership constraints. Failed actions roll the write back, and supported idempotent replays must not duplicate effects. This is a dependable narrow contract; it is not arbitrary uploaded code, a recursive workflow engine or an external email and scheduling service.

Open App Data and switch to Automations & Logs to inspect the installed rule and committed event metadata. Exercise the trigger once and verify the actual resulting record, not just a toast. Test a permitted failure in a disposable project to understand what the user sees when the transaction cannot complete. Keep sensitive record bodies out of public logs and remember that website version restoration does not rewind customer data. A rule change and a data migration are separate decisions, so preserve a record of the schema version and intended behavior when evolving a live product.

## Use bounded inference only when the product needs it

If the product needs a short AI summary or structured suggestion, request the managed AI connector explicitly. Uvilno.ai.ask returns real text, while Uvilno.ai.json returns parsed, bounded JSON for the app to validate. The service requires a real app visitor identity and uses the creator’s metered studio allowance, subject to admission limits and a 600-output-token response ceiling. Design the feature to fit that contract, show real loading and failure states, and avoid replacing a failed call with a hardcoded answer that appears to be genuine analysis.

Keep product claims proportional to what inference actually does. A model summary does not prove that customer facts were checked, a web page fetched or professional advice reviewed. Validate required JSON fields and explain missing or unsuitable input before saving a result. Give the visitor an explicit choice to persist generated output and keep private records private. A public website about an AI business does not need inference merely because its description contains the letters AI. Add the service for an actual product task, then measure its usage during a realistic trial.

## Keep Stripe test checkout separate from live entitlement

Add a pricing and payment flow only after the application’s core task is useful. Uvilno’s managed Stripe connector is currently in test mode. A successful test checkout can establish a test provider journey, but it is not a real charge, live recurring subscription or automatically correct account entitlement. Label the interface accordingly and avoid claims that a paying customer now has access unless a real, reviewed server workflow establishes that state. Keep product prices, fulfillment rules and failure behavior explicit rather than inferring them from a successful return page.

Before live commerce, review provider onboarding, live credentials, webhook signature verification, idempotency, payment failure, cancellation and refunds. The builder’s own $4.99 source unlock and monthly plans are separate from any prices your generated SaaS may eventually charge. Never embed secret provider keys in exported JavaScript or enter real customer card details in a disposable prototype. If live charging remains outside the supported release, omit the live action and document the remaining implementation rather than exposing a button that promises a transaction the application cannot safely complete.

- [Plan a configured Stripe integration](https://uvilno.com/guides/how-to-add-stripe-payments-without-api-keys)

## Inspect the whole journey, then plan the handoff

Use @file, @db and the selected-element context when requesting a focused refinement. Describe the current behavior, intended outcome and what must remain. Check the changed control, the next page and an unrelated nearby task after the saved result arrives. The live probe supplies bounded runtime observations, and native static projects may receive a limited free repair after a critical fault is reproduced server-side. Neither that probe nor a successful compile proves an entire application flawless. Review phone behavior, keyboard access, error recovery and the full record lifecycle with someone unfamiliar with the product.

When ready for source handoff, review the unlocked package in a clean environment and identify each hosted dependency. Uvilno’s auth, database, inference and payment services do not become independently provisioned infrastructure simply because the frontend exports. Register the final origin where necessary, continue with the supported services or implement a separate replacement, and test the actual deployment before public use. Keep private customer records and credentials out of shared archives. Finish with a maintained list of operational ownership, data retention, deletion and monitoring responsibilities so the product remains understandable after its first successful demonstration.

- [Review the export and hosting workflow](https://uvilno.com/guides/how-to-export-and-host-your-ai-website)
- [Compare full-stack builder workflows](https://uvilno.com/guides/best-full-stack-ai-app-builders-2026)

## Common questions

### Can a complete production SaaS be guaranteed in ten minutes?

No. Scope, provider behavior, verification, security requirements and operations determine the work. Start with one useful supported workflow and review the actual outcome.

### Can I change records without running the AI?

Supported owner App Data operations and generated Uvilno.db CRUD calls operate on data without a generation turn. Changing the schema or application behavior through AI is a different action.

### Does restoring a website version undo customer data?

No. Treat frontend restoration and hosted data changes separately. Review compatibility and any required migration before using an older interface against current records.
