migrationsscript erstellt

This commit is contained in:
ecki
2026-04-06 18:07:00 +02:00
parent 69f94cec83
commit e4e42b0472
8 changed files with 187 additions and 6 deletions
+8 -1
View File
@@ -66,7 +66,14 @@ infra.js
```bash
git clone <repo>
cd resman
cd backend
npm install
npm run migrate
npm start
```
Beim Start des Backends werden ausstehende Migrationen automatisch ausgefuehrt.
Manuell kannst du sie jederzeit mit `npm run migrate` im `backend`-Ordner starten.
🗄️ Datenbank Schema
@@ -88,6 +95,7 @@ CREATE TABLE resources (
providername VARCHAR(255),
kosten_monat DECIMAL(10,2),
kosten_jahr DECIMAL(10,2),
laufzeit_monate INT,
bestelldatum DATE,
kuendbar_ab DATE,
kuendigungsdatum DATE,
@@ -197,4 +205,3 @@ main.js → Initialisierung + Refresh
DNS Requests können ohne Cache langsam sein
Keine Authentifizierung im Backend
Kein Rollen-/Rechtesystem
+46
View File
@@ -0,0 +1,46 @@
const db = require("./db");
const migrations = require("./migrations");
async function ensureMigrationsTable() {
await db.query(`
CREATE TABLE IF NOT EXISTS schema_migrations (
id VARCHAR(255) PRIMARY KEY,
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`);
}
async function getAppliedMigrationIds() {
const [rows] = await db.query(`
SELECT id
FROM schema_migrations
ORDER BY id ASC
`);
return new Set(rows.map((row) => row.id));
}
async function runMigrations() {
await ensureMigrationsTable();
const appliedIds = await getAppliedMigrationIds();
for (const migration of migrations) {
if (appliedIds.has(migration.id)) {
continue;
}
console.log(`Running migration ${migration.id}`);
await migration.up(db);
await db.query(
"INSERT INTO schema_migrations (id) VALUES (?)",
[migration.id]
);
}
}
module.exports = {
runMigrations,
};
@@ -0,0 +1,61 @@
module.exports = {
id: "001_create_base_schema",
async up(db) {
await db.query(`
CREATE TABLE IF NOT EXISTS resources (
id INT AUTO_INCREMENT PRIMARY KEY,
position INT,
name VARCHAR(255),
produkt VARCHAR(255),
provider VARCHAR(255),
art VARCHAR(100),
cpu VARCHAR(50),
ram VARCHAR(50),
disk VARCHAR(50),
os VARCHAR(100),
ipv6_net VARCHAR(255),
providername VARCHAR(255),
kosten_monat DECIMAL(10,2),
kosten_jahr DECIMAL(10,2),
laufzeit_monate INT,
bestelldatum DATE,
kuendbar_ab DATE,
kuendigungsdatum DATE,
status VARCHAR(50),
bemerkung TEXT
)
`);
await db.query(`
CREATE TABLE IF NOT EXISTS resource_ips (
id INT AUTO_INCREMENT PRIMARY KEY,
resource_id INT,
ip VARCHAR(100),
type VARCHAR(50),
comment VARCHAR(255)
)
`);
await db.query(`
CREATE TABLE IF NOT EXISTS domains (
id INT AUTO_INCREMENT PRIMARY KEY,
position INT,
domain_name VARCHAR(255),
provider VARCHAR(255),
ip_address VARCHAR(100),
yearly_cost DECIMAL(10,2),
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`);
await db.query(`
CREATE TABLE IF NOT EXISTS subdomains (
id INT AUTO_INCREMENT PRIMARY KEY,
domain_id INT,
subdomain VARCHAR(100),
ip_address VARCHAR(100)
)
`);
}
};
@@ -0,0 +1,26 @@
module.exports = {
id: "002_add_position_columns",
async up(db) {
await db.query(`
ALTER TABLE resources
ADD COLUMN IF NOT EXISTS position INT
`);
await db.query(`
ALTER TABLE domains
ADD COLUMN IF NOT EXISTS position INT
`);
await db.query(`
UPDATE resources
SET position = id
WHERE position IS NULL
`);
await db.query(`
UPDATE domains
SET position = id
WHERE position IS NULL
`);
}
};
+12
View File
@@ -0,0 +1,12 @@
const fs = require("fs");
const path = require("path");
const migrationsDir = __dirname;
const migrations = fs
.readdirSync(migrationsDir)
.filter((file) => file.endsWith(".js") && file !== "index.js")
.sort()
.map((file) => require(path.join(migrationsDir, file)));
module.exports = migrations;
+4
View File
@@ -2,6 +2,10 @@
"name": "resman",
"version": "1.0.0",
"main": "server.js",
"scripts": {
"start": "node server.js",
"migrate": "node scripts/runMigrations.js"
},
"dependencies": {
"express": "^4.18.2",
"mysql2": "^3.6.0",
+12
View File
@@ -0,0 +1,12 @@
const { runMigrations } = require("../migrate");
runMigrations()
.then(() => {
console.log("Migrations finished");
process.exit(0);
})
.catch((error) => {
console.error("Migration failed");
console.error(error);
process.exit(1);
});
+18 -5
View File
@@ -10,6 +10,7 @@ const dnsRoutes = require("./routes/dns")
const pingRoutes = require("./routes/ping")
const ipCheck = require("./routes/ipcheck")
const subdomainRoutes = require("./routes/subdomains")
const { runMigrations } = require("./migrate");
const app = express();
@@ -57,14 +58,26 @@ error: err.message || "Internal Server Error"
})
})
app.listen(3000, () => {
console.log("ResMan running on port 3000");
});
app.use((err, req, res, next) => {
console.error("GLOBAL ERROR:", err)
res.status(500).json({
error: "Interner Serverfehler"
})
})
})
async function bootstrap() {
try {
await runMigrations();
app.listen(3000, () => {
console.log("ResMan running on port 3000");
});
} catch (err) {
console.error("Migration startup failed");
console.error(err);
process.exit(1);
}
}
bootstrap();