|
|
|
|
@@ -1,99 +1,94 @@
|
|
|
|
|
import { promises as fs } from 'fs';
|
|
|
|
|
import path from 'path';
|
|
|
|
|
import { PrismaClient, PoliticalStatement as PrismaPoliticalStatement } from '@prisma/client';
|
|
|
|
|
|
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
|
|
|
|
|
|
export type PoliticalStatement = {
|
|
|
|
|
id: number;
|
|
|
|
|
locale: string;
|
|
|
|
|
text: string;
|
|
|
|
|
active?: boolean;
|
|
|
|
|
source?: string;
|
|
|
|
|
active: boolean;
|
|
|
|
|
source?: string | null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function getFilePath(locale: string): string {
|
|
|
|
|
const safeLocale = ['de', 'en'].includes(locale) ? locale : 'en';
|
|
|
|
|
return path.join(process.cwd(), 'data', `political-statements.${safeLocale}.json`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function readStatementsFile(locale: string): Promise<PoliticalStatement[]> {
|
|
|
|
|
const filePath = getFilePath(locale);
|
|
|
|
|
try {
|
|
|
|
|
const raw = await fs.readFile(filePath, 'utf-8');
|
|
|
|
|
const data = JSON.parse(raw);
|
|
|
|
|
if (Array.isArray(data)) {
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
return [];
|
|
|
|
|
} catch (err: any) {
|
|
|
|
|
if (err.code === 'ENOENT') {
|
|
|
|
|
// File does not exist yet
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
console.error('[politicalStatements] Failed to read file', filePath, err);
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function writeStatementsFile(locale: string, statements: PoliticalStatement[]): Promise<void> {
|
|
|
|
|
const filePath = getFilePath(locale);
|
|
|
|
|
const dir = path.dirname(filePath);
|
|
|
|
|
try {
|
|
|
|
|
await fs.mkdir(dir, { recursive: true });
|
|
|
|
|
await fs.writeFile(filePath, JSON.stringify(statements, null, 2), 'utf-8');
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error('[politicalStatements] Failed to write file', filePath, err);
|
|
|
|
|
throw err;
|
|
|
|
|
}
|
|
|
|
|
function mapFromPrisma(stmt: PrismaPoliticalStatement): PoliticalStatement {
|
|
|
|
|
return {
|
|
|
|
|
id: stmt.id,
|
|
|
|
|
locale: stmt.locale,
|
|
|
|
|
text: stmt.text,
|
|
|
|
|
active: stmt.active,
|
|
|
|
|
source: stmt.source,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function getRandomActiveStatement(locale: string): Promise<PoliticalStatement | null> {
|
|
|
|
|
const statements = await readStatementsFile(locale);
|
|
|
|
|
const active = statements.filter((s) => s.active !== false);
|
|
|
|
|
if (active.length === 0) {
|
|
|
|
|
const safeLocale = ['de', 'en'].includes(locale) ? locale : 'en';
|
|
|
|
|
const all = await prisma.politicalStatement.findMany({
|
|
|
|
|
where: {
|
|
|
|
|
locale: safeLocale,
|
|
|
|
|
active: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (all.length === 0) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
const index = Math.floor(Math.random() * active.length);
|
|
|
|
|
return active[index] ?? null;
|
|
|
|
|
|
|
|
|
|
const index = Math.floor(Math.random() * all.length);
|
|
|
|
|
return mapFromPrisma(all[index]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function getAllStatements(locale: string): Promise<PoliticalStatement[]> {
|
|
|
|
|
return readStatementsFile(locale);
|
|
|
|
|
const safeLocale = ['de', 'en'].includes(locale) ? locale : 'en';
|
|
|
|
|
const all = await prisma.politicalStatement.findMany({
|
|
|
|
|
where: { locale: safeLocale },
|
|
|
|
|
orderBy: { id: 'asc' },
|
|
|
|
|
});
|
|
|
|
|
return all.map(mapFromPrisma);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function createStatement(locale: string, input: Omit<PoliticalStatement, 'id'>): Promise<PoliticalStatement> {
|
|
|
|
|
const statements = await readStatementsFile(locale);
|
|
|
|
|
const nextId = statements.length > 0 ? Math.max(...statements.map((s) => s.id)) + 1 : 1;
|
|
|
|
|
const newStatement: PoliticalStatement = {
|
|
|
|
|
id: nextId,
|
|
|
|
|
active: true,
|
|
|
|
|
...input,
|
|
|
|
|
};
|
|
|
|
|
statements.push(newStatement);
|
|
|
|
|
await writeStatementsFile(locale, statements);
|
|
|
|
|
return newStatement;
|
|
|
|
|
export async function createStatement(locale: string, input: Omit<PoliticalStatement, 'id' | 'locale'>): Promise<PoliticalStatement> {
|
|
|
|
|
const safeLocale = ['de', 'en'].includes(locale) ? locale : 'en';
|
|
|
|
|
const created = await prisma.politicalStatement.create({
|
|
|
|
|
data: {
|
|
|
|
|
locale: safeLocale,
|
|
|
|
|
text: input.text,
|
|
|
|
|
active: input.active ?? true,
|
|
|
|
|
source: input.source ?? null,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
return mapFromPrisma(created);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function updateStatement(locale: string, id: number, input: Partial<Omit<PoliticalStatement, 'id'>>): Promise<PoliticalStatement | null> {
|
|
|
|
|
const statements = await readStatementsFile(locale);
|
|
|
|
|
const index = statements.findIndex((s) => s.id === id);
|
|
|
|
|
if (index === -1) return null;
|
|
|
|
|
export async function updateStatement(locale: string, id: number, input: Partial<Omit<PoliticalStatement, 'id' | 'locale'>>): Promise<PoliticalStatement | null> {
|
|
|
|
|
const safeLocale = ['de', 'en'].includes(locale) ? locale : 'en';
|
|
|
|
|
|
|
|
|
|
const updated: PoliticalStatement = {
|
|
|
|
|
...statements[index],
|
|
|
|
|
...input,
|
|
|
|
|
id,
|
|
|
|
|
};
|
|
|
|
|
statements[index] = updated;
|
|
|
|
|
await writeStatementsFile(locale, statements);
|
|
|
|
|
return updated;
|
|
|
|
|
// Optional: sicherstellen, dass das Statement zu dieser Locale gehört
|
|
|
|
|
const existing = await prisma.politicalStatement.findUnique({ where: { id } });
|
|
|
|
|
if (!existing || existing.locale !== safeLocale) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const updated = await prisma.politicalStatement.update({
|
|
|
|
|
where: { id },
|
|
|
|
|
data: {
|
|
|
|
|
text: input.text ?? existing.text,
|
|
|
|
|
active: input.active ?? existing.active,
|
|
|
|
|
source: input.source !== undefined ? input.source : existing.source,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return mapFromPrisma(updated);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function deleteStatement(locale: string, id: number): Promise<boolean> {
|
|
|
|
|
const statements = await readStatementsFile(locale);
|
|
|
|
|
const filtered = statements.filter((s) => s.id !== id);
|
|
|
|
|
if (filtered.length === statements.length) {
|
|
|
|
|
const safeLocale = ['de', 'en'].includes(locale) ? locale : 'en';
|
|
|
|
|
|
|
|
|
|
const existing = await prisma.politicalStatement.findUnique({ where: { id } });
|
|
|
|
|
if (!existing || existing.locale !== safeLocale) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
await writeStatementsFile(locale, filtered);
|
|
|
|
|
|
|
|
|
|
await prisma.politicalStatement.delete({ where: { id } });
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|