bf7be65b03
Jenkins Production Deployment
Reviewed-on: #12 Co-authored-by: Patrick Müller <mail@pmueller.me> Co-committed-by: Patrick Müller <mail@pmueller.me>
56 lines
2.4 KiB
TypeScript
56 lines
2.4 KiB
TypeScript
import * as dotenv from 'dotenv';
|
|
import mysql from 'mysql2';
|
|
import {Kysely, MysqlDialect} from 'kysely';
|
|
import {AdminDatabase} from './admin.schema.js';
|
|
import logger from '../../middleware/logger.js';
|
|
|
|
dotenv.config();
|
|
|
|
/**
|
|
* The admin module is the one place in this API that does not use the
|
|
* `mariadb` driver: better-auth talks to the database through Kysely, whose
|
|
* MySQL dialect expects a mysql2 pool. The other domains keep their own
|
|
* `mariadb` pools (see Feedback.db.ts) - this is an addition, not a migration.
|
|
*
|
|
* The pool is the callback-style `mysql2` one, NOT `mysql2/promise`: Kysely's
|
|
* MysqlDialect calls `pool.getConnection((err, conn) => ...)`. The promise
|
|
* wrapper ignores that callback and returns a Promise instead, so every query
|
|
* through Kysely would hang forever with no error - which is exactly what it
|
|
* did until the integration tests caught it.
|
|
*
|
|
* timezone 'Z' matters: better-auth computes session and token expiry in UTC.
|
|
* Without it mysql2 would write and read those DATETIMEs in the process's local
|
|
* zone, so sessions would expire an hour early or late depending on DST.
|
|
*/
|
|
|
|
export namespace NachklangAdminDB {
|
|
export const pool = mysql.createPool({
|
|
host: process.env.DB_HOST,
|
|
user: process.env.DB_USER,
|
|
password: process.env.DB_PASSWORD,
|
|
database: process.env.ADMIN_DB,
|
|
// The other modules' pools default to 3306. This one is configurable so
|
|
// the integration tests can point at a throwaway container on another
|
|
// port without touching a developer's real .env.
|
|
port: parseInt(process.env.DB_PORT || '3306', 10),
|
|
connectionLimit: 5,
|
|
timezone: 'Z'
|
|
});
|
|
|
|
// mysql2 emits connection trouble as an event on the pool, not only as a
|
|
// rejected query. Without a listener Node turns that into an
|
|
// uncaughtException, so a database restart would take the whole API - and
|
|
// with it the calendar, feedback and tickets domains - down with it.
|
|
// Individual queries still reject, and their callers still answer 500.
|
|
pool.on('error', (err: unknown) => {
|
|
logger.error('Admin database pool error', {detail: (err as any)?.message});
|
|
});
|
|
|
|
// Handed to better-auth as `database: {dialect, type: 'mysql'}`.
|
|
export const dialect = new MysqlDialect({pool});
|
|
|
|
// Used by this module's own services for the two custom tables and for
|
|
// permission lookups that join better-auth's `user`.
|
|
export const db = new Kysely<AdminDatabase>({dialect});
|
|
}
|