Initial commit baby!

This commit is contained in:
Rich Teslow
2026-04-13 18:15:41 -07:00
parent 10e6227931
commit 6b0fc9fdf1
99 changed files with 34064 additions and 3 deletions
+53
View File
@@ -0,0 +1,53 @@
import { Pool } from 'pg';
import dotenv from 'dotenv';
dotenv.config();
export const pool = new Pool({
connectionString: process.env.DATABASE_URL,
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 5000,
});
pool.on('error', (err) => {
console.error('PostgreSQL pool error:', err);
});
export async function query<T = Record<string, unknown>>(
text: string,
params?: unknown[]
): Promise<T[]> {
const client = await pool.connect();
try {
const result = await client.query(text, params);
return result.rows as T[];
} finally {
client.release();
}
}
export async function queryOne<T = Record<string, unknown>>(
text: string,
params?: unknown[]
): Promise<T | null> {
const rows = await query<T>(text, params);
return rows[0] ?? null;
}
export async function transaction<T>(
fn: (client: import('pg').PoolClient) => Promise<T>
): Promise<T> {
const client = await pool.connect();
try {
await client.query('BEGIN');
const result = await fn(client);
await client.query('COMMIT');
return result;
} catch (err) {
await client.query('ROLLBACK');
throw err;
} finally {
client.release();
}
}
+34
View File
@@ -0,0 +1,34 @@
import { InfluxDB, WriteApi, QueryApi } from '@influxdata/influxdb-client';
const url = process.env.INFLUXDB_URL || 'http://influxdb:8086';
const token = process.env.INFLUXDB_TOKEN || '';
const org = process.env.INFLUXDB_ORG || 'mikrotik-manager';
const bucket = process.env.INFLUXDB_BUCKET || 'metrics';
let influxClient: InfluxDB | null = null;
let writeClient: WriteApi | null = null;
let queryClient: QueryApi | null = null;
export function getInfluxClient(): InfluxDB {
if (!influxClient) {
influxClient = new InfluxDB({ url, token });
}
return influxClient;
}
export function getWriteApi(): WriteApi {
if (!writeClient) {
writeClient = getInfluxClient().getWriteApi(org, bucket, 'ns');
writeClient.useDefaultTags({ source: 'mikrotik-manager' });
}
return writeClient;
}
export function getQueryApi(): QueryApi {
if (!queryClient) {
queryClient = getInfluxClient().getQueryApi(org);
}
return queryClient;
}
export { bucket, org };
+26
View File
@@ -0,0 +1,26 @@
import Redis from 'ioredis';
const redisUrl = process.env.REDIS_URL || 'redis://redis:6379';
export const redis = new Redis(redisUrl, {
maxRetriesPerRequest: null,
enableReadyCheck: false,
lazyConnect: true,
});
redis.on('error', (err) => {
console.error('Redis error:', err.message);
});
redis.on('connect', () => {
console.log('Redis connected');
});
// Separate connection for BullMQ (requires maxRetriesPerRequest: null)
export function createRedisConnection(): Redis {
return new Redis(redisUrl, {
maxRetriesPerRequest: null,
enableReadyCheck: false,
lazyConnect: true,
});
}