feat: require calendar title configuration

This commit is contained in:
leon
2026-10-08 00:38:57 +02:00
parent 67d5d5bb36
commit 3d1a08aa11
6 changed files with 28 additions and 2 deletions

3
.env.example Normal file
View File

@@ -0,0 +1,3 @@
# Lokale Entwicklung mit Docker Compose.
# Bei Installation über MPM den Kalendertitel in der Modul-Konfiguration setzen.
CALENDAR_TITLE=Mein Kalender

1
.gitignore vendored
View File

@@ -5,3 +5,4 @@
node_modules/
calendar-mvp-*.zip
calendar-mvp-*.sha256
.env

View File

@@ -6,6 +6,10 @@ Ein kleines, eigenständiges Kalender-Modul für MPM. Es zeigt einen Monatskalen
MPM installiert das Repository als eigenen Compose-Stack. Der App-Container läuft mit Node.js 24, stellt Port `41002` nur intern bereit und lauscht auf `0.0.0.0`. Die SQLite-Datei liegt unter `MPM_MODULE_DATA_DIR` im persistenten MPM-Modulvolume und überlebt Container- sowie Modul-Neustarts.
## Konfiguration
Der Kalendertitel wird über `CALENDAR_TITLE` gesetzt. Für lokale Entwicklung `.env.example` nach `.env` kopieren. Bei einer Installation über MPM erscheint nach der Installation die Modul-Konfiguration; dort muss der Titel gesetzt werden. MPM übergibt den Wert an den App-Container, eine `.env`-Datei im Repository ist dafür nicht nötig.
## Installation über den MPM-Marketplace
Das öffentliche Repository kann mit der verbundenen Gitea-Instanz direkt aus dem Marketplace installiert werden. `module.json`, `compose.yml` und `Dockerfile` liegen im Repository-Stamm. MPM installiert den Standard-Branch; der Start erfolgt anschließend über die Modulverwaltung.

View File

@@ -12,7 +12,10 @@ const db = new DatabaseSync(path.join(dataDirectory, manifest.id + '.sqlite'));
db.exec('CREATE TABLE IF NOT EXISTS events (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id TEXT NOT NULL, title TEXT NOT NULL CHECK(length(title)<=120), event_date TEXT NOT NULL, notes TEXT NOT NULL DEFAULT "" CHECK(length(notes)<=1000), created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP)');
const listEvents = db.prepare('SELECT id,title,event_date,notes FROM events WHERE user_id=? AND event_date>=? AND event_date<? ORDER BY event_date,title');
const insertEvent = db.prepare('INSERT INTO events(user_id,title,event_date,notes) VALUES(?,?,?,?)');
const html = fs.readFileSync(path.join(__dirname, '..', 'frontend', 'index.html'));
const calendarTitle = process.env.CALENDAR_TITLE?.trim();
if (!calendarTitle) throw new Error('CALENDAR_TITLE muss gesetzt werden');
const escapeHtml = (value) => value.replace(/[&<>"']/g, (character) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', "'": '&#39;' })[character]);
const html = fs.readFileSync(path.join(__dirname, '..', 'frontend', 'index.html'), 'utf8').replaceAll('Mein Kalender', escapeHtml(calendarTitle));
function json(res, status, value) { res.writeHead(status, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' }); res.end(JSON.stringify(value)); }
async function bodyJson(req) { let data=''; for await (const chunk of req) { data+=chunk; if(data.length>16384) throw new Error('too large'); } return JSON.parse(data||'{}'); }
const server = createModuleServer({manifest,logger,routes:async(req,res,{path:pathname,url,identity})=>{

View File

@@ -6,3 +6,5 @@ services:
expose:
- "41002"
restart: unless-stopped
environment:
CALENDAR_TITLE: "${CALENDAR_TITLE:?Set CALENDAR_TITLE in .env or MPM module configuration}"

View File

@@ -11,5 +11,18 @@
"healthcheck": "/health",
"apiVersion": "v1",
"composeFile": "compose.yml",
"appService": "app"
"appService": "app",
"configuration": [
{
"key": "CALENDAR_TITLE",
"label": "Kalendertitel",
"description": "Name, der oben in der Kalender-App angezeigt wird.",
"type": "text",
"secret": false,
"required": true,
"services": [
"app"
]
}
]
}