feat(repositories): Add SocialMediaRepository and extend GroupRepository
- Create new SocialMediaRepository for platform and consent management - getAllPlatforms(), getActivePlatforms() - createPlatform(), updatePlatform(), togglePlatformStatus() - saveConsents(), getConsentsForGroup(), getGroupIdsByConsentStatus() - revokeConsent(), restoreConsent(), hasActiveConsent() - Extend GroupRepository with consent management methods - createGroupWithConsent() - create group with workshop & social media consents - getGroupWithConsents() - retrieve group with all consent data - updateConsents() - update consent preferences - getGroupsByConsentStatus() - filter groups by consent status - exportConsentData() - export for legal documentation - generateManagementToken(), getGroupByManagementToken() (Phase 2) - Both repositories work together seamlessly via transactions
This commit is contained in:
parent
8dc5a03584
commit
ff2ea310ed
|
|
@ -505,6 +505,288 @@ class GroupRepository {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Consent Management Methods
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erstelle neue Gruppe mit Consent-Daten
|
||||||
|
* @param {Object} groupData - Standard Gruppendaten
|
||||||
|
* @param {boolean} workshopConsent - Werkstatt-Anzeige Zustimmung
|
||||||
|
* @param {Array} socialMediaConsents - Array von {platformId, consented}
|
||||||
|
* @returns {Promise<string>} groupId der erstellten Gruppe
|
||||||
|
*/
|
||||||
|
async createGroupWithConsent(groupData, workshopConsent, socialMediaConsents = []) {
|
||||||
|
const SocialMediaRepository = require('./SocialMediaRepository');
|
||||||
|
const socialMediaRepo = new SocialMediaRepository(dbManager);
|
||||||
|
|
||||||
|
return await dbManager.transaction(async (db) => {
|
||||||
|
const consentTimestamp = new Date().toISOString();
|
||||||
|
|
||||||
|
// Füge Gruppe mit Consent-Feldern hinzu
|
||||||
|
await db.run(`
|
||||||
|
INSERT INTO groups (
|
||||||
|
group_id, year, title, description, name, upload_date, approved,
|
||||||
|
display_in_workshop, consent_timestamp
|
||||||
|
)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
`, [
|
||||||
|
groupData.groupId,
|
||||||
|
groupData.year,
|
||||||
|
groupData.title,
|
||||||
|
groupData.description || null,
|
||||||
|
groupData.name || null,
|
||||||
|
groupData.uploadDate,
|
||||||
|
groupData.approved || false,
|
||||||
|
workshopConsent ? 1 : 0,
|
||||||
|
consentTimestamp
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Füge Bilder hinzu
|
||||||
|
if (groupData.images && groupData.images.length > 0) {
|
||||||
|
for (const image of groupData.images) {
|
||||||
|
await db.run(`
|
||||||
|
INSERT INTO images (
|
||||||
|
group_id, file_name, original_name, file_path, upload_order,
|
||||||
|
file_size, mime_type, preview_path, image_description
|
||||||
|
)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
`, [
|
||||||
|
groupData.groupId,
|
||||||
|
image.fileName,
|
||||||
|
image.originalName,
|
||||||
|
image.filePath,
|
||||||
|
image.uploadOrder,
|
||||||
|
image.fileSize || null,
|
||||||
|
image.mimeType || null,
|
||||||
|
image.previewPath || null,
|
||||||
|
image.imageDescription || null
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Speichere Social Media Consents
|
||||||
|
if (socialMediaConsents && socialMediaConsents.length > 0) {
|
||||||
|
await socialMediaRepo.saveConsents(
|
||||||
|
groupData.groupId,
|
||||||
|
socialMediaConsents,
|
||||||
|
consentTimestamp
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return groupData.groupId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hole Gruppe mit allen Consent-Informationen
|
||||||
|
* @param {string} groupId - ID der Gruppe
|
||||||
|
* @returns {Promise<Object>} Gruppe mit Bildern und Consents
|
||||||
|
*/
|
||||||
|
async getGroupWithConsents(groupId) {
|
||||||
|
const SocialMediaRepository = require('./SocialMediaRepository');
|
||||||
|
const socialMediaRepo = new SocialMediaRepository(dbManager);
|
||||||
|
|
||||||
|
// Hole Standard-Gruppendaten
|
||||||
|
const group = await this.getGroupById(groupId);
|
||||||
|
|
||||||
|
if (!group) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Füge Consent-Daten hinzu
|
||||||
|
group.consents = await socialMediaRepo.getConsentsForGroup(groupId);
|
||||||
|
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualisiere Consents für eine bestehende Gruppe
|
||||||
|
* @param {string} groupId - ID der Gruppe
|
||||||
|
* @param {boolean} workshopConsent - Neue Werkstatt-Consent
|
||||||
|
* @param {Array} socialMediaConsents - Neue Social Media Consents
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async updateConsents(groupId, workshopConsent, socialMediaConsents = []) {
|
||||||
|
const SocialMediaRepository = require('./SocialMediaRepository');
|
||||||
|
const socialMediaRepo = new SocialMediaRepository(dbManager);
|
||||||
|
|
||||||
|
return await dbManager.transaction(async (db) => {
|
||||||
|
const consentTimestamp = new Date().toISOString();
|
||||||
|
|
||||||
|
// Aktualisiere Werkstatt-Consent
|
||||||
|
await db.run(`
|
||||||
|
UPDATE groups
|
||||||
|
SET display_in_workshop = ?,
|
||||||
|
consent_timestamp = ?
|
||||||
|
WHERE group_id = ?
|
||||||
|
`, [workshopConsent ? 1 : 0, consentTimestamp, groupId]);
|
||||||
|
|
||||||
|
// Lösche alte Social Media Consents
|
||||||
|
await socialMediaRepo.deleteConsentsForGroup(groupId);
|
||||||
|
|
||||||
|
// Speichere neue Consents
|
||||||
|
if (socialMediaConsents && socialMediaConsents.length > 0) {
|
||||||
|
await socialMediaRepo.saveConsents(
|
||||||
|
groupId,
|
||||||
|
socialMediaConsents,
|
||||||
|
consentTimestamp
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filtere Gruppen nach Consent-Status
|
||||||
|
* @param {Object} filters - Filter-Optionen
|
||||||
|
* @param {boolean} filters.displayInWorkshop - Filter nach Werkstatt-Consent
|
||||||
|
* @param {number} filters.platformId - Filter nach Plattform-ID
|
||||||
|
* @param {boolean} filters.platformConsent - Filter nach Platform-Consent-Status
|
||||||
|
* @returns {Promise<Array>} Gefilterte Gruppen
|
||||||
|
*/
|
||||||
|
async getGroupsByConsentStatus(filters = {}) {
|
||||||
|
let query = `
|
||||||
|
SELECT DISTINCT g.*
|
||||||
|
FROM groups g
|
||||||
|
`;
|
||||||
|
const params = [];
|
||||||
|
const conditions = [];
|
||||||
|
|
||||||
|
// Filter nach Werkstatt-Consent
|
||||||
|
if (filters.displayInWorkshop !== undefined) {
|
||||||
|
conditions.push('g.display_in_workshop = ?');
|
||||||
|
params.push(filters.displayInWorkshop ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter nach Social Media Platform
|
||||||
|
if (filters.platformId !== undefined) {
|
||||||
|
query += `
|
||||||
|
LEFT JOIN group_social_media_consents c
|
||||||
|
ON g.group_id = c.group_id AND c.platform_id = ?
|
||||||
|
`;
|
||||||
|
params.push(filters.platformId);
|
||||||
|
|
||||||
|
if (filters.platformConsent !== undefined) {
|
||||||
|
conditions.push('c.consented = ?');
|
||||||
|
params.push(filters.platformConsent ? 1 : 0);
|
||||||
|
conditions.push('(c.revoked IS NULL OR c.revoked = 0)');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conditions.length > 0) {
|
||||||
|
query += ' WHERE ' + conditions.join(' AND ');
|
||||||
|
}
|
||||||
|
|
||||||
|
query += ' ORDER BY g.upload_date DESC';
|
||||||
|
|
||||||
|
return await dbManager.all(query, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exportiere Consent-Daten für rechtliche Dokumentation
|
||||||
|
* @param {Object} filters - Optional: Filter-Kriterien
|
||||||
|
* @returns {Promise<Array>} Export-Daten mit allen Consent-Informationen
|
||||||
|
*/
|
||||||
|
async exportConsentData(filters = {}) {
|
||||||
|
let query = `
|
||||||
|
SELECT
|
||||||
|
g.group_id,
|
||||||
|
g.year,
|
||||||
|
g.title,
|
||||||
|
g.name,
|
||||||
|
g.upload_date,
|
||||||
|
g.display_in_workshop,
|
||||||
|
g.consent_timestamp,
|
||||||
|
g.approved
|
||||||
|
FROM groups g
|
||||||
|
WHERE 1=1
|
||||||
|
`;
|
||||||
|
const params = [];
|
||||||
|
|
||||||
|
if (filters.year) {
|
||||||
|
query += ' AND g.year = ?';
|
||||||
|
params.push(filters.year);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.approved !== undefined) {
|
||||||
|
query += ' AND g.approved = ?';
|
||||||
|
params.push(filters.approved ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
query += ' ORDER BY g.upload_date DESC';
|
||||||
|
|
||||||
|
const groups = await dbManager.all(query, params);
|
||||||
|
|
||||||
|
// Lade Social Media Consents für jede Gruppe
|
||||||
|
const SocialMediaRepository = require('./SocialMediaRepository');
|
||||||
|
const socialMediaRepo = new SocialMediaRepository(dbManager);
|
||||||
|
|
||||||
|
for (const group of groups) {
|
||||||
|
group.socialMediaConsents = await socialMediaRepo.getConsentsForGroup(group.group_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generiere Management-Token für Gruppe (Phase 2)
|
||||||
|
* @param {string} groupId - ID der Gruppe
|
||||||
|
* @returns {Promise<string>} Generierter UUID Token
|
||||||
|
*/
|
||||||
|
async generateManagementToken(groupId) {
|
||||||
|
const crypto = require('crypto');
|
||||||
|
const token = crypto.randomUUID();
|
||||||
|
|
||||||
|
await dbManager.run(`
|
||||||
|
UPDATE groups
|
||||||
|
SET management_token = ?
|
||||||
|
WHERE group_id = ?
|
||||||
|
`, [token, groupId]);
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hole Gruppe über Management-Token (Phase 2)
|
||||||
|
* @param {string} token - Management Token
|
||||||
|
* @returns {Promise<Object|null>} Gruppe mit allen Daten oder null
|
||||||
|
*/
|
||||||
|
async getGroupByManagementToken(token) {
|
||||||
|
const group = await dbManager.get(`
|
||||||
|
SELECT * FROM groups WHERE management_token = ?
|
||||||
|
`, [token]);
|
||||||
|
|
||||||
|
if (!group) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lade Bilder und Consents
|
||||||
|
return await this.getGroupWithConsents(group.group_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hole aktive Social Media Plattformen
|
||||||
|
* Convenience-Methode für Frontend
|
||||||
|
* @returns {Promise<Array>} Aktive Plattformen
|
||||||
|
*/
|
||||||
|
async getActiveSocialMediaPlatforms() {
|
||||||
|
const SocialMediaRepository = require('./SocialMediaRepository');
|
||||||
|
const socialMediaRepo = new SocialMediaRepository(dbManager);
|
||||||
|
return await socialMediaRepo.getActivePlatforms();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hole Social Media Consents für Gruppe
|
||||||
|
* Convenience-Methode
|
||||||
|
* @param {string} groupId - ID der Gruppe
|
||||||
|
* @returns {Promise<Array>} Consents
|
||||||
|
*/
|
||||||
|
async getSocialMediaConsentsForGroup(groupId) {
|
||||||
|
const SocialMediaRepository = require('./SocialMediaRepository');
|
||||||
|
const socialMediaRepo = new SocialMediaRepository(dbManager);
|
||||||
|
return await socialMediaRepo.getConsentsForGroup(groupId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = new GroupRepository();
|
module.exports = new GroupRepository();
|
||||||
339
backend/src/repositories/SocialMediaRepository.js
Normal file
339
backend/src/repositories/SocialMediaRepository.js
Normal file
|
|
@ -0,0 +1,339 @@
|
||||||
|
/**
|
||||||
|
* SocialMediaRepository
|
||||||
|
*
|
||||||
|
* Repository für Social Media Platform und Consent Management
|
||||||
|
* Verwaltet social_media_platforms und group_social_media_consents Tabellen
|
||||||
|
*/
|
||||||
|
|
||||||
|
class SocialMediaRepository {
|
||||||
|
constructor(dbManager) {
|
||||||
|
this.db = dbManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Platform Management
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lade alle Social Media Plattformen (aktiv und inaktiv)
|
||||||
|
* @returns {Promise<Array>} Array von Platform-Objekten
|
||||||
|
*/
|
||||||
|
async getAllPlatforms() {
|
||||||
|
const query = `
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
platform_name,
|
||||||
|
display_name,
|
||||||
|
icon_name,
|
||||||
|
is_active,
|
||||||
|
sort_order,
|
||||||
|
created_at
|
||||||
|
FROM social_media_platforms
|
||||||
|
ORDER BY sort_order ASC, display_name ASC
|
||||||
|
`;
|
||||||
|
|
||||||
|
return await this.db.all(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lade nur aktive Social Media Plattformen
|
||||||
|
* @returns {Promise<Array>} Array von aktiven Platform-Objekten
|
||||||
|
*/
|
||||||
|
async getActivePlatforms() {
|
||||||
|
const query = `
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
platform_name,
|
||||||
|
display_name,
|
||||||
|
icon_name,
|
||||||
|
sort_order
|
||||||
|
FROM social_media_platforms
|
||||||
|
WHERE is_active = 1
|
||||||
|
ORDER BY sort_order ASC, display_name ASC
|
||||||
|
`;
|
||||||
|
|
||||||
|
return await this.db.all(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erstelle eine neue Social Media Plattform
|
||||||
|
* @param {Object} platformData - Platform-Daten
|
||||||
|
* @param {string} platformData.platform_name - Interner Name (z.B. 'facebook')
|
||||||
|
* @param {string} platformData.display_name - Anzeigename (z.B. 'Facebook')
|
||||||
|
* @param {string} platformData.icon_name - Material-UI Icon Name
|
||||||
|
* @param {number} platformData.sort_order - Sortierreihenfolge
|
||||||
|
* @returns {Promise<number>} ID der neu erstellten Plattform
|
||||||
|
*/
|
||||||
|
async createPlatform(platformData) {
|
||||||
|
const query = `
|
||||||
|
INSERT INTO social_media_platforms
|
||||||
|
(platform_name, display_name, icon_name, sort_order, is_active)
|
||||||
|
VALUES (?, ?, ?, ?, 1)
|
||||||
|
`;
|
||||||
|
|
||||||
|
const result = await this.db.run(
|
||||||
|
query,
|
||||||
|
[
|
||||||
|
platformData.platform_name,
|
||||||
|
platformData.display_name,
|
||||||
|
platformData.icon_name || null,
|
||||||
|
platformData.sort_order || 0
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
return result.lastID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualisiere eine bestehende Plattform
|
||||||
|
* @param {number} platformId - ID der Plattform
|
||||||
|
* @param {Object} platformData - Zu aktualisierende Daten
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async updatePlatform(platformId, platformData) {
|
||||||
|
const updates = [];
|
||||||
|
const values = [];
|
||||||
|
|
||||||
|
if (platformData.display_name !== undefined) {
|
||||||
|
updates.push('display_name = ?');
|
||||||
|
values.push(platformData.display_name);
|
||||||
|
}
|
||||||
|
if (platformData.icon_name !== undefined) {
|
||||||
|
updates.push('icon_name = ?');
|
||||||
|
values.push(platformData.icon_name);
|
||||||
|
}
|
||||||
|
if (platformData.sort_order !== undefined) {
|
||||||
|
updates.push('sort_order = ?');
|
||||||
|
values.push(platformData.sort_order);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updates.length === 0) {
|
||||||
|
return; // Nichts zu aktualisieren
|
||||||
|
}
|
||||||
|
|
||||||
|
values.push(platformId);
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
UPDATE social_media_platforms
|
||||||
|
SET ${updates.join(', ')}
|
||||||
|
WHERE id = ?
|
||||||
|
`;
|
||||||
|
|
||||||
|
await this.db.run(query, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktiviere oder deaktiviere eine Plattform
|
||||||
|
* @param {number} platformId - ID der Plattform
|
||||||
|
* @param {boolean} isActive - Aktiv-Status
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async togglePlatformStatus(platformId, isActive) {
|
||||||
|
const query = `
|
||||||
|
UPDATE social_media_platforms
|
||||||
|
SET is_active = ?
|
||||||
|
WHERE id = ?
|
||||||
|
`;
|
||||||
|
|
||||||
|
await this.db.run(query, [isActive ? 1 : 0, platformId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Consent Management
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Speichere Consents für eine Gruppe
|
||||||
|
* @param {string} groupId - ID der Gruppe
|
||||||
|
* @param {Array} consentsArray - Array von {platformId, consented} Objekten
|
||||||
|
* @param {string} consentTimestamp - ISO-Timestamp der Zustimmung
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async saveConsents(groupId, consentsArray, consentTimestamp) {
|
||||||
|
if (!Array.isArray(consentsArray) || consentsArray.length === 0) {
|
||||||
|
return; // Keine Consents zu speichern
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
INSERT INTO group_social_media_consents
|
||||||
|
(group_id, platform_id, consented, consent_timestamp)
|
||||||
|
VALUES (?, ?, ?, ?)
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Speichere jeden Consent einzeln
|
||||||
|
for (const consent of consentsArray) {
|
||||||
|
await this.db.run(
|
||||||
|
query,
|
||||||
|
[
|
||||||
|
groupId,
|
||||||
|
consent.platformId,
|
||||||
|
consent.consented ? 1 : 0,
|
||||||
|
consentTimestamp
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lade alle Consents für eine Gruppe
|
||||||
|
* @param {string} groupId - ID der Gruppe
|
||||||
|
* @returns {Promise<Array>} Array von Consent-Objekten mit Platform-Info
|
||||||
|
*/
|
||||||
|
async getConsentsForGroup(groupId) {
|
||||||
|
const query = `
|
||||||
|
SELECT
|
||||||
|
c.id,
|
||||||
|
c.group_id,
|
||||||
|
c.platform_id,
|
||||||
|
c.consented,
|
||||||
|
c.consent_timestamp,
|
||||||
|
c.revoked,
|
||||||
|
c.revoked_timestamp,
|
||||||
|
p.platform_name,
|
||||||
|
p.display_name,
|
||||||
|
p.icon_name
|
||||||
|
FROM group_social_media_consents c
|
||||||
|
JOIN social_media_platforms p ON c.platform_id = p.id
|
||||||
|
WHERE c.group_id = ?
|
||||||
|
ORDER BY p.sort_order ASC
|
||||||
|
`;
|
||||||
|
|
||||||
|
return await this.db.all(query, [groupId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lade Gruppen-IDs nach Consent-Status filtern
|
||||||
|
* @param {Object} filters - Filter-Optionen
|
||||||
|
* @param {number} filters.platformId - Optional: Filter nach Plattform-ID
|
||||||
|
* @param {boolean} filters.consented - Optional: Filter nach Consent-Status
|
||||||
|
* @returns {Promise<Array>} Array von Gruppen-IDs
|
||||||
|
*/
|
||||||
|
async getGroupIdsByConsentStatus(filters = {}) {
|
||||||
|
let query = `
|
||||||
|
SELECT DISTINCT c.group_id
|
||||||
|
FROM group_social_media_consents c
|
||||||
|
WHERE 1=1
|
||||||
|
`;
|
||||||
|
const params = [];
|
||||||
|
|
||||||
|
if (filters.platformId !== undefined) {
|
||||||
|
query += ' AND c.platform_id = ?';
|
||||||
|
params.push(filters.platformId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.consented !== undefined) {
|
||||||
|
query += ' AND c.consented = ?';
|
||||||
|
params.push(filters.consented ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.revoked !== undefined) {
|
||||||
|
query += ' AND c.revoked = ?';
|
||||||
|
params.push(filters.revoked ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = await this.db.all(query, params);
|
||||||
|
return results.map(row => row.group_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Widerrufe einen Consent (Phase 2)
|
||||||
|
* @param {string} groupId - ID der Gruppe
|
||||||
|
* @param {number} platformId - ID der Plattform
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async revokeConsent(groupId, platformId) {
|
||||||
|
const query = `
|
||||||
|
UPDATE group_social_media_consents
|
||||||
|
SET
|
||||||
|
revoked = 1,
|
||||||
|
revoked_timestamp = CURRENT_TIMESTAMP
|
||||||
|
WHERE group_id = ? AND platform_id = ?
|
||||||
|
`;
|
||||||
|
|
||||||
|
await this.db.run(query, [groupId, platformId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stelle einen widerrufenen Consent wieder her (Phase 2)
|
||||||
|
* @param {string} groupId - ID der Gruppe
|
||||||
|
* @param {number} platformId - ID der Plattform
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async restoreConsent(groupId, platformId) {
|
||||||
|
const query = `
|
||||||
|
UPDATE group_social_media_consents
|
||||||
|
SET
|
||||||
|
revoked = 0,
|
||||||
|
revoked_timestamp = NULL
|
||||||
|
WHERE group_id = ? AND platform_id = ?
|
||||||
|
`;
|
||||||
|
|
||||||
|
await this.db.run(query, [groupId, platformId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lade Consent-Historie für eine Gruppe (Phase 2)
|
||||||
|
* @param {string} groupId - ID der Gruppe
|
||||||
|
* @returns {Promise<Array>} Array von Consent-Änderungen
|
||||||
|
*/
|
||||||
|
async getConsentHistory(groupId) {
|
||||||
|
const query = `
|
||||||
|
SELECT
|
||||||
|
c.id,
|
||||||
|
c.group_id,
|
||||||
|
c.platform_id,
|
||||||
|
c.consented,
|
||||||
|
c.consent_timestamp,
|
||||||
|
c.revoked,
|
||||||
|
c.revoked_timestamp,
|
||||||
|
c.created_at,
|
||||||
|
c.updated_at,
|
||||||
|
p.platform_name,
|
||||||
|
p.display_name
|
||||||
|
FROM group_social_media_consents c
|
||||||
|
JOIN social_media_platforms p ON c.platform_id = p.id
|
||||||
|
WHERE c.group_id = ?
|
||||||
|
ORDER BY c.updated_at DESC
|
||||||
|
`;
|
||||||
|
|
||||||
|
return await this.db.all(query, [groupId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prüfe ob eine Gruppe Consent für eine bestimmte Plattform hat
|
||||||
|
* @param {string} groupId - ID der Gruppe
|
||||||
|
* @param {number} platformId - ID der Plattform
|
||||||
|
* @returns {Promise<boolean>} true wenn Consent erteilt und nicht widerrufen
|
||||||
|
*/
|
||||||
|
async hasActiveConsent(groupId, platformId) {
|
||||||
|
const query = `
|
||||||
|
SELECT consented, revoked
|
||||||
|
FROM group_social_media_consents
|
||||||
|
WHERE group_id = ? AND platform_id = ?
|
||||||
|
`;
|
||||||
|
|
||||||
|
const result = await this.db.get(query, [groupId, platformId]);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.consented === 1 && result.revoked === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lösche alle Consents für eine Gruppe (CASCADE durch DB)
|
||||||
|
* @param {string} groupId - ID der Gruppe
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async deleteConsentsForGroup(groupId) {
|
||||||
|
const query = `
|
||||||
|
DELETE FROM group_social_media_consents
|
||||||
|
WHERE group_id = ?
|
||||||
|
`;
|
||||||
|
|
||||||
|
await this.db.run(query, [groupId]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = SocialMediaRepository;
|
||||||
Loading…
Reference in New Issue
Block a user