Update 10 files

This commit is contained in:
[dyad] committed 2026-08-02 12:33:19 +02:00
1 parent 28a3c6121a
commit 28680e396e
10 files changed
+46 -108

No files matched your search

+6 -15
View File
@@ -3,20 +3,11 @@
* This document lists all data entities, their purposes, legal basis, and retention categories
*/
const fs = require("fs");
const path = require("path");
interface DataEntity {
name: string;
dataCategories: string[];
legalBasis: string;
purpose: string;
retentionCategory: string;
notes?: string;
}
import fs from "node:fs";
import path from "node:path";
// Core data model definition
const dataModel: DataEntity[] = [
const dataModel = [
{
name: "User",
dataCategories: ["firstName", "lastName", "email", "role", "createdAt"],
@@ -112,12 +103,12 @@ const dataModel: DataEntity[] = [
},
];
export function generateDataModel(outputPath: string = "docs/legal"): void {
function generateDataModel(outputPath = "docs/legal") {
if (!fs.existsSync(outputPath)) {
fs.mkdirSync(outputPath, { recursive: true });
}
const lines: string[] = [
const lines = [
"# Data Model Documentation",
"",
"**Status**: Schema Reference for ExaMetra (Module L)",
@@ -166,7 +157,7 @@ export function generateDataModel(outputPath: string = "docs/legal"): void {
"",
`Generated: ${new Date().toISOString()}`,
"Source: ExaMetra Prisma schema (Module L)",
];
);
const filePath = path.join(outputPath, "DATA_MODEL.md");
fs.writeFileSync(filePath, lines.join("\n"), "utf-8");
+5 -16
View File
@@ -3,26 +3,15 @@
* Plain-language German, based on school configuration
*/
const fs = require("fs");
const path = require("path");
import fs from "node:fs";
import path from "node:path";
interface PrivacyNoticeParams {
schoolName: string;
dpoName: string;
dpoEmail: string;
schultragerName: string;
bundesland: string;
}
export function generatePrivacyNotice(
params: PrivacyNoticeParams,
outputPath: string = "docs/legal"
): void {
function generatePrivacyNotice(params, outputPath = "docs/legal") {
if (!fs.existsSync(outputPath)) {
fs.mkdirSync(outputPath, { recursive: true });
}
const lines: string[] = [
const lines = [
"# Datenschutzerklärung",
"# (Privacy Notice for Parents & Students)",
"",
@@ -139,7 +128,7 @@ export function generatePrivacyNotice(
console.log(`[v0] Generated privacy notice at ${filePath}`);
}
if (require.main === module) {
if (process.argv[1] && path.resolve(process.argv[1]) === new URL(import.meta.url).pathname) {
generatePrivacyNotice({
schoolName: "Gymnasium Berlin",
dpoName: "Max Mustermann",
+6 -16
View File
@@ -4,20 +4,10 @@
* German legal document for school's DPO review
*/
const fs = require("fs");
const path = require("path");
import fs from "node:fs";
import path from "node:path";
interface RopaEntry {
name: string;
purposes: string[];
dataCategories: string[];
recipients: string[];
retentionPeriod: string;
legalBasis: string;
securityMeasures: string[];
}
const ropas: RopaEntry[] = [
const ropas = [
{
name: "Student Information Management",
purposes: [
@@ -126,12 +116,12 @@ const ropas: RopaEntry[] = [
},
];
export function generateRopa(outputPath: string = "docs/legal"): void {
function generateRopa(outputPath = "docs/legal") {
if (!fs.existsSync(outputPath)) {
fs.mkdirSync(outputPath, { recursive: true });
}
const lines: string[] = [
const lines = [
"# Verzeichnis von Verarbeitungstätigkeiten",
"# (Records of Processing Activities - Art. 30 GDPR)",
"",
@@ -198,7 +188,7 @@ export function generateRopa(outputPath: string = "docs/legal"): void {
"",
`**Generiert**: ${new Date().toISOString()}`,
"**Quelle**: ExaMetra Module L - Compliance Framework",
];
);
const filePath = path.join(
outputPath,
+8 -23
View File
@@ -6,18 +6,11 @@
* Usage: npx ts-node scripts/run-retention-job.ts
*/
const { PrismaClient } = require("@prisma/client");
import { PrismaClient } from "@prisma/client";
import path from "node:path";
const prisma = new PrismaClient();
interface FlaggedRecord {
entityType: string;
entityId: string;
dataCategory: string;
flaggedAt: Date;
reason: string;
}
/**
* Check records for each school and flag those exceeding retention period
*/
@@ -32,7 +25,7 @@ async function runRetentionJob() {
});
let totalFlagged = 0;
const report: { school: string; flagged: number }[] = [];
const report = [];
for (const school of schools) {
const schoolFlagged = await flagExpiredRecordsForSchool(school.id);
@@ -75,7 +68,7 @@ async function runRetentionJob() {
/**
* Flag expired records for a specific school
*/
async function flagExpiredRecordsForSchool(schoolId: string): Promise<number> {
async function flagExpiredRecordsForSchool(schoolId) {
// Get all retention policies for this school
const policies = await prisma.dataRetentionPolicy.findMany({
where: { schoolId },
@@ -106,11 +99,7 @@ async function flagExpiredRecordsForSchool(schoolId: string): Promise<number> {
/**
* Flag records of a specific category that are older than expiryDate
*/
async function flagRecordsByCategory(
schoolId: string,
dataCategory: string,
expiryDate: Date
): Promise<number> {
async function flagRecordsByCategory(schoolId, dataCategory, expiryDate) {
let flaggedCount = 0;
try {
@@ -201,11 +190,7 @@ async function flagRecordsByCategory(
/**
* Generic function to flag expired records by entity type
*/
async function flagRecordsByEntityType(
schoolId: string,
entityType: string,
expiryDate: Date
): Promise<number> {
async function flagRecordsByEntityType(schoolId, entityType, expiryDate) {
// Check if records of this type already have deletion flags
const alreadyFlagged = await prisma.deletionFlag.findMany({
where: {
@@ -255,7 +240,7 @@ async function flagRecordsByEntityType(
}
// Run the job if this script is executed directly
if (require.main === module) {
if (process.argv[1] && path.resolve(process.argv[1]) === new URL(import.meta.url).pathname) {
runRetentionJob()
.then((result) => {
console.log(
@@ -270,4 +255,4 @@ if (require.main === module) {
});
}
module.exports = { runRetentionJob, flagExpiredRecordsForSchool };
export { runRetentionJob, flagExpiredRecordsForSchool };