migrationsscript erstellt
This commit is contained in:
@@ -66,7 +66,14 @@ infra.js
|
|||||||
```bash
|
```bash
|
||||||
git clone <repo>
|
git clone <repo>
|
||||||
cd resman
|
cd resman
|
||||||
|
cd backend
|
||||||
npm install
|
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
|
🗄️ Datenbank Schema
|
||||||
@@ -88,6 +95,7 @@ CREATE TABLE resources (
|
|||||||
providername VARCHAR(255),
|
providername VARCHAR(255),
|
||||||
kosten_monat DECIMAL(10,2),
|
kosten_monat DECIMAL(10,2),
|
||||||
kosten_jahr DECIMAL(10,2),
|
kosten_jahr DECIMAL(10,2),
|
||||||
|
laufzeit_monate INT,
|
||||||
bestelldatum DATE,
|
bestelldatum DATE,
|
||||||
kuendbar_ab DATE,
|
kuendbar_ab DATE,
|
||||||
kuendigungsdatum DATE,
|
kuendigungsdatum DATE,
|
||||||
@@ -197,4 +205,3 @@ main.js → Initialisierung + Refresh
|
|||||||
DNS Requests können ohne Cache langsam sein
|
DNS Requests können ohne Cache langsam sein
|
||||||
Keine Authentifizierung im Backend
|
Keine Authentifizierung im Backend
|
||||||
Kein Rollen-/Rechtesystem
|
Kein Rollen-/Rechtesystem
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -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;
|
||||||
@@ -2,6 +2,10 @@
|
|||||||
"name": "resman",
|
"name": "resman",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node server.js",
|
||||||
|
"migrate": "node scripts/runMigrations.js"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"mysql2": "^3.6.0",
|
"mysql2": "^3.6.0",
|
||||||
|
|||||||
@@ -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
@@ -10,6 +10,7 @@ const dnsRoutes = require("./routes/dns")
|
|||||||
const pingRoutes = require("./routes/ping")
|
const pingRoutes = require("./routes/ping")
|
||||||
const ipCheck = require("./routes/ipcheck")
|
const ipCheck = require("./routes/ipcheck")
|
||||||
const subdomainRoutes = require("./routes/subdomains")
|
const subdomainRoutes = require("./routes/subdomains")
|
||||||
|
const { runMigrations } = require("./migrate");
|
||||||
|
|
||||||
const app = express();
|
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) => {
|
app.use((err, req, res, next) => {
|
||||||
console.error("GLOBAL ERROR:", err)
|
console.error("GLOBAL ERROR:", err)
|
||||||
|
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
error: "Interner Serverfehler"
|
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();
|
||||||
|
|||||||
Reference in New Issue
Block a user