fix(issues): allow priority+status change for assignees, dynamic owner transitions, kanban droppable columns; feat(persoenliche-ausruestung): configurable zustand
This commit is contained in:
@@ -116,18 +116,24 @@ class IssueController {
|
||||
updateData = { ...req.body };
|
||||
// Explicit null for unassign is handled by 'zugewiesen_an' in data check in service
|
||||
} else if (canChangeStatus || isAssignee) {
|
||||
// Can only change status (+ kommentar is handled separately)
|
||||
// Can change status and priority (+ kommentar is handled separately)
|
||||
updateData = {};
|
||||
if (req.body.status !== undefined) updateData.status = req.body.status;
|
||||
if (req.body.prioritaet !== undefined) updateData.prioritaet = req.body.prioritaet;
|
||||
} else if (isOwner) {
|
||||
// Owner without change_status: can only close own issue or reopen from erledigt
|
||||
// Owner without change_status: can only close own issue or reopen from terminal status
|
||||
updateData = {};
|
||||
if (req.body.status !== undefined) {
|
||||
const newStatus = req.body.status;
|
||||
if (newStatus === 'erledigt') {
|
||||
updateData.status = 'erledigt';
|
||||
} else if (newStatus === 'offen' && existing.status === 'erledigt') {
|
||||
// Reopen: require kommentar
|
||||
const allStatuses = await issueService.getIssueStatuses();
|
||||
const targetDef = allStatuses.find((s: any) => s.schluessel === newStatus);
|
||||
const currentDef = allStatuses.find((s: any) => s.schluessel === existing.status);
|
||||
|
||||
if (targetDef?.ist_abschluss) {
|
||||
// Owner can close with any terminal status
|
||||
updateData.status = newStatus;
|
||||
} else if (targetDef?.ist_initial && currentDef?.ist_abschluss) {
|
||||
// Owner can reopen from terminal → initial (requires kommentar)
|
||||
if (!req.body.kommentar || typeof req.body.kommentar !== 'string' || req.body.kommentar.trim().length === 0) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
@@ -135,7 +141,7 @@ class IssueController {
|
||||
});
|
||||
return;
|
||||
}
|
||||
updateData.status = 'offen';
|
||||
updateData.status = newStatus;
|
||||
} else {
|
||||
res.status(403).json({ success: false, message: 'Keine Berechtigung für diese Statusänderung' });
|
||||
return;
|
||||
@@ -192,13 +198,18 @@ class IssueController {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle reopen comment (owner reopen flow)
|
||||
if (isOwner && !canChangeStatus && req.body.status === 'offen' && existing.status === 'erledigt' && req.body.kommentar) {
|
||||
await issueService.addComment(id, userId, `[Wiedereröffnet] ${req.body.kommentar.trim()}`);
|
||||
}
|
||||
|
||||
// If kommentar was provided alongside a status change (not the reopen flow above)
|
||||
if (req.body.kommentar && updateData.status && !(isOwner && !canChangeStatus && req.body.status === 'offen' && existing.status === 'erledigt')) {
|
||||
// Handle reopen comment (owner reopen flow: terminal → initial)
|
||||
if (isOwner && !canChangeStatus && updateData.status && req.body.kommentar) {
|
||||
const allStatusesForComment = await issueService.getIssueStatuses();
|
||||
const targetForComment = allStatusesForComment.find((s: any) => s.schluessel === updateData.status);
|
||||
const currentForComment = allStatusesForComment.find((s: any) => s.schluessel === existing.status);
|
||||
if (targetForComment?.ist_initial && currentForComment?.ist_abschluss) {
|
||||
await issueService.addComment(id, userId, `[Wiedereröffnet] ${req.body.kommentar.trim()}`);
|
||||
} else if (req.body.kommentar && updateData.status) {
|
||||
await issueService.addComment(id, userId, req.body.kommentar.trim());
|
||||
}
|
||||
} else if (req.body.kommentar && updateData.status) {
|
||||
// If kommentar was provided alongside a status change (non-owner flow)
|
||||
await issueService.addComment(id, userId, req.body.kommentar.trim());
|
||||
}
|
||||
|
||||
|
||||
@@ -41,11 +41,13 @@ const BASE_SELECT = `
|
||||
SELECT pa.*,
|
||||
COALESCE(u.given_name || ' ' || u.family_name, u.name) AS user_display_name,
|
||||
aa.bezeichnung AS artikel_bezeichnung,
|
||||
akk.name AS artikel_kategorie_name
|
||||
akk.name AS artikel_kategorie_name,
|
||||
akk_parent.name AS artikel_kategorie_parent_name
|
||||
FROM persoenliche_ausruestung pa
|
||||
LEFT JOIN users u ON u.id = pa.user_id
|
||||
LEFT JOIN ausruestung_artikel aa ON aa.id = pa.artikel_id
|
||||
LEFT JOIN ausruestung_kategorien_katalog akk ON akk.id = aa.kategorie_id
|
||||
LEFT JOIN ausruestung_kategorien_katalog akk_parent ON akk_parent.id = akk.parent_id
|
||||
WHERE pa.geloescht_am IS NULL
|
||||
`;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user