2.4 KiB
2.4 KiB
Multi-Tenant Migration Guide
Overview
This guide walks you through migrating existing services from the single-database architecture to the new multi-database per-tenant architecture.
Architecture Comparison
Before (Single Database)
// Single Prisma client, data segregated by tenantId column
@Injectable()
export class UserService {
constructor(private prisma: PrismaService) {}
async findUserByEmail(tenantId: string, email: string) {
return this.prisma.user.findFirst({
where: { tenantId, email },
});
}
}
After (Multi-Database)
// Dynamic Knex connection per tenant, complete database isolation
@Injectable()
export class UserService {
constructor(private tenantDb: TenantDatabaseService) {}
async findUserByEmail(tenantId: string, email: string) {
const knex = await this.tenantDb.getTenantKnex(tenantId);
return User.query(knex).findOne({ email });
}
}
Step-by-Step Service Migration Examples
See full examples in the file for:
- AuthService migration
- RBACService migration
- ObjectService migration
- Controller updates
- Common query patterns
- Testing strategies
Quick Reference
Query Patterns
Simple Query
// Prisma
const user = await this.prisma.user.findUnique({ where: { tenantId, id } });
// Objection
const knex = await this.tenantDb.getTenantKnex(tenantId);
const user = await User.query(knex).findById(id);
Query with Relations
// Prisma
const user = await this.prisma.user.findUnique({
where: { tenantId, id },
include: { roles: { include: { permissions: true } } },
});
// Objection
const user = await User.query(knex)
.findById(id)
.withGraphFetched("roles.permissions");
Create
// Prisma
const user = await this.prisma.user.create({ data: { ... } });
// Objection
const user = await User.query(knex).insert({ ... });
Update
// Prisma
const user = await this.prisma.user.update({ where: { id }, data: { ... } });
// Objection
const user = await User.query(knex).patchAndFetchById(id, { ... });
Delete
// Prisma
await this.prisma.user.delete({ where: { id } });
// Objection
await User.query(knex).deleteById(id);
Resources
- Knex.js Documentation
- Objection.js Documentation
- MULTI_TENANT_IMPLEMENTATION.md - Full implementation details