Dokumenttien poisto kaikille + versioiden säilytysrajoitus

- Poisto-nappi näkyy dokumentin luojalle (ei enää vain admin)
- API: document_delete sallii poiston adminille tai luojalle
- Uusi max_versions-sarake documents-tauluun (oletus 10)
- Versioiden automaattinen pruning: uuden version tallennuksen yhteydessä
  poistetaan vanhimmat versiot jos yli max_versions (tiedostot levyltä myös)
- Valittavissa per dokumentti: 5, 10, 20, 50 tai rajaton

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 23:35:50 +02:00
parent f40b387383
commit cb52dbfabe
4 changed files with 57 additions and 6 deletions

35
db.php
View File

@@ -612,6 +612,7 @@ function initDatabase(): void {
"ALTER TABLE todos ADD COLUMN category VARCHAR(30) DEFAULT '' AFTER priority",
"ALTER TABLE user_companies ADD COLUMN role VARCHAR(20) DEFAULT 'user' AFTER company_id",
"ALTER TABLE documents ADD COLUMN folder_id VARCHAR(20) DEFAULT NULL AFTER customer_id",
"ALTER TABLE documents ADD COLUMN max_versions INT DEFAULT 10 AFTER current_version",
"ALTER TABLE document_versions ADD COLUMN content MEDIUMTEXT DEFAULT NULL AFTER mime_type",
];
foreach ($alters as $sql) {
@@ -1818,14 +1819,15 @@ function dbSaveDocument(string $companyId, array $doc): string {
$id = $doc['id'] ?? generateId();
$now = date('Y-m-d H:i:s');
_dbExecute("
INSERT INTO documents (id, company_id, customer_id, folder_id, title, description, category, current_version, created_by, luotu, muokattu, muokkaaja)
VALUES (:id, :companyId, :customerId, :folderId, :title, :description, :category, :currentVersion, :createdBy, :luotu, :muokattu, :muokkaaja)
INSERT INTO documents (id, company_id, customer_id, folder_id, title, description, category, current_version, max_versions, created_by, luotu, muokattu, muokkaaja)
VALUES (:id, :companyId, :customerId, :folderId, :title, :description, :category, :currentVersion, :maxVersions, :createdBy, :luotu, :muokattu, :muokkaaja)
ON DUPLICATE KEY UPDATE
title = VALUES(title),
description = VALUES(description),
category = VALUES(category),
customer_id = VALUES(customer_id),
folder_id = VALUES(folder_id),
max_versions = VALUES(max_versions),
muokattu = VALUES(muokattu),
muokkaaja = VALUES(muokkaaja)
", [
@@ -1837,6 +1839,7 @@ function dbSaveDocument(string $companyId, array $doc): string {
'description' => $doc['description'] ?? '',
'category' => $doc['category'] ?? 'muu',
'currentVersion' => (int)($doc['current_version'] ?? 0),
'maxVersions' => (int)($doc['max_versions'] ?? 10),
'createdBy' => $doc['created_by'] ?? '',
'luotu' => $doc['luotu'] ?? $now,
'muokattu' => $now,
@@ -1877,6 +1880,34 @@ function dbAddDocumentVersion(string $documentId, array $version): void {
_dbExecute("UPDATE documents SET current_version = ?, muokattu = ?, muokkaaja = ? WHERE id = ?", [
$nextVersion, $now, $version['created_by'] ?? '', $documentId
]);
// Versioiden pruning: poista vanhimmat jos yli max_versions
_pruneDocumentVersions($documentId);
}
function _pruneDocumentVersions(string $documentId): void {
$doc = _dbFetchOne("SELECT max_versions, company_id FROM documents WHERE id = ?", [$documentId]);
if (!$doc) return;
$maxVersions = (int)($doc['max_versions'] ?? 10);
if ($maxVersions <= 0) return; // 0 = rajaton
$versions = _dbFetchAll(
"SELECT id, version_number, filename FROM document_versions WHERE document_id = ? ORDER BY version_number DESC",
[$documentId]
);
if (count($versions) <= $maxVersions) return;
// Poista vanhimmat versiot (säilytä uusimmat $maxVersions kpl)
$toDelete = array_slice($versions, $maxVersions);
foreach ($toDelete as $v) {
// Poista tiedosto levyltä jos olemassa
if (!empty($v['filename'])) {
$filePath = DATA_DIR . '/companies/' . $doc['company_id'] . '/documents/' . $documentId . '/' . $v['filename'];
if (is_file($filePath)) unlink($filePath);
}
_dbExecute("DELETE FROM document_versions WHERE id = ?", [$v['id']]);
}
}
function dbRestoreDocumentVersion(string $documentId, string $versionId, string $user): ?int {