Freigabe durch die Leitung innerhalb von Grenzen (#687)
- UnitConfig.Approvals: Operationen, Hoechstzahl je Tag, Stunden je Freigabe; nur der Mensch setzt sie (OrgAdministration.SetApprovals mit Audit, Teilmengenregel nach oben, Senken oben senkt unten mit; Agentenaenderungen/Sonderbudget nie freigebbar) - LeadApprovals: Vorlage geht an die naechste Leitung, deren Einheit die Operation erlaubt; nie eigene Aufrufe, nie eine Leitung mit Fremdinhalt, Tagesdeckel, Frist. Entscheidung ueber Escalation approve_call/reject_call, im Audit als lead:<id> - Der Mensch sieht alles und kann zuerst entscheiden; danach wird die Leitungsaufgabe geschlossen. Nach der Frist nur noch der Mensch. - StagedCalls: Approver, ApproverUntil, ApproverTaskId (Nachruestung) - WebUI: Hinweis "bei Leitung" in der Freigabestelle, Zaehler ohne diese, Quote je Leitung; Karte in der Organisationsansicht; i18n en/de - Tests: LeadApprovalsTests (13), OrgAdministrationTests (+2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
dafb8241a0
commit
f51186269c
@@ -251,6 +251,43 @@ public sealed class OrgAdministrationTests : IDisposable
|
||||
Find("newbie").UnitId.ShouldBe("amazon");
|
||||
}
|
||||
|
||||
// ═══════════════════ approvals by the lead (#687) ═══════════════════
|
||||
|
||||
private UnitConfig Unit(string id) => _test.Host.Instance.Units.Single(u => u.Id == id);
|
||||
|
||||
[Fact]
|
||||
public void A_unit_grants_its_lead_approvals_but_never_changes_to_agents()
|
||||
{
|
||||
BuildMarketing();
|
||||
|
||||
Org.SetApprovals("marketing", ["AgentEditor.update_soul"]).Message.ShouldContain("always stays with a human");
|
||||
Org.SetApprovals("marketing", ["AgentEditor"]).Ok.ShouldBeFalse("a whole tool with such an operation reads as a grant for it");
|
||||
Org.SetApprovals("marketing", [".x"]).Ok.ShouldBeFalse();
|
||||
|
||||
var set = Org.SetApprovals("marketing", ["Database.insert", "FileRW.delete"], perDay: 5, hours: 2, reason: "night shift");
|
||||
|
||||
set.Ok.ShouldBeTrue(set.Message);
|
||||
Unit("marketing").Approvals!.Operations.ShouldBe(["Database.insert", "FileRW.delete"]);
|
||||
Unit("marketing").Approvals!.PerDay.ShouldBe(5);
|
||||
Org.SetApprovals("marketing", []).Ok.ShouldBeTrue();
|
||||
Unit("marketing").Approvals.ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_sub_unit_grants_no_more_than_the_units_above_and_shrinks_with_them()
|
||||
{
|
||||
BuildMarketing();
|
||||
Org.SetApprovals("marketing", ["Database"]).Ok.ShouldBeTrue();
|
||||
|
||||
Org.SetApprovals("amazon", ["Mail.send"]).Message.ShouldContain("Marketing");
|
||||
Org.SetApprovals("amazon", ["Database.insert", "Database.update"]).Ok.ShouldBeTrue("'Database' above covers each of its operations");
|
||||
|
||||
var lowered = Org.SetApprovals("marketing", ["Database.insert"]);
|
||||
|
||||
lowered.Message.ShouldContain("Amazon");
|
||||
Unit("amazon").Approvals!.Operations.ShouldBe(["Database.insert"]);
|
||||
}
|
||||
|
||||
// ═══════════════════ the top (#690) ═══════════════════
|
||||
|
||||
private void MakeDecider(string id)
|
||||
|
||||
Reference in New Issue
Block a user