Add segmented GVL reference data maintenance

Dieser Commit ist enthalten in:
2026-06-10 20:35:27 +02:00
Ursprung d0dc1978e4
Commit 61a20c424c
6 geänderte Dateien mit 180 neuen und 22 gelöschten Zeilen
+10
Datei anzeigen
@@ -125,6 +125,10 @@ async function handleVendorGetMessage(message, sender) {
return handlePurgeUnlockedEvidenceRecordsMessage(); return handlePurgeUnlockedEvidenceRecordsMessage();
} }
if (message.type === "purge_gvl_reference_data") {
return handlePurgeGvlReferenceDataMessage();
}
if (message.type === "delete_all_evidence_database") { if (message.type === "delete_all_evidence_database") {
return handleDeleteAllEvidenceDatabaseMessage(); return handleDeleteAllEvidenceDatabaseMessage();
} }
@@ -1225,6 +1229,12 @@ async function handlePurgeUnlockedEvidenceRecordsMessage() {
return purgeUnlockedEvidenceRecords(db); return purgeUnlockedEvidenceRecords(db);
} }
async function handlePurgeGvlReferenceDataMessage() {
const db = await openVendorGetDb();
return purgeGvlReferenceData(db);
}
function handleDeleteAllEvidenceDatabaseMessage() { function handleDeleteAllEvidenceDatabaseMessage() {
return deleteVendorGetDatabase(); return deleteVendorGetDatabase();
} }
+13
Datei anzeigen
@@ -33,3 +33,16 @@ const VENDORGET_EVIDENCE_STORE_NAMES = [
VENDORGET_STORE_NAMES.gvlDataCategories, VENDORGET_STORE_NAMES.gvlDataCategories,
VENDORGET_STORE_NAMES.gvlVendorRelationships VENDORGET_STORE_NAMES.gvlVendorRelationships
]; ];
const VENDORGET_GVL_REFERENCE_STORE_NAMES = [
VENDORGET_STORE_NAMES.gvlRawEvidence,
VENDORGET_STORE_NAMES.gvlSnapshots,
VENDORGET_STORE_NAMES.gvlSnapshotEvents,
VENDORGET_STORE_NAMES.gvlVendors,
VENDORGET_STORE_NAMES.gvlPurposes,
VENDORGET_STORE_NAMES.gvlSpecialPurposes,
VENDORGET_STORE_NAMES.gvlFeatures,
VENDORGET_STORE_NAMES.gvlSpecialFeatures,
VENDORGET_STORE_NAMES.gvlDataCategories,
VENDORGET_STORE_NAMES.gvlVendorRelationships
];
+26
Datei anzeigen
@@ -89,6 +89,32 @@ async function purgeUnlockedEvidenceRecords(db) {
}); });
} }
function purgeGvlReferenceData(db) {
return new Promise((resolve, reject) => {
const clearedStores = {};
const tx = db.transaction(VENDORGET_GVL_REFERENCE_STORE_NAMES, "readwrite");
tx.onerror = () => reject(tx.error);
tx.onabort = () => reject(tx.error);
tx.oncomplete = () => {
resolve({
success: true,
clearedStores
});
};
for (const storeName of VENDORGET_GVL_REFERENCE_STORE_NAMES) {
const objectStore = tx.objectStore(storeName);
const countRequest = objectStore.count();
countRequest.onsuccess = () => {
clearedStores[storeName] = countRequest.result;
objectStore.clear();
};
}
});
}
function buildGvlWorkspaceProtectionIndex(db) { function buildGvlWorkspaceProtectionIndex(db) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const protectedSnapshotSha256 = new Set(); const protectedSnapshotSha256 = new Set();
@@ -27,6 +27,7 @@ body {
h1, h1,
h2, h2,
h3, h3,
h4,
p { p {
margin: 0; margin: 0;
} }
@@ -47,6 +48,11 @@ h3 {
color: #e5edf5; color: #e5edf5;
} }
h4 {
font-size: 13px;
color: #e5edf5;
}
p { p {
max-width: 760px; max-width: 760px;
font-size: 13px; font-size: 13px;
@@ -87,6 +93,15 @@ p {
background: #1f2937; background: #1f2937;
} }
.segment-action {
display: grid;
gap: 8px;
padding: 10px;
border: 1px solid #475569;
border-radius: 4px;
background: #172033;
}
.segment-status { .segment-status {
width: fit-content; width: fit-content;
max-width: 100%; max-width: 100%;
@@ -98,6 +113,23 @@ p {
background: #172033; background: #172033;
} }
button {
width: fit-content;
max-width: 100%;
padding: 8px 10px;
border: 1px solid #475569;
border-radius: 4px;
font: inherit;
font-size: 13px;
color: #e5edf5;
background: #1f2937;
}
button:disabled {
cursor: default;
opacity: 0.65;
}
.danger-panel { .danger-panel {
border-bottom: 0; border-bottom: 0;
} }
+30 -22
Datei anzeigen
@@ -12,44 +12,55 @@
<a class="back-link" href="../dashboard/dashboard.html">Zurück zum Observe-Dashboard</a> <a class="back-link" href="../dashboard/dashboard.html">Zurück zum Observe-Dashboard</a>
<h1>Datenpflege</h1> <h1>Datenpflege</h1>
<p class="section-help"> <p class="section-help">
Diese Ansicht bereitet die künftige segmentierte Verwaltung lokaler Lokale Datenbestände verwalten und bereinigen.
VG-Observe-Datenbestände vor. Aktuell werden keine Datenoperationen
ausgeführt.
</p> </p>
</header> </header>
<section class="panel" aria-labelledby="segments-title"> <section class="panel" aria-labelledby="segments-title">
<h2 id="segments-title">Geplante Pflegebereiche</h2> <h2 id="segments-title">Datenbereiche</h2>
<div class="segment-grid"> <div class="segment-grid">
<article class="segment-card"> <article class="segment-card">
<h3>GVL-Referenzdaten</h3> <h3>GVL-Referenzdaten</h3>
<p> <p>
Referenzdaten der Browser-Datenbank. Enthält Vendorlisten, Vendorlisten, Revisionen und GVL-Referenzbestände.
Revisionen und zugehörige Referenzbestände.
</p> </p>
<p class="segment-status"> <div class="segment-action">
Noch keine segmentierte Datenpflege implementiert. <h4>GVL-Referenzdaten bereinigen</h4>
<p>
Entfernt lokale GVL-Referenzdaten aus der Browser-Datenbank.
Consent-Daten, Request-Beobachtungen und Analyse-Daten bleiben
unberührt.
</p>
<button id="purge-gvl-reference-data-button" type="button">
GVL-Referenzdaten bereinigen
</button>
</div>
<p
id="gvl-reference-maintenance-status"
class="segment-status"
aria-live="polite"
>
Bereit.
</p> </p>
</article> </article>
<article class="segment-card"> <article class="segment-card">
<h3>Consent-Daten</h3> <h3>Consent-Daten</h3>
<p> <p>
Dokumentierte Consent-Zustände und zugehörige Ereignisse. Consent-Zustände und Ereignisse.
</p> </p>
<p class="segment-status"> <p class="segment-status">
Noch keine segmentierte Datenpflege implementiert. Noch nicht verfügbar.
</p> </p>
</article> </article>
<article class="segment-card"> <article class="segment-card">
<h3>Analyse-Daten</h3> <h3>Analyse-Daten</h3>
<p> <p>
Vorbereitete Arbeits- und Auswertungsdaten zukünftiger Analyse- und Arbeitsdaten.
Analysefunktionen.
</p> </p>
<p class="segment-status"> <p class="segment-status">
Noch keine segmentierte Datenpflege implementiert. Noch nicht verfügbar.
</p> </p>
</article> </article>
@@ -59,7 +70,7 @@
Reserviert für zukünftige Erweiterungen. Reserviert für zukünftige Erweiterungen.
</p> </p>
<p class="segment-status"> <p class="segment-status">
Noch keine segmentierte Datenpflege implementiert. Noch nicht verfügbar.
</p> </p>
</article> </article>
</div> </div>
@@ -68,20 +79,17 @@
<section class="panel danger-panel" aria-labelledby="danger-title"> <section class="panel danger-panel" aria-labelledby="danger-title">
<h2 id="danger-title">Gefahrenbereich</h2> <h2 id="danger-title">Gefahrenbereich</h2>
<p class="section-help"> <p class="section-help">
Hier werden später irreversible Verwaltungsaktionen gebündelt. Diese Irreversible Aktionen für den gesamten lokalen Datenbestand.
Aktionen betreffen den lokalen VG-Observe-Datenbestand und erfordern
eine ausdrückliche Sicherheitsbestätigung.
</p> </p>
<article class="danger-action" aria-label="Vorbereitete Gefahrenaktion"> <article class="danger-action" aria-label="Vorbereitete Gefahrenaktion">
<h3>Gesamten lokalen VG-Observe-Datenbestand löschen</h3> <h3>Gesamten lokalen Datenbestand löschen</h3>
<p class="segment-status">Noch nicht implementiert.</p> <p class="segment-status">Noch nicht verfügbar.</p>
<p> <p>
Vor einer späteren Umsetzung muss klar angezeigt werden, welche Erfordert später eine ausdrückliche Sicherheitsbestätigung.
Datenbereiche betroffen sind. Die Ausführung darf nur nach
ausdrücklicher Sicherheitsabfrage erfolgen.
</p> </p>
</article> </article>
</section> </section>
</main> </main>
<script src="data-maintenance.js"></script>
</body> </body>
</html> </html>
@@ -0,0 +1,69 @@
"use strict";
const purgeGvlReferenceDataButton = document.getElementById(
"purge-gvl-reference-data-button"
);
const gvlReferenceMaintenanceStatus = document.getElementById(
"gvl-reference-maintenance-status"
);
document.addEventListener("DOMContentLoaded", () => {
purgeGvlReferenceDataButton?.addEventListener("click", async () => {
await purgeGvlReferenceData();
});
});
async function purgeGvlReferenceData() {
if (!confirm(buildGvlReferenceDataPurgeConfirmationText())) {
renderGvlReferenceMaintenanceStatus("Abgebrochen.");
return;
}
purgeGvlReferenceDataButton.disabled = true;
renderGvlReferenceMaintenanceStatus("GVL-Referenzdaten werden bereinigt...");
try {
const result = await browser.runtime.sendMessage({
type: "purge_gvl_reference_data"
});
if (!result?.success) {
throw new Error(result?.error ?? "purge_gvl_reference_data_failed");
}
renderGvlReferenceMaintenanceStatus(
buildGvlReferenceDataPurgeSuccessMessage(result)
);
} catch (error) {
renderGvlReferenceMaintenanceStatus(
"GVL-Referenzdaten konnten nicht bereinigt werden."
);
console.warn("VG-Observe GVL reference data purge failed", error);
} finally {
purgeGvlReferenceDataButton.disabled = false;
}
}
function buildGvlReferenceDataPurgeConfirmationText() {
return [
"GVL-Referenzdaten bereinigen?",
"",
"Betroffen: GVL-Referenzdaten der Browser-DB.",
"Nicht betroffen: Consent-Daten, Request-Beobachtungen, Analyse-Daten.",
"",
"Diese Aktion entfernt lokale GVL-Referenzdaten aus der Browser-Datenbank."
].join("\n");
}
function buildGvlReferenceDataPurgeSuccessMessage(result) {
const clearedCount = Object.values(result.clearedStores ?? {}).reduce(
(total, count) => total + Number(count ?? 0),
0
);
return `GVL-Referenzdaten bereinigt: ${clearedCount} Records entfernt.`;
}
function renderGvlReferenceMaintenanceStatus(message) {
gvlReferenceMaintenanceStatus.textContent = message;
}