fix(api): resolve Docker startup failures (secrets, Redis, Prisma)
- Pass BETTER_AUTH_SECRET through all 6 docker-compose files to API container - Fix BullModule to parse VALKEY_URL instead of VALKEY_HOST/VALKEY_PORT, matching all other Redis consumers in the codebase - Migrate Prisma encryption from removed $use() middleware to $extends() client extensions (Prisma 6.x compatibility), keeping extends PrismaClient pattern with only account and llmProviderInstance getters overridden Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { Injectable, Logger, OnModuleDestroy, OnModuleInit } from "@nestjs/common";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { VaultService } from "../vault/vault.service";
|
||||
import { registerAccountEncryptionMiddleware } from "./account-encryption.middleware";
|
||||
import { registerLlmEncryptionMiddleware } from "./llm-encryption.middleware";
|
||||
import { createAccountEncryptionExtension } from "./account-encryption.extension";
|
||||
import { createLlmEncryptionExtension } from "./llm-encryption.extension";
|
||||
|
||||
/**
|
||||
* Prisma service that manages database connection lifecycle
|
||||
@@ -11,11 +11,20 @@ import { registerLlmEncryptionMiddleware } from "./llm-encryption.middleware";
|
||||
* IMPORTANT: VaultService is required (not optional) for encryption/decryption
|
||||
* of sensitive Account tokens. It automatically falls back to AES-256-GCM when
|
||||
* OpenBao is unavailable.
|
||||
*
|
||||
* Encryption is handled via Prisma Client Extensions ($extends) on the `account`
|
||||
* and `llmProviderInstance` models. The extended client is stored in `_xClient`
|
||||
* and only those two model getters are overridden — all other models use the
|
||||
* base PrismaClient inheritance, preserving full type safety.
|
||||
*/
|
||||
@Injectable()
|
||||
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
|
||||
private readonly logger = new Logger(PrismaService.name);
|
||||
|
||||
// Extended client with encryption hooks for account + llmProviderInstance
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
private _xClient: any = null;
|
||||
|
||||
constructor(private readonly vaultService: VaultService) {
|
||||
super({
|
||||
log: process.env.NODE_ENV === "development" ? ["query", "info", "warn", "error"] : ["error"],
|
||||
@@ -30,20 +39,30 @@ export class PrismaService extends PrismaClient implements OnModuleInit, OnModul
|
||||
await this.$connect();
|
||||
this.logger.log("Database connection established");
|
||||
|
||||
// Register Account token encryption middleware
|
||||
// VaultService provides OpenBao Transit encryption with AES-256-GCM fallback
|
||||
registerAccountEncryptionMiddleware(this, this.vaultService);
|
||||
this.logger.log("Account encryption middleware registered");
|
||||
|
||||
// Register LLM provider API key encryption middleware
|
||||
registerLlmEncryptionMiddleware(this, this.vaultService);
|
||||
this.logger.log("LLM encryption middleware registered");
|
||||
// Register encryption extensions (replaces removed $use() middleware)
|
||||
this._xClient = this.$extends(createAccountEncryptionExtension(this.vaultService)).$extends(
|
||||
createLlmEncryptionExtension(this.vaultService)
|
||||
);
|
||||
this.logger.log("Encryption extensions registered (Account, LlmProviderInstance)");
|
||||
} catch (error) {
|
||||
this.logger.error("Failed to connect to database", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Override only the 2 models that need encryption hooks.
|
||||
// All other models (user, task, workspace, etc.) use base PrismaClient via inheritance.
|
||||
// Cast _xClient to PrismaClient to preserve the accessor return types for consumers.
|
||||
|
||||
override get account() {
|
||||
return this._xClient ? (this._xClient as PrismaClient).account : super.account;
|
||||
}
|
||||
|
||||
override get llmProviderInstance() {
|
||||
if (this._xClient) return (this._xClient as PrismaClient).llmProviderInstance;
|
||||
return super.llmProviderInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from database when NestJS module is destroyed
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user