feat: created_at/created_by — видно время и сервис, добавивший строку

- CREATE TABLE IF NOT EXISTS дополнена колонками:
    created_at TIMESTAMPTZ NOT NULL DEFAULT now()
    created_by TEXT NOT NULL DEFAULT ''
- ALTER TABLE ... ADD COLUMN IF NOT EXISTS досыпает колонки в уже существующую
  таблицу — данные при этом не теряются;
- INSERT пишет created_by из env SERVICE_NAME (задаётся в json_env манифеста),
  created_at ставит сама СУБД;
- список записей и UI показывают обе колонки.

Зачем: три приложения (flask / lucee / nodejs) пишут в ОДНУ таблицу — теперь
сразу видно, какое из них и когда добавило строку.
This commit is contained in:
Repinoid
2026-10-01 18:37:27 +03:00
parent 25666a977f
commit 23338cbdf5
2 changed files with 26 additions and 6 deletions
+23 -5
View File
@@ -14,6 +14,9 @@ const path = require("path");
const VERSION = "1.0.0";
const TABLE_NAME = process.env.TABLE_NAME || "crud_items";
// SERVICE_NAME — какое приложение добавило строку (колонка created_by).
// Задаётся в json_env манифеста для каждого сервиса (flask / lucee / nodejs).
const SERVICE_NAME = process.env.SERVICE_NAME || "nodejs";
const PORT = process.env.PORT || 3000;
const pool = new Pool({
@@ -32,15 +35,26 @@ app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "views"));
// --- Инициализация БД ---
// Таблица выставочная: кроме id/value — две метки: created_at (когда добавлено)
// и created_by (какое приложение добавило). ALTER ... IF NOT EXISTS досыпает
// колонки в таблицу, созданную прошлой версией приложения, не теряя данные.
async function initDB() {
const client = await pool.connect();
try {
await client.query(`
CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (
id SERIAL PRIMARY KEY,
value TEXT NOT NULL DEFAULT ''
id SERIAL PRIMARY KEY,
value TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
created_by TEXT NOT NULL DEFAULT ''
)
`);
await client.query(
`ALTER TABLE ${TABLE_NAME} ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ NOT NULL DEFAULT now()`
);
await client.query(
`ALTER TABLE ${TABLE_NAME} ADD COLUMN IF NOT EXISTS created_by TEXT NOT NULL DEFAULT ''`
);
} finally {
client.release();
}
@@ -52,14 +66,14 @@ app.get("/", async (req, res) => {
let editRow = null;
if (req.query.edit) {
const result = await pool.query(
`SELECT id, value FROM ${TABLE_NAME} WHERE id = $1`,
`SELECT id, value, created_at, created_by FROM ${TABLE_NAME} WHERE id = $1`,
[parseInt(req.query.edit)]
);
if (result.rows.length > 0) editRow = result.rows[0];
}
const result = await pool.query(
`SELECT id, value FROM ${TABLE_NAME} ORDER BY id`
`SELECT id, value, created_at, created_by FROM ${TABLE_NAME} ORDER BY id`
);
res.render("index", {
@@ -78,7 +92,11 @@ app.post("/", async (req, res) => {
const { action, value, id } = req.body;
if (action === "create") {
await pool.query(`INSERT INTO ${TABLE_NAME} (value) VALUES ($1)`, [value || ""]);
// created_at ставит СУБД (DEFAULT now()), created_by — имя этого сервиса
await pool.query(
`INSERT INTO ${TABLE_NAME} (value, created_by) VALUES ($1, $2)`,
[value || "", SERVICE_NAME]
);
} else if (action === "update") {
await pool.query(`UPDATE ${TABLE_NAME} SET value = $1 WHERE id = $2`, [
value || "",