feat: Configure database with Prisma and MySQL spatial support (Task 22)

- Set up MySQL 8.0+ with spatial data support (POINT SRID 4326)
- Created Prisma schema with all models (User, Report, Event, etc.)
- Added Clerk authentication support (clerk_id field)
- Configured spatial indexes on location fields for performance
- Created database migrations and applied to MySQL
- Built spatial query utilities for geographical operations
- Added database connection singleton and health checks
- Created comprehensive documentation and test scripts

Requirements: 1.1, 2.1, 3.2, 4.1
This commit is contained in:
2025-11-16 18:46:00 +00:00
parent 82a365f357
commit fc2fff5cb1
11 changed files with 1032 additions and 5 deletions

View File

@@ -1,7 +1,55 @@
/**
* Database configuration and Prisma client singleton
*/
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient({
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
});
// PrismaClient is attached to the `global` object in development to prevent
// exhausting your database connection limit.
const globalForPrisma = global as unknown as { prisma: PrismaClient };
export const prisma =
globalForPrisma.prisma ||
new PrismaClient({
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
});
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma;
}
/**
* Connect to the database
*/
export async function connectDatabase() {
try {
await prisma.$connect();
console.log('✅ Database connected successfully');
} catch (error) {
console.error('❌ Database connection failed:', error);
process.exit(1);
}
}
/**
* Disconnect from the database
*/
export async function disconnectDatabase() {
await prisma.$disconnect();
console.log('Database disconnected');
}
/**
* Health check for database connection
*/
export async function checkDatabaseHealth(): Promise<boolean> {
try {
await prisma.$queryRaw`SELECT 1`;
return true;
} catch (error) {
console.error('Database health check failed:', error);
return false;
}
}
export default prisma;