feat: add sequelize with postgres UTC timestamp endpoint
This commit is contained in:
parent
1365bd7644
commit
8237c6cd2a
8 changed files with 450 additions and 7 deletions
26
src/config/database.ts
Normal file
26
src/config/database.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { Sequelize } from "sequelize";
|
||||
|
||||
const dbUrl = process.env.DATABASE_URL;
|
||||
const dbHost = process.env.DB_HOST;
|
||||
const dbPort = Number(process.env.DB_PORT ?? 5432);
|
||||
const dbName = process.env.DB_NAME;
|
||||
const dbUser = process.env.DB_USER;
|
||||
const dbPassword = process.env.DB_PASSWORD;
|
||||
|
||||
let sequelize: Sequelize | null = null;
|
||||
|
||||
if (dbUrl) {
|
||||
sequelize = new Sequelize(dbUrl, {
|
||||
dialect: "postgres",
|
||||
logging: process.env.DB_LOGGING === "true" ? console.log : false,
|
||||
});
|
||||
} else if (dbHost && dbName && dbUser) {
|
||||
sequelize = new Sequelize(dbName, dbUser, dbPassword, {
|
||||
host: dbHost,
|
||||
port: dbPort,
|
||||
dialect: "postgres",
|
||||
logging: process.env.DB_LOGGING === "true" ? console.log : false,
|
||||
});
|
||||
}
|
||||
|
||||
export { sequelize };
|
||||
|
|
@ -1,7 +1,14 @@
|
|||
import { describe, it, expect } from "vitest";
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
import request from "supertest";
|
||||
import { app } from "./index.js";
|
||||
import { greeting } from "./greeting.js";
|
||||
import * as db from "./services/database.js";
|
||||
|
||||
const getUtcTimestampSpy = vi.spyOn(db, "getUtcTimestamp");
|
||||
|
||||
beforeEach(() => {
|
||||
getUtcTimestampSpy.mockReset();
|
||||
});
|
||||
|
||||
describe("greeting", () => {
|
||||
it("mentions the homelab", () => {
|
||||
|
|
@ -31,3 +38,30 @@ describe("GET /", () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /utc-time", () => {
|
||||
it("returns 503 when database is not configured", async () => {
|
||||
getUtcTimestampSpy.mockResolvedValueOnce(null);
|
||||
|
||||
const res = await request(app).get("/utc-time");
|
||||
expect(res.status).toBe(503);
|
||||
expect(res.body).toHaveProperty("error");
|
||||
});
|
||||
|
||||
it("returns UTC timestamp when database is available", async () => {
|
||||
const mockTime = "2026-01-01T00:00:00.000Z";
|
||||
getUtcTimestampSpy.mockResolvedValueOnce(mockTime);
|
||||
|
||||
const res = await request(app).get("/utc-time");
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body).toHaveProperty("utc_time", mockTime);
|
||||
});
|
||||
|
||||
it("returns 503 when database query fails", async () => {
|
||||
getUtcTimestampSpy.mockResolvedValueOnce(null);
|
||||
|
||||
const res = await request(app).get("/utc-time");
|
||||
expect(res.status).toBe(503);
|
||||
expect(res.body).toHaveProperty("error");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
10
src/index.ts
10
src/index.ts
|
|
@ -1,6 +1,7 @@
|
|||
import express from "express";
|
||||
import { hostname } from "node:os";
|
||||
import { greeting } from "./greeting.js";
|
||||
import { getUtcTimestamp } from "./services/database.js";
|
||||
|
||||
const app = express();
|
||||
const port = Number(process.env.PORT ?? 3000);
|
||||
|
|
@ -20,4 +21,13 @@ app.get("/", (_req, res) => {
|
|||
});
|
||||
});
|
||||
|
||||
app.get("/utc-time", async (_req, res) => {
|
||||
const utcTime = await getUtcTimestamp();
|
||||
if (!utcTime) {
|
||||
res.status(503).json({ error: "Database not configured or unavailable" });
|
||||
return;
|
||||
}
|
||||
res.json({ utc_time: utcTime });
|
||||
});
|
||||
|
||||
export { app, port };
|
||||
|
|
|
|||
9
src/migrations/001_create_utc_timestamp_function.sql
Normal file
9
src/migrations/001_create_utc_timestamp_function.sql
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
-- Migration: Create stored procedure to get UTC timestamp
|
||||
-- Run: psql -f 001_create_utc_timestamp_function.sql
|
||||
|
||||
CREATE OR REPLACE FUNCTION get_utc_timestamp()
|
||||
RETURNS TIMESTAMP WITH TIME ZONE AS $$
|
||||
BEGIN
|
||||
RETURN NOW();
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
15
src/services/database.ts
Normal file
15
src/services/database.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { sequelize } from "../config/database.js";
|
||||
|
||||
export async function getUtcTimestamp(): Promise<string | null> {
|
||||
if (!sequelize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const [results] = await sequelize.query("SELECT NOW() AS utc_time");
|
||||
const rows = results as { utc_time: string }[];
|
||||
return rows[0]?.utc_time ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue