import type { PrismaClient, SecretBackend, Prisma } from '@prisma/client'; export interface CreateSecretBackendInput { name: string; type: string; config?: Record; isDefault?: boolean; description?: string; } export interface UpdateSecretBackendInput { config?: Record; isDefault?: boolean; description?: string; } export interface ISecretBackendRepository { findAll(): Promise; findById(id: string): Promise; findByName(name: string): Promise; findDefault(): Promise; create(data: CreateSecretBackendInput): Promise; update(id: string, data: UpdateSecretBackendInput): Promise; /** * Atomically clear `isDefault` on every row except the one named, then set * the given row as default. Used by `setDefault`. */ setAsDefault(id: string): Promise; delete(id: string): Promise; /** Count secrets that still reference this backend — used to guard delete. */ countReferencingSecrets(backendId: string): Promise; } export class SecretBackendRepository implements ISecretBackendRepository { constructor(private readonly prisma: PrismaClient) {} async findAll(): Promise { return this.prisma.secretBackend.findMany({ orderBy: { name: 'asc' } }); } async findById(id: string): Promise { return this.prisma.secretBackend.findUnique({ where: { id } }); } async findByName(name: string): Promise { return this.prisma.secretBackend.findUnique({ where: { name } }); } async findDefault(): Promise { return this.prisma.secretBackend.findFirst({ where: { isDefault: true } }); } async create(data: CreateSecretBackendInput): Promise { return this.prisma.$transaction(async (tx) => { if (data.isDefault === true) { await tx.secretBackend.updateMany({ where: { isDefault: true }, data: { isDefault: false } }); } return tx.secretBackend.create({ data: { name: data.name, type: data.type, config: (data.config ?? {}) as Prisma.InputJsonValue, isDefault: data.isDefault ?? false, description: data.description ?? '', }, }); }); } async update(id: string, data: UpdateSecretBackendInput): Promise { return this.prisma.$transaction(async (tx) => { if (data.isDefault === true) { await tx.secretBackend.updateMany({ where: { isDefault: true, NOT: { id } }, data: { isDefault: false }, }); } const updateData: Prisma.SecretBackendUpdateInput = {}; if (data.config !== undefined) updateData.config = data.config as Prisma.InputJsonValue; if (data.isDefault !== undefined) updateData.isDefault = data.isDefault; if (data.description !== undefined) updateData.description = data.description; return tx.secretBackend.update({ where: { id }, data: updateData }); }); } async setAsDefault(id: string): Promise { return this.prisma.$transaction(async (tx) => { await tx.secretBackend.updateMany({ where: { isDefault: true, NOT: { id } }, data: { isDefault: false }, }); return tx.secretBackend.update({ where: { id }, data: { isDefault: true } }); }); } async delete(id: string): Promise { await this.prisma.secretBackend.delete({ where: { id } }); } async countReferencingSecrets(backendId: string): Promise { return this.prisma.secret.count({ where: { backendId } }); } }