Data Layer
Data Layer
Section titled “Data Layer”Current Data Layer Summary
Section titled “Current Data Layer Summary”The new backend currently uses Prisma as the clearest active persistence layer and appears to be built against an existing MySQL schema rather than a greenfield database design.
This is an important architectural fact:
- the backend is modern in framework and typing
- but the data layer is integrating with an already-existing legacy-style relational schema
Primary Persistence Technology
Section titled “Primary Persistence Technology”The backend currently includes:
- Prisma schema definitions under
prisma/ - Prisma client generation scripts
- Prisma migrations workflow commands
- Prisma seeding support
- a Prisma module and Prisma service under
src/database
This indicates Prisma is the primary data access foundation for the new backend.
Core Data Layer Components
Section titled “Core Data Layer Components”The most important current files are:
backend/prisma/schema.prismabackend/prisma/seed.tsbackend/prisma/seeders/consultants.seeder.tsbackend/prisma/seeders/customers.seeder.tsbackend/src/database/prisma.module.tsbackend/src/database/prisma.service.ts
Datasource Design
Section titled “Datasource Design”The Prisma datasource is configured as:
- provider:
mysql - connection source:
DATABASE_URL - shadow database source:
SHADOW_DATABASE_URL
This means the backend is built around MySQL-compatible persistence and is prepared for migration workflows that require a shadow database.
Prisma Client Integration
Section titled “Prisma Client Integration”The PrismaService extends PrismaClient and integrates with the Nest lifecycle.
It currently provides:
- connect-on-module-init behavior
- disconnect-on-module-destroy behavior
- a simple database health-check query
- logging for connection events
Because PrismaModule is marked @Global(), Prisma is effectively the shared database gateway for all feature modules.
Schema Style
Section titled “Schema Style”The Prisma schema is not modeling a simple new domain from scratch. It is mapping into an existing database with many legacy conventions.
The strongest signals are:
- table names remain legacy and pluralized
- column names are mapped with
@map - many models use uppercase legacy database columns such as
Customer_ID,TimeStamp, orCreated_at - enums mirror operational business states from the existing system
Examples from the schema:
customers.customer_idmaps toCustomer_IDconsultants.order_in_listmaps toOrder_In_Listcustomers.verified_statusmaps toVerified_Status
This tells us Prisma is being used as a typed integration layer over an existing schema, not as the original source of naming conventions.
Relationship Modeling Pattern
Section titled “Relationship Modeling Pattern”A very important characteristic of the current data layer is that many models appear flat from Prisma’s perspective.
The schema contains many integer reference fields such as:
Customer_IDConsultant_IDBranch_IDCategory_IDOrder_ID
However, many of these are not yet modeled with rich Prisma relations.
Practical implication
Section titled “Practical implication”The backend currently relies heavily on:
- scalar foreign-key-style fields
- manual querying by ID
- service-level orchestration of joins and lookups
instead of deeply relational Prisma model traversal.
This makes sense when integrating into a large existing database, but it also means:
- domain relationships are still encoded primarily in naming and service logic
- not all data integrity meaning is expressed directly in Prisma relations
Current Domain Coverage in Prisma
Section titled “Current Domain Coverage in Prisma”The Prisma schema already includes a broad set of mapped models, including:
- customers
- consultants
- appointments
- articles
- branches
- careers and career applications
- collections and courses
- configuration settings
- consultant contracts and schedules
- content and engagement tables
This indicates that the new backend is already wired into a large cross-domain persistence surface, even if only part of it is currently exposed through active Nest modules.
Active Access Patterns in Services
Section titled “Active Access Patterns in Services”The currently visible services show a simple and pragmatic access pattern.
Reference service
Section titled “Reference service”The reference service reads from:
consultations_categoriesservices_categories
It then maps those rows into API response objects, including media URL composition using CONTENT_URL.
Consultants service
Section titled “Consultants service”The consultants service reads from:
consultants
It uses:
- pagination helpers
- selective field projection
- explicit
findUniqueaccess byid - translation-aware not-found errors
Auth service
Section titled “Auth service”The auth service uses Prisma heavily across:
customersconsultantsconsultations_ordersconsultant_contract- token and OTP-related persistence
This is the richest currently visible example of business logic composed directly on top of Prisma queries.
Persistence Strategy in Auth
Section titled “Persistence Strategy in Auth”The auth domain provides the clearest view of how the backend currently thinks about persistence.
It combines:
- persistence-layer types
- branded domain-level ID types
- token payload mappers
- profile mappers for database records
This indicates an attempt to separate:
- database record structure
- domain semantics
- token and session semantics
even though all of them still sit fairly close together in the auth module.
Typed Mapping Layer
Section titled “Typed Mapping Layer”The auth module includes mappers and branded types that sit between raw Prisma rows and application-level behavior.
Examples include:
mapCustomerToProfilecreateTokenPayload- branded types such as
UserId,ConsultantId, andDeviceToken
This is a good sign that the backend is moving toward clearer domain boundaries rather than passing raw database shapes everywhere.
Seeding Strategy
Section titled “Seeding Strategy”The backend already includes a seed pipeline through:
npm run seedbackend/prisma/seed.ts
The current seed behavior focuses especially on:
- customers
- consultants
- auth-related and consultant-eligibility scenarios
The consultant seeder is particularly valuable because it does not only create demo rows. It creates realistic state combinations such as:
- eligible consultant
- disabled customer
- disabled consultant
- pending order
- missing contract
- expired contract
- missing license
- expired license
- missing order
This indicates the seeding layer is being used as a domain-scenario tool for development and testing, not only as static fixture loading.
Migration Direction
Section titled “Migration Direction”The backend package exposes Prisma commands for:
- generate
- migrate
- deploy
- reset
- studio
- db pull
This suggests the intended data workflow is:
- define or update Prisma schema
- generate Prisma client
- run migration workflows
- seed development data when useful
At the same time, the presence of schema-existing-stg.prisma suggests the team is also working against an already-existing staging schema and may be reconciling legacy and new database representations.
Mixed ORM Signal
Section titled “Mixed ORM Signal”The backend dependencies still include TypeORM, but the actively visible data workflow is Prisma-first.
This creates an important interpretation:
- Prisma is the practical current data layer
- TypeORM may be transitional, planned, or legacy dependency carry-over
Until TypeORM is proven active in module code, Prisma should be treated as the real persistence standard for this backend.
Strengths of the Current Data Layer
Section titled “Strengths of the Current Data Layer”The current data layer already has several strengths:
- type-safe database access
- migration-driven schema management
- seedable development environments
- explicit service-level database usage through NestJS modules
It also provides a clear path away from direct SQL embedded in application logic.
Current Tradeoffs
Section titled “Current Tradeoffs”The current implementation also shows some tradeoffs:
- Prisma is integrating with a complex pre-existing schema, so naming is less clean than a greenfield model
- many relations are still represented as scalar IDs rather than explicit relational graphs
- service modules may need to manually compose cross-table logic
- domain boundaries at the persistence level are improving, but not fully abstracted yet
Recommended Documentation Framing
Section titled “Recommended Documentation Framing”For documentation purposes, the current data layer should be described as:
- Prisma-backed
- MySQL-based
- legacy-schema-integrated
- service-composed rather than deeply relation-driven
- already capable of typed queries, seeded scenarios, and migration workflows
This is the most accurate description of the backend data layer today.