Enhance staffing management with uncovered teacher tracking
- Updated `protocol.md` to clarify the concept of uncovered subjects and the number of additional teachers required. - Introduced `teachersShort` property in the `StaffingSubject` interface to indicate how many more teachers are needed for a subject. - Enhanced localization strings to reflect the new uncovered teacher information in both English and Russian. - Updated the management panel UI to display the number of teachers short for each uncovered subject. - Revised the `Uncovered` method in the staffing logic to return detailed information about uncovered subjects, including the shortfall of teachers. - Added tests to validate the new uncovered teacher tracking functionality and ensure accurate reporting in the staffing API. - Marked related tasks as complete in the documentation for the golden fixtures phase.
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using HSchool.Content;
|
||||
|
||||
namespace HSchool.People.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Writes the host golden save files. Not a correctness test — run with WRITE_GOLDEN=1 after an
|
||||
/// intentional generation change, then commit the AppHost fixtures in the same change.
|
||||
/// </summary>
|
||||
public class GoldenSaveDump
|
||||
{
|
||||
[Fact]
|
||||
public void Dump_HostSaveFixtures_WhenAsked()
|
||||
{
|
||||
if (!string.Equals(Environment.GetEnvironmentVariable("WRITE_GOLDEN"), "1", StringComparison.Ordinal))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var catalog = Fixtures.Catalog();
|
||||
var map = TwoClassrooms();
|
||||
var roster = RosterGenerator.Generate(catalog, map, schoolSeed: 1, "Slavic", Fixtures.AsOf, "RussianLanguage");
|
||||
var pool = ApplicantPool.Create(catalog, roster, schoolSeed: 1, "Slavic", Fixtures.AsOf, "RussianLanguage");
|
||||
var people = RosterJson.Serialize(RosterDocument.From(1, roster, pool));
|
||||
var mapNode = JsonNode.Parse(JsonSerializer.Serialize(map, Jsonc.SerializerOptions));
|
||||
var current = SchoolJson(mapNode, includeNative: true);
|
||||
var legacy = SchoolJson(mapNode, includeNative: false);
|
||||
|
||||
var root = Path.Combine(Fixtures.RepoRoot(), "tests", "HSchool.AppHost.Tests", "golden");
|
||||
Write(Path.Combine(root, "current", "1.json"), current);
|
||||
Write(Path.Combine(root, "current", "1.people.json"), people);
|
||||
Write(Path.Combine(root, "legacy-no-native", "1.json"), legacy);
|
||||
Write(Path.Combine(root, "legacy-no-native", "1.people.json"), people);
|
||||
}
|
||||
|
||||
internal static MapLayout TwoClassrooms() =>
|
||||
new()
|
||||
{
|
||||
Territory = new TerritoryNode { Id = "yard", Def = "SchoolYard" },
|
||||
Buildings = [new BuildingNode { Id = "main", Def = "MainBuilding" }],
|
||||
Floors = [new FloorNode { Id = "floor-1", Def = "StandardFloor", Building = "main", Label = "1" }],
|
||||
Rooms =
|
||||
[
|
||||
new RoomNode
|
||||
{
|
||||
Id = "classroom-00",
|
||||
Def = "Classroom",
|
||||
Building = "main",
|
||||
Floor = "floor-1",
|
||||
Label = "101",
|
||||
Seats = 16,
|
||||
},
|
||||
new RoomNode
|
||||
{
|
||||
Id = "classroom-01",
|
||||
Def = "Classroom",
|
||||
Building = "main",
|
||||
Floor = "floor-1",
|
||||
Label = "102",
|
||||
Seats = 16,
|
||||
},
|
||||
],
|
||||
Links =
|
||||
[
|
||||
new MapLink { A = "yard", B = "classroom-00" },
|
||||
new MapLink { A = "yard", B = "classroom-01" },
|
||||
],
|
||||
};
|
||||
|
||||
private static string SchoolJson(JsonNode? map, bool includeNative)
|
||||
{
|
||||
var root = new JsonObject
|
||||
{
|
||||
["format"] = 2,
|
||||
["id"] = 1,
|
||||
["name"] = "Золотая",
|
||||
["gameTime"] = "2012-03-31T06:00:00Z",
|
||||
["running"] = false,
|
||||
["speedIndex"] = 1,
|
||||
["modIds"] = new JsonArray("core"),
|
||||
["map"] = map?.DeepClone(),
|
||||
["nameSetId"] = "Slavic",
|
||||
};
|
||||
if (includeNative)
|
||||
{
|
||||
root["nativeLanguage"] = "RussianLanguage";
|
||||
}
|
||||
|
||||
return root.ToJsonString(new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||
});
|
||||
}
|
||||
|
||||
private static void Write(string path, string contents)
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
|
||||
File.WriteAllText(path, contents);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user