Files
stack/apps/api/src/prisma/prisma.service.ts
Jason Woltje c221b63d14
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
fix: Resolve CI typecheck failures and improve type safety
Fixes CI pipeline failures caused by missing Prisma Client generation and TypeScript type safety issues. Added Prisma generation step to CI pipeline, installed missing type dependencies, and resolved 40+ exactOptionalPropertyTypes violations across service layer.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-30 20:39:03 -06:00

83 lines
2.2 KiB
TypeScript

import { Injectable, Logger, OnModuleDestroy, OnModuleInit } from "@nestjs/common";
import { PrismaClient } from "@prisma/client";
/**
* Prisma service that manages database connection lifecycle
* Extends PrismaClient to provide connection management and health checks
*/
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
private readonly logger = new Logger(PrismaService.name);
constructor() {
super({
log: process.env.NODE_ENV === "development" ? ["query", "info", "warn", "error"] : ["error"],
});
}
/**
* Connect to database when NestJS module initializes
*/
async onModuleInit() {
try {
await this.$connect();
this.logger.log("Database connection established");
} catch (error) {
this.logger.error("Failed to connect to database", error);
throw error;
}
}
/**
* Disconnect from database when NestJS module is destroyed
*/
async onModuleDestroy() {
await this.$disconnect();
this.logger.log("Database connection closed");
}
/**
* Health check for database connectivity
* @returns true if database is accessible, false otherwise
*/
async isHealthy(): Promise<boolean> {
try {
await this.$queryRaw`SELECT 1`;
return true;
} catch (error) {
this.logger.error("Database health check failed", error);
return false;
}
}
/**
* Get database connection info for debugging
* @returns Connection status and basic info
*/
async getConnectionInfo(): Promise<{
connected: boolean;
database?: string;
version?: string;
}> {
try {
const result = await this.$queryRaw<{ current_database: string; version: string }[]>`
SELECT current_database(), version()
`;
if (result.length > 0 && result[0]) {
const dbVersion = result[0].version.split(" ")[0];
return {
connected: true,
database: result[0].current_database,
...(dbVersion && { version: dbVersion }),
};
}
return { connected: false };
} catch (error) {
this.logger.error("Failed to get connection info", error);
return { connected: false };
}
}
}