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:
@@ -14,6 +14,9 @@ const path = require("path");
|
|||||||
|
|
||||||
const VERSION = "1.0.0";
|
const VERSION = "1.0.0";
|
||||||
const TABLE_NAME = process.env.TABLE_NAME || "crud_items";
|
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 PORT = process.env.PORT || 3000;
|
||||||
|
|
||||||
const pool = new Pool({
|
const pool = new Pool({
|
||||||
@@ -32,15 +35,26 @@ app.set("view engine", "ejs");
|
|||||||
app.set("views", path.join(__dirname, "views"));
|
app.set("views", path.join(__dirname, "views"));
|
||||||
|
|
||||||
// --- Инициализация БД ---
|
// --- Инициализация БД ---
|
||||||
|
// Таблица выставочная: кроме id/value — две метки: created_at (когда добавлено)
|
||||||
|
// и created_by (какое приложение добавило). ALTER ... IF NOT EXISTS досыпает
|
||||||
|
// колонки в таблицу, созданную прошлой версией приложения, не теряя данные.
|
||||||
async function initDB() {
|
async function initDB() {
|
||||||
const client = await pool.connect();
|
const client = await pool.connect();
|
||||||
try {
|
try {
|
||||||
await client.query(`
|
await client.query(`
|
||||||
CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (
|
CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
value TEXT NOT NULL DEFAULT ''
|
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 {
|
} finally {
|
||||||
client.release();
|
client.release();
|
||||||
}
|
}
|
||||||
@@ -52,14 +66,14 @@ app.get("/", async (req, res) => {
|
|||||||
let editRow = null;
|
let editRow = null;
|
||||||
if (req.query.edit) {
|
if (req.query.edit) {
|
||||||
const result = await pool.query(
|
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)]
|
[parseInt(req.query.edit)]
|
||||||
);
|
);
|
||||||
if (result.rows.length > 0) editRow = result.rows[0];
|
if (result.rows.length > 0) editRow = result.rows[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await pool.query(
|
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", {
|
res.render("index", {
|
||||||
@@ -78,7 +92,11 @@ app.post("/", async (req, res) => {
|
|||||||
const { action, value, id } = req.body;
|
const { action, value, id } = req.body;
|
||||||
|
|
||||||
if (action === "create") {
|
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") {
|
} else if (action === "update") {
|
||||||
await pool.query(`UPDATE ${TABLE_NAME} SET value = $1 WHERE id = $2`, [
|
await pool.query(`UPDATE ${TABLE_NAME} SET value = $1 WHERE id = $2`, [
|
||||||
value || "",
|
value || "",
|
||||||
|
|||||||
+3
-1
@@ -23,7 +23,7 @@
|
|||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>ID</th><th>VALUE</th>
|
<th>ID</th><th>VALUE</th><th>ДОБАВЛЕНО</th><th>КЕМ</th>
|
||||||
<th style="text-align:center;"></th>
|
<th style="text-align:center;"></th>
|
||||||
<th style="text-align:center;"></th>
|
<th style="text-align:center;"></th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -33,6 +33,8 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><%= row.id %></td>
|
<td><%= row.id %></td>
|
||||||
<td><%= row.value %></td>
|
<td><%= row.value %></td>
|
||||||
|
<td><%= row.created_at ? new Date(row.created_at).toLocaleString('ru-RU') : '' %></td>
|
||||||
|
<td><%= row.created_by %></td>
|
||||||
<td style="text-align:center;">
|
<td style="text-align:center;">
|
||||||
<a href="/?edit=<%= row.id %>" class="btn btn-sm">✏️</a>
|
<a href="/?edit=<%= row.id %>" class="btn btn-sm">✏️</a>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user