Enhance school creation and staffing management with native language support
ci / server (push) Failing after 3m44s
ci / client (push) Successful in 14s

- Updated protocol documentation to include `nativeLanguages` in `nameSets` and added `nativeLanguage` to school creation options.
- Enhanced the UI for school creation to allow selection of native languages, improving user experience.
- Revised API interfaces to accommodate new native language features, ensuring proper data handling.
- Improved localization strings to support new native language functionalities in both English and Russian.
- Updated tests to validate the new native language features and ensure robust functionality in staffing scenarios.
This commit is contained in:
Leonid Pershin
2026-08-19 22:22:31 +03:00
parent 21d79cb49b
commit 5a00ad7746
48 changed files with 2064 additions and 312 deletions
+15 -8
View File
@@ -16,10 +16,11 @@ public sealed record ApplicantPool(int Week, int NextIndex, IReadOnlyList<Applic
Roster roster,
int schoolSeed,
string nameSetId,
DateTime asOf)
DateTime asOf,
string? nativeLanguage = null)
{
var week = ApplicantWeeks.Id(asOf);
return Fill(catalog, roster, schoolSeed, nameSetId, asOf, new ApplicantPool(week, 0, []));
return Fill(catalog, roster, schoolSeed, nameSetId, asOf, new ApplicantPool(week, 0, []), nativeLanguage: nativeLanguage);
}
/// <summary>
@@ -31,7 +32,8 @@ public sealed record ApplicantPool(int Week, int NextIndex, IReadOnlyList<Applic
Roster roster,
int schoolSeed,
string nameSetId,
DateTime asOf)
DateTime asOf,
string? nativeLanguage = null)
{
var target = ApplicantWeeks.Id(asOf);
if (target <= Week)
@@ -42,7 +44,7 @@ public sealed record ApplicantPool(int Week, int NextIndex, IReadOnlyList<Applic
var pool = this;
for (var week = Week + 1; week <= target; week++)
{
pool = Step(pool, catalog, roster, schoolSeed, nameSetId, asOf, week);
pool = Step(pool, catalog, roster, schoolSeed, nameSetId, asOf, week, nativeLanguage);
}
return pool;
@@ -93,7 +95,8 @@ public sealed record ApplicantPool(int Week, int NextIndex, IReadOnlyList<Applic
int schoolSeed,
string nameSetId,
DateTime asOf,
int week)
int week,
string? nativeLanguage)
{
var rules = RequireRules(catalog);
var rng = new Random(Seed.Mix(schoolSeed, week, Seed.ApplicantSalt));
@@ -113,7 +116,8 @@ public sealed record ApplicantPool(int Week, int NextIndex, IReadOnlyList<Applic
nameSetId,
asOf,
new ApplicantPool(week, current.NextIndex, staying),
rng);
rng,
nativeLanguage);
}
private static ApplicantPool Fill(
@@ -123,7 +127,8 @@ public sealed record ApplicantPool(int Week, int NextIndex, IReadOnlyList<Applic
string nameSetId,
DateTime asOf,
ApplicantPool current,
Random? rng = null)
Random? rng = null,
string? nativeLanguage = null)
{
var rules = RequireRules(catalog);
if (!catalog.NameSets.TryGetValue(nameSetId, out var names))
@@ -131,6 +136,8 @@ public sealed record ApplicantPool(int Week, int NextIndex, IReadOnlyList<Applic
throw new ArgumentException($"Unknown name set '{nameSetId}'.", nameof(nameSetId));
}
var native = NativeLanguages.Pick(names, schoolSeed, nativeLanguage, rollIfOmitted: false);
rng ??= new Random(Seed.Mix(schoolSeed, current.Week, Seed.ApplicantSalt));
var applicants = new List<Applicant>(rules.PoolSize);
var taken = new HashSet<string>(StringComparer.Ordinal);
@@ -163,7 +170,7 @@ public sealed record ApplicantPool(int Week, int NextIndex, IReadOnlyList<Applic
}
else
{
var (_, person) = FamilyFactory.CreateStaffOnly(catalog, names, schoolSeed, nextIndex, asOf);
var (_, person) = FamilyFactory.CreateStaffOnly(catalog, names, schoolSeed, nextIndex, asOf, nativeLanguage: native);
nextIndex++;
taken.Add(person.Id);
next = new Applicant(person, HourlyAsk(catalog, person));