Collaborative-pixel-art/backend/src/config/database.ts
2025-08-22 19:28:05 +02:00

126 lines
No EOL
3.4 KiB
TypeScript

import { createClient } from 'redis';
import pkg from 'pg';
const { Pool } = pkg;
export interface DatabaseConfig {
redis: {
url: string;
maxRetriesPerRequest: number;
};
postgres: {
host: string;
port: number;
database: string;
user: string;
password: string;
max: number;
};
}
export const databaseConfig: DatabaseConfig = {
redis: {
url: process.env.REDIS_URL || 'redis://localhost:6379',
maxRetriesPerRequest: 3,
},
postgres: {
host: process.env.POSTGRES_HOST || 'localhost',
port: parseInt(process.env.POSTGRES_PORT || '5432'),
database: process.env.POSTGRES_DB || 'gaplace',
user: process.env.POSTGRES_USER || 'gaplace',
password: process.env.POSTGRES_PASSWORD || 'password',
max: 20,
},
};
// Redis client
export const redisClient = createClient({
url: databaseConfig.redis.url,
});
redisClient.on('error', (err) => {
console.error('Redis Client Error:', err);
});
redisClient.on('connect', () => {
console.log('✅ Connected to Redis');
});
// PostgreSQL client
export const pgPool = new Pool(databaseConfig.postgres);
pgPool.on('error', (err) => {
console.error('PostgreSQL Pool Error:', err);
});
export async function initializeDatabase(): Promise<void> {
try {
// Connect to Redis
await redisClient.connect();
// Test PostgreSQL connection
const client = await pgPool.connect();
console.log('✅ Connected to PostgreSQL');
client.release();
// Create tables if they don't exist
await createTables();
} catch (error) {
console.error('❌ Database initialization failed:', error);
throw error;
}
}
async function createTables(): Promise<void> {
const client = await pgPool.connect();
try {
await client.query(`
CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE,
password_hash VARCHAR(255),
avatar_url TEXT,
is_guest BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW(),
last_seen TIMESTAMP DEFAULT NOW()
);
`);
await client.query(`
CREATE TABLE IF NOT EXISTS canvases (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(100) NOT NULL,
width INTEGER NOT NULL DEFAULT 1000,
height INTEGER NOT NULL DEFAULT 1000,
chunk_size INTEGER NOT NULL DEFAULT 64,
is_public BOOLEAN DEFAULT TRUE,
created_by UUID REFERENCES users(id),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
`);
await client.query(`
CREATE TABLE IF NOT EXISTS user_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
canvas_id UUID REFERENCES canvases(id),
session_token VARCHAR(255) UNIQUE NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
last_activity TIMESTAMP DEFAULT NOW(),
created_at TIMESTAMP DEFAULT NOW()
);
`);
await client.query(`
CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
CREATE INDEX IF NOT EXISTS idx_canvases_public ON canvases(is_public);
CREATE INDEX IF NOT EXISTS idx_sessions_active ON user_sessions(is_active, last_activity);
`);
console.log('✅ Database tables created/verified');
} finally {
client.release();
}
}