Hinweise: - Neue Tabelle notices (tenant-scoped, Soft-Delete via deleted_at) loest die global unscoped kl_hinweise als aktive Datenquelle ab; Migration uebernimmt einmalig aktuell gueltige kl_hinweise-Eintraege fuer den Default-Mandanten. kl_hinweise bleibt als Golden-Master-Referenz stehen. - hinweise.php und der Banner in header.php sind tenant-scoped umgestellt. Mitgliederverwaltung: - mitarbeiterverwalten.php verwaltet jetzt participants (tenant-scoped) statt der global unscoped kl_Mitarbeiter-Tabelle als primaere Quelle. Das behebt nebenbei ein Mandanten-Datenleck: jeder SaaS-Mandant mit Owner/Admin-Rolle haette zuvor die komplette Default-Mandanten- Mitgliederliste sehen und bearbeiten koennen. - Fuer den Default-Mandanten bleibt Dual-Write nach kl_Mitarbeiter bestehen, damit stricheintragen.php/einzahlung.php weiter funktionieren; andere Mandanten werden rein participant-nativ verwaltet. - Die Legacy-Administrator-Checkbox ist raus. Stattdessen kann ein Admin je Mitglied unabhaengig von Name/E-Mail einen Login-Zugang mit Rolle (member/treasurer/admin) gewaehren oder entziehen (saas_grant_participant_access / saas_revoke_participant_access). Einladung laeuft ueber den bestehenden Passwort-Reset-Mechanismus, Entzug setzt die Mitgliedschaft auf revoked statt sie zu loeschen. - Kompletter Flow live getestet: anlegen, Zugang gewaehren, Einladungsmail, Passwort setzen, Login, Rollenschutz, Zugang entziehen, Login-Sperre. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
73 lines
1.8 KiB
PHP
73 lines
1.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/bootstrap.php';
|
|
|
|
/**
|
|
* @return array{id: int, message: string, valid_from: string, valid_until: string}|null
|
|
*/
|
|
function notices_fetch_active(PDO $pdo, int $tenantId): ?array
|
|
{
|
|
$stmt = $pdo->prepare(
|
|
"SELECT id, message, valid_from, valid_until
|
|
FROM notices
|
|
WHERE tenant_id = ?
|
|
AND deleted_at IS NULL
|
|
AND valid_from <= NOW()
|
|
AND valid_until >= NOW()
|
|
ORDER BY valid_until ASC
|
|
LIMIT 1"
|
|
);
|
|
$stmt->execute([$tenantId]);
|
|
$row = $stmt->fetch();
|
|
|
|
return $row !== false ? $row : null;
|
|
}
|
|
|
|
/**
|
|
* @return list<array{id: int, message: string, valid_from: string, valid_until: string}>
|
|
*/
|
|
function notices_fetch_all(PDO $pdo, int $tenantId): array
|
|
{
|
|
$stmt = $pdo->prepare(
|
|
"SELECT id, message, valid_from, valid_until
|
|
FROM notices
|
|
WHERE tenant_id = ?
|
|
AND deleted_at IS NULL
|
|
ORDER BY valid_until DESC"
|
|
);
|
|
$stmt->execute([$tenantId]);
|
|
|
|
return $stmt->fetchAll();
|
|
}
|
|
|
|
function notices_create(PDO $pdo, int $tenantId, string $message, string $validUntil, ?int $createdByUserId): bool
|
|
{
|
|
$message = trim($message);
|
|
if ($message === '' || $validUntil === '') {
|
|
return false;
|
|
}
|
|
|
|
$stmt = $pdo->prepare(
|
|
'INSERT INTO notices (tenant_id, message, valid_from, valid_until, created_by_user_id)
|
|
VALUES (?, ?, NOW(), ?, ?)'
|
|
);
|
|
|
|
return $stmt->execute([$tenantId, $message, $validUntil, $createdByUserId]);
|
|
}
|
|
|
|
function notices_soft_delete(PDO $pdo, int $tenantId, int $noticeId): bool
|
|
{
|
|
$stmt = $pdo->prepare(
|
|
'UPDATE notices
|
|
SET deleted_at = NOW()
|
|
WHERE id = ?
|
|
AND tenant_id = ?
|
|
AND deleted_at IS NULL'
|
|
);
|
|
$stmt->execute([$noticeId, $tenantId]);
|
|
|
|
return $stmt->rowCount() > 0;
|
|
}
|