fix permissions

This commit is contained in:
Matthias Hochmeister
2026-03-25 07:48:00 +01:00
parent 5a64987236
commit 59140939df
9 changed files with 750 additions and 100 deletions

View File

@@ -363,20 +363,202 @@ async function getAssignableMembers() {
async function getIssueCounts() {
try {
const result = await pool.query(
`SELECT status, COUNT(*)::int AS count FROM issues GROUP BY status`
);
const counts: Record<string, number> = { offen: 0, in_bearbeitung: 0, erledigt: 0, abgelehnt: 0 };
for (const row of result.rows) {
counts[row.status] = row.count;
}
return counts;
const result = await pool.query(`
SELECT
COALESCE(s.schluessel, i.status) AS schluessel,
COALESCE(s.bezeichnung, i.status) AS bezeichnung,
COALESCE(s.farbe, 'default') AS farbe,
COALESCE(s.ist_abschluss, false) AS ist_abschluss,
COALESCE(s.sort_order, 99) AS sort_order,
COUNT(*)::int AS count
FROM issues i
LEFT JOIN issue_statuses s ON s.schluessel = i.status
GROUP BY
COALESCE(s.schluessel, i.status),
COALESCE(s.bezeichnung, i.status),
COALESCE(s.farbe, 'default'),
COALESCE(s.ist_abschluss, false),
COALESCE(s.sort_order, 99)
ORDER BY COALESCE(s.sort_order, 99)
`);
return result.rows;
} catch (error) {
logger.error('IssueService.getIssueCounts failed', { error });
throw new Error('Issue-Counts konnten nicht geladen werden');
}
}
async function getIssueStatuses() {
try {
const result = await pool.query(
`SELECT * FROM issue_statuses ORDER BY sort_order ASC, id ASC`
);
return result.rows;
} catch (error) {
logger.error('IssueService.getIssueStatuses failed', { error });
throw new Error('Issue-Status konnten nicht geladen werden');
}
}
async function createIssueStatus(data: {
schluessel: string;
bezeichnung: string;
farbe?: string;
ist_abschluss?: boolean;
ist_initial?: boolean;
benoetigt_typ_freigabe?: boolean;
sort_order?: number;
}) {
try {
const result = await pool.query(
`INSERT INTO issue_statuses (schluessel, bezeichnung, farbe, ist_abschluss, ist_initial, benoetigt_typ_freigabe, sort_order)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING *`,
[
data.schluessel,
data.bezeichnung,
data.farbe ?? 'default',
data.ist_abschluss ?? false,
data.ist_initial ?? false,
data.benoetigt_typ_freigabe ?? false,
data.sort_order ?? 0,
]
);
return result.rows[0];
} catch (error) {
logger.error('IssueService.createIssueStatus failed', { error });
throw new Error('Issue-Status konnte nicht erstellt werden');
}
}
async function updateIssueStatus(id: number, data: {
bezeichnung?: string;
farbe?: string;
ist_abschluss?: boolean;
ist_initial?: boolean;
benoetigt_typ_freigabe?: boolean;
sort_order?: number;
aktiv?: boolean;
}) {
try {
const setClauses: string[] = [];
const values: any[] = [];
let idx = 1;
if (data.bezeichnung !== undefined) { setClauses.push(`bezeichnung = $${idx}`); values.push(data.bezeichnung); idx++; }
if (data.farbe !== undefined) { setClauses.push(`farbe = $${idx}`); values.push(data.farbe); idx++; }
if (data.ist_abschluss !== undefined) { setClauses.push(`ist_abschluss = $${idx}`); values.push(data.ist_abschluss); idx++; }
if (data.ist_initial !== undefined) { setClauses.push(`ist_initial = $${idx}`); values.push(data.ist_initial); idx++; }
if (data.benoetigt_typ_freigabe !== undefined) { setClauses.push(`benoetigt_typ_freigabe = $${idx}`); values.push(data.benoetigt_typ_freigabe); idx++; }
if (data.sort_order !== undefined) { setClauses.push(`sort_order = $${idx}`); values.push(data.sort_order); idx++; }
if (data.aktiv !== undefined) { setClauses.push(`aktiv = $${idx}`); values.push(data.aktiv); idx++; }
if (setClauses.length === 0) {
const r = await pool.query(`SELECT * FROM issue_statuses WHERE id = $1`, [id]);
return r.rows[0] || null;
}
values.push(id);
const result = await pool.query(
`UPDATE issue_statuses SET ${setClauses.join(', ')} WHERE id = $${idx} RETURNING *`,
values
);
return result.rows[0] || null;
} catch (error) {
logger.error('IssueService.updateIssueStatus failed', { error, id });
throw new Error('Issue-Status konnte nicht aktualisiert werden');
}
}
async function deleteIssueStatus(id: number) {
try {
const result = await pool.query(
`UPDATE issue_statuses SET aktiv = false WHERE id = $1 RETURNING *`,
[id]
);
return result.rows[0] || null;
} catch (error) {
logger.error('IssueService.deleteIssueStatus failed', { error, id });
throw new Error('Issue-Status konnte nicht deaktiviert werden');
}
}
async function getIssuePriorities() {
try {
const result = await pool.query(
`SELECT * FROM issue_prioritaeten ORDER BY sort_order ASC, id ASC`
);
return result.rows;
} catch (error) {
logger.error('IssueService.getIssuePriorities failed', { error });
throw new Error('Issue-Prioritäten konnten nicht geladen werden');
}
}
async function createIssuePriority(data: {
schluessel: string;
bezeichnung: string;
farbe?: string;
sort_order?: number;
}) {
try {
const result = await pool.query(
`INSERT INTO issue_prioritaeten (schluessel, bezeichnung, farbe, sort_order)
VALUES ($1, $2, $3, $4)
RETURNING *`,
[data.schluessel, data.bezeichnung, data.farbe ?? '#9e9e9e', data.sort_order ?? 0]
);
return result.rows[0];
} catch (error) {
logger.error('IssueService.createIssuePriority failed', { error });
throw new Error('Priorität konnte nicht erstellt werden');
}
}
async function updateIssuePriority(id: number, data: {
bezeichnung?: string;
farbe?: string;
sort_order?: number;
aktiv?: boolean;
}) {
try {
const setClauses: string[] = [];
const values: any[] = [];
let idx = 1;
if (data.bezeichnung !== undefined) { setClauses.push(`bezeichnung = $${idx}`); values.push(data.bezeichnung); idx++; }
if (data.farbe !== undefined) { setClauses.push(`farbe = $${idx}`); values.push(data.farbe); idx++; }
if (data.sort_order !== undefined) { setClauses.push(`sort_order = $${idx}`); values.push(data.sort_order); idx++; }
if (data.aktiv !== undefined) { setClauses.push(`aktiv = $${idx}`); values.push(data.aktiv); idx++; }
if (setClauses.length === 0) {
const r = await pool.query(`SELECT * FROM issue_prioritaeten WHERE id = $1`, [id]);
return r.rows[0] || null;
}
values.push(id);
const result = await pool.query(
`UPDATE issue_prioritaeten SET ${setClauses.join(', ')} WHERE id = $${idx} RETURNING *`,
values
);
return result.rows[0] || null;
} catch (error) {
logger.error('IssueService.updateIssuePriority failed', { error, id });
throw new Error('Priorität konnte nicht aktualisiert werden');
}
}
async function deleteIssuePriority(id: number) {
try {
const result = await pool.query(
`UPDATE issue_prioritaeten SET aktiv = false WHERE id = $1 RETURNING *`,
[id]
);
return result.rows[0] || null;
} catch (error) {
logger.error('IssueService.deleteIssuePriority failed', { error, id });
throw new Error('Priorität konnte nicht deaktiviert werden');
}
}
async function getStatusmeldungen() {
try {
const result = await pool.query(
@@ -465,6 +647,14 @@ export default {
deactivateType,
getAssignableMembers,
getIssueCounts,
getIssueStatuses,
createIssueStatus,
updateIssueStatus,
deleteIssueStatus,
getIssuePriorities,
createIssuePriority,
updateIssuePriority,
deleteIssuePriority,
getStatusmeldungen,
createStatusmeldung,
updateStatusmeldung,