Database

The database is the foundation of every feature in Vuesion.

Rather than treating it as an implementation detail, Vuesion starts new features by modeling the domain first. The resulting Prisma schema becomes the source from which the rest of the backend grows.

This approach keeps the application consistent as it evolves and allows generators to build upon a stable foundation.

PostgreSQL and Prisma

Vuesion uses PostgreSQL together with Prisma.

PostgreSQL provides a mature, reliable relational database, while Prisma offers a type-safe API for interacting with it.

Together they provide:

  • Type-safe database access
  • Automatic migrations
  • Generated TypeScript types
  • Excellent developer experience

Vuesion intentionally stays close to standard Prisma without introducing additional abstraction layers.

Domain-oriented schema organization

Instead of storing every model in a single schema.prisma file, Vuesion organizes the schema by domain.

Text
prisma/
├── schema/
│   ├── auth.prisma
│   ├── config.prisma
│   ├── file.prisma
│   ├── user.prisma
│   └── workspace.prisma
├── migrations/
└── seed.ts

As the application grows, this keeps related models together and makes navigating the schema significantly easier.

Each domain owns the models that belong to it.

Prisma as the foundation

One of the core ideas behind Vuesion is that the Prisma schema comes first.

A typical workflow looks like this:

Text
    Prisma schema
          │
          ▼
  Database migration
          │
          ▼
Generated Prisma Client
          │
          ▼
Backend implementation
          │
          ▼
 Application feature

Because generators build upon the Prisma models, defining the data model is usually the first implementation step of a new feature.

Relationships

Vuesion models relationships explicitly.

Foreign keys are used throughout the schema and database integrity is enforced by PostgreSQL.

Cascade rules are configured where appropriate so related records remain consistent without requiring additional application code.

The database should enforce structural integrity whenever possible.

Primary keys

Vuesion uses ULIDs as primary keys.

Unlike random UUIDs, ULIDs preserve chronological ordering while remaining globally unique.

This improves index locality inside PostgreSQL and results in more balanced B-tree indexes as new records are inserted.

ULIDs also remain URL-friendly and can be generated without requiring a database round trip.

Migrations

Database changes are managed through Prisma migrations.

Whenever the schema changes, a corresponding migration records the structural changes required by the database.

This ensures that every environment evolves through the same sequence of schema changes.

Migrations should always be committed together with the corresponding schema updates.

Generated Prisma Client

Prisma automatically generates a fully typed database client from the schema.

Services interact directly with this generated client.

No custom repository layer is required.

This keeps database access simple while still maintaining a clear separation between persistence and business logic.

Seeding

Vuesion includes a seed entry point for initializing development databases.

The seed script is intentionally left empty.

Every application has different initial data requirements, so the project does not assume demo users, sample workspaces, or example content.

Teams can populate the seed script according to their own project needs.

Deleting data

Vuesion generally performs permanent deletes.

Records are removed from the database instead of being soft deleted.

The main exception is the file domain.

Files are deleted asynchronously so that associated assets can first be removed from the external object storage before the corresponding database records disappear.

JSON columns

Vuesion does not prescribe a strict rule regarding JSON columns.

Whenever a JSON field provides the best representation of a particular problem, it should be used.

Likewise, relational models should be preferred whenever the data benefits from explicit relationships and querying capabilities.

The choice should be driven by the domain rather than by a general architectural preference.

Why this approach?

Many projects treat the database as a storage layer that is designed after the application.

Vuesion takes the opposite approach.

The data model defines the language of the domain and becomes the starting point for the rest of the implementation.

This provides:

  • A clear domain model
  • Type-safe database access
  • Predictable migrations
  • Consistent generated code
  • Simpler backend development
  • A scalable schema organization

The result is a database structure that remains understandable and maintainable as both the application and the team grow.

Next steps

Continue with Testing to learn how Vuesion verifies every layer of the application through automated tests.