Willkommens-Karten, Geburtstage, Devlog-Permalinks mit OG-Vorschau, Auto-Publish
- Willkommens-Karten: gerendertes PNG (SVG → sharp) mit Avatar im Neon-Ring, Willkommens-Schriftzug und Member-Nummer; Fallback aufs bisherige Embed wenn das Rendering scheitert; Dockerfile installiert fonts-dejavu-core für die Text-Darstellung - Geburtstags-System: /geburtstag setzen|entfernen (birthdays-Tabelle), tägliche Runde ab 09:00 Europe/Berlin (Doppel-Post-Schutz über last_birthday_run), Gratulations-Embed + Tages-Rolle (wird am nächsten Morgen wieder abgeräumt); Kanal + Rolle im Community-Tab - Devlog-Permalinks: /devlogs/:id als eigene Seite (GET /api/devlogs/:id), Link-Symbol an jeder Karte, Link-kopieren-Button; der Server injiziert Open-Graph-Tags ins SPA-HTML — Devlog-Links zeigen Titel, Anriss und Bild, alle anderen Seiten bekommen Default-Tags (auch die Startseite) - Auto-Publish: maybeCrosspost() veröffentlicht Devlog-, Release-, Composer- und geplante Posts automatisch in Ankündigungs-Kanälen - brandEmbed: leere Avatar-URL crasht nicht mehr die Footer-Validierung Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -474,6 +474,25 @@ export const webAdminScopes = (userId) =>
|
||||
export const listWebAdmins = () => listWebAdminsStmt.all();
|
||||
export const deleteWebAdmin = (userId) => deleteWebAdminStmt.run(userId).changes > 0;
|
||||
|
||||
// Geburtstage: /geburtstag → morgendliche Gratulation + Tages-Rolle
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS birthdays (
|
||||
user_id TEXT PRIMARY KEY,
|
||||
username TEXT,
|
||||
day INTEGER NOT NULL,
|
||||
month INTEGER NOT NULL
|
||||
);
|
||||
`);
|
||||
const upsertBirthday = db.prepare(`
|
||||
INSERT INTO birthdays (user_id, username, day, month) VALUES (?, ?, ?, ?)
|
||||
ON CONFLICT(user_id) DO UPDATE SET username = excluded.username, day = excluded.day, month = excluded.month
|
||||
`);
|
||||
const deleteBirthdayStmt = db.prepare('DELETE FROM birthdays WHERE user_id = ?');
|
||||
const birthdaysTodayStmt = db.prepare('SELECT * FROM birthdays WHERE day = ? AND month = ?');
|
||||
export const setBirthday = (userId, username, day, month) => upsertBirthday.run(userId, username, day, month);
|
||||
export const deleteBirthday = (userId) => deleteBirthdayStmt.run(userId).changes > 0;
|
||||
export const birthdaysToday = (day, month) => birthdaysTodayStmt.all(day, month);
|
||||
|
||||
// Audit-Log: wer (Owner/Team) hat wann was im Webinterface geändert
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS audit_log (
|
||||
@@ -873,6 +892,11 @@ export function listDevlogs(limit, offset) {
|
||||
return { items: selectDevlogs.all(limit, offset), total: countDevlogsStmt.get().n };
|
||||
}
|
||||
|
||||
const getDevlogStmt = db.prepare(
|
||||
'SELECT message_id, content, author_name, posted_at, images FROM devlogs WHERE message_id = ?'
|
||||
);
|
||||
export const getDevlog = (messageId) => getDevlogStmt.get(messageId) ?? null;
|
||||
|
||||
const searchDevlogsStmt = db.prepare(`
|
||||
SELECT d.message_id, d.content, d.author_name, d.posted_at, d.images
|
||||
FROM devlogs_fts f
|
||||
|
||||
Reference in New Issue
Block a user