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:
8
api.php
8
api.php
@@ -4283,7 +4283,7 @@ switch ($action) {
|
||||
break;
|
||||
|
||||
case 'document_delete':
|
||||
requireAdmin();
|
||||
requireAuth();
|
||||
$companyId = requireCompany();
|
||||
if ($method !== 'POST') break;
|
||||
try {
|
||||
@@ -4295,6 +4295,12 @@ switch ($action) {
|
||||
echo json_encode(['error' => 'Dokumenttia ei löytynyt']);
|
||||
break;
|
||||
}
|
||||
// Salli poisto adminille tai dokumentin luojalle
|
||||
if (!isCompanyAdmin() && $doc['created_by'] !== currentUser()) {
|
||||
http_response_code(403);
|
||||
echo json_encode(['error' => 'Ei oikeutta poistaa']);
|
||||
break;
|
||||
}
|
||||
// Poista tiedostot levyltä
|
||||
$docDir = DATA_DIR . '/companies/' . $companyId . '/documents/' . $docId;
|
||||
if (is_dir($docDir)) {
|
||||
|
||||
35
db.php
35
db.php
@@ -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 {
|
||||
|
||||
10
index.html
10
index.html
@@ -894,6 +894,16 @@
|
||||
<label>Tiedosto</label>
|
||||
<input type="file" id="doc-edit-file">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Versioita säilytetään</label>
|
||||
<select id="doc-edit-max-versions">
|
||||
<option value="5">5 versiota</option>
|
||||
<option value="10" selected>10 versiota</option>
|
||||
<option value="20">20 versiota</option>
|
||||
<option value="50">50 versiota</option>
|
||||
<option value="0">Rajaton</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group full-width" id="doc-edit-desc-group">
|
||||
<label>Kuvaus</label>
|
||||
<textarea id="doc-edit-description" rows="3" placeholder="Dokumentin kuvaus..."></textarea>
|
||||
|
||||
10
script.js
10
script.js
@@ -4970,7 +4970,8 @@ function renderDocReadView() {
|
||||
document.getElementById('doc-read-title').textContent = d.title || '';
|
||||
document.getElementById('doc-read-customer').textContent = '👤 ' + customerName;
|
||||
document.getElementById('doc-read-category').innerHTML = `<span class="doc-category cat-${d.category || 'muu'}">${docCategoryLabels[d.category] || d.category || 'Muu'}</span>`;
|
||||
document.getElementById('doc-read-version').textContent = `📌 Versio ${d.current_version || 0}`;
|
||||
const maxV = (d.max_versions && d.max_versions > 0) ? d.max_versions : '∞';
|
||||
document.getElementById('doc-read-version').textContent = `📌 Versio ${d.current_version || 0} (max ${maxV})`;
|
||||
document.getElementById('doc-read-date').textContent = d.muokattu ? '📅 ' + new Date(d.muokattu).toLocaleDateString('fi-FI') : '';
|
||||
const isMeeting = d.category === 'kokousmuistio';
|
||||
|
||||
@@ -4981,9 +4982,10 @@ function renderDocReadView() {
|
||||
document.getElementById('doc-read-description').textContent = d.description || '';
|
||||
}
|
||||
|
||||
// Admin-napit
|
||||
// Poista-nappi: näytetään adminille tai dokumentin luojalle
|
||||
const isAdmin = isCurrentUserAdmin();
|
||||
document.getElementById('btn-doc-delete').style.display = isAdmin ? '' : 'none';
|
||||
const isOwner = d.created_by === (currentUser?.username || '');
|
||||
document.getElementById('btn-doc-delete').style.display = (isAdmin || isOwner) ? '' : 'none';
|
||||
|
||||
// Kokousmuistio vs tiedostopohjainen
|
||||
const contentSection = document.getElementById('doc-read-content-section');
|
||||
@@ -5162,6 +5164,7 @@ function openDocEdit(doc, forceCategory, forceCustomerId) {
|
||||
const cat = forceCategory || doc?.category || 'muu';
|
||||
document.getElementById('doc-edit-category').value = cat;
|
||||
document.getElementById('doc-edit-folder-id').value = doc?.folder_id || currentDocFolderId || '';
|
||||
document.getElementById('doc-edit-max-versions').value = doc?.max_versions ?? 10;
|
||||
|
||||
const isMeeting = cat === 'kokousmuistio';
|
||||
document.getElementById('doc-edit-title').textContent = doc
|
||||
@@ -5227,6 +5230,7 @@ document.getElementById('doc-edit-form')?.addEventListener('submit', async (e) =
|
||||
category: cat,
|
||||
customer_id: document.getElementById('doc-edit-customer').value || null,
|
||||
folder_id: document.getElementById('doc-edit-folder-id').value || null,
|
||||
max_versions: parseInt(document.getElementById('doc-edit-max-versions').value) || 10,
|
||||
created_by: currentUser?.username || ''
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user