Brett je Einheit, Stufe 3: Aufgaben sehen, wer sie sehen soll (#684)
- TaskBoard: das Brett einer Aufgabe wird nicht gespeichert, es folgt aus der Organisation - Einheit des Zustaendigen, sonst des Anlegers. Offene Aufgaben ziehen damit beim Umzug mit. Sichtbar: das eigene Brett, fuer eine Leitung alle darunter, und was man selbst angelegt hat (nach oben Gereichtes bleibt im Blick). - TaskItem.CreatedBy, in der Datei als created_by und in der DB. Ein Import aus einer Datei ohne das Feld behaelt, was die DB weiss. - Taskboard-Tool: task_list, task_find und die Dublettenpruefung sehen nur die eigenen Bretter - eine aehnliche Buchhaltungsaufgabe haelt keine Marketingaufgabe auf und bekommt keinen Kommentar von dort. task_update und task_comment antworten auf eine fremde Aufgabe wie auf eine unbekannte. - TaskboardService.ListAsync mit Sichtfilter: erst filtern, dann kappen. - WebUI: jede Aufgabe nennt ihr Brett, ein Filter waehlt eines aus. - Konzept (Abschnitt 3) und Einrichtungshandbuch nachgetragen. Ohne Einheiten aendert sich nichts - ein Brett fuer alle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
609298dd7a
commit
29d953a5eb
@@ -117,7 +117,11 @@ public sealed record TaskDto(
|
||||
DateTime? NextRunUtc = null,
|
||||
TaskLastRunDto? LastRun = null,
|
||||
string? Hinweis = null,
|
||||
TaskBudgetMissDto? BudgetMiss = null);
|
||||
TaskBudgetMissDto? BudgetMiss = null,
|
||||
string? CreatedBy = null,
|
||||
// #684: the unit whose board the task is on, computed from the organisation; null on the top level.
|
||||
string? Board = null,
|
||||
string? BoardPath = null);
|
||||
|
||||
/// <summary>
|
||||
/// #716: Runs of this task the budget refused — only present while something is open
|
||||
|
||||
@@ -153,7 +153,16 @@ internal static class Mapping
|
||||
BudgetMiss: task.BudgetMissCount > 0 || task.CatchUpPending || task.DeferredUntil is not null
|
||||
? new TaskBudgetMissDto(task.BudgetMissCount, task.LastBudgetMissAt, task.DeferredUntil,
|
||||
task.CatchUpPending, task.IsCarriedOver)
|
||||
: null);
|
||||
: null,
|
||||
CreatedBy: string.IsNullOrWhiteSpace(task.CreatedBy) ? null : task.CreatedBy);
|
||||
|
||||
/// <summary>#684: The board of a task, for a list the human sees whole.</summary>
|
||||
public static TaskDto WithBoard(this TaskDto dto, TaskItem task, Core.Organisation.OrgChart org)
|
||||
{
|
||||
if (!org.HasUnits || Core.Tasks.TaskBoard.UnitOf(task, org) is not { } unit)
|
||||
return dto;
|
||||
return dto with { Board = unit, BoardPath = org.PathOf(unit) };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ein wartender Aufruf samt seiner eingefrorenen Argumente.
|
||||
|
||||
@@ -260,9 +260,14 @@ internal static class ApiEndpoints
|
||||
// #594: Das Taskboard ist die einzige Stelle fuer geplante Arbeit. Die frueheren
|
||||
// /api/jobs bearbeiteten die Alt-Konfiguration, die nach der Uebernahme nichts mehr bewirkte.
|
||||
tasks.MapGet("/", async (AppHost host, CancellationToken ct, int limit = 50) =>
|
||||
await host.TaskAdmin.ListAsync(limit, ct) is { } list
|
||||
? Results.Ok(list.Select(t => t.ToDto()).ToList())
|
||||
: Unavailable("Kein Taskboard: Den Agenten dieser Instanz fehlt ein gemeinsamer Arbeitsbereich."));
|
||||
{
|
||||
if (await host.TaskAdmin.ListAsync(limit, ct) is not { } list)
|
||||
return Unavailable("Kein Taskboard: Den Agenten dieser Instanz fehlt ein gemeinsamer Arbeitsbereich.");
|
||||
|
||||
// #684: A human sees every board; each task says which one it is on.
|
||||
var org = host.Organisation.Current();
|
||||
return Results.Ok(list.Select(t => t.ToDto().WithBoard(t.Task, org)).ToList());
|
||||
});
|
||||
|
||||
tasks.MapPost("/", async (AppHost host, TaskInputDto input, CancellationToken ct) =>
|
||||
(await host.TaskAdmin.CreateAsync(input.ToInput(), ct)).ToResponse());
|
||||
|
||||
Reference in New Issue
Block a user