Update wire protocol to version 7 and enhance presence management features
ci / server (push) Failing after 3m44s
ci / client (push) Successful in 15s

- Bumped the wire protocol version to 7, reflecting significant changes in the communication structure.
- Introduced a new presence message type for real-time occupancy updates, including node activity and individual presence states.
- Updated the API to include a directory endpoint for fetching short id→name mappings, improving client-side name resolution.
- Revised the map snapshot structure to be static, with people and current lessons now handled through the presence stream.
- Enhanced client-side handling of presence updates, including UI adjustments to display live occupancy and activity.
- Updated documentation to reflect the new protocol features and changes in presence management.
- Added tests to validate the new presence functionalities and ensure robust handling of real-time data.
This commit is contained in:
Leonid Pershin
2026-08-19 17:00:53 +03:00
parent 4137400621
commit 3c54f981b7
31 changed files with 1025 additions and 373 deletions
@@ -81,6 +81,32 @@ public class PeopleApiTests(AppHostFixture fixture)
Assert.Empty(staff.People);
}
[Fact]
public async Task Directory_ListsRosterIdsAndNames()
{
using var client = fixture.App.CreateHttpClient("server");
await SchoolApiTests.ResetAsync(client);
var school = await SchoolApiTests.CreateAsync(client, "Справочник", Start);
var directory = await client.GetFromJsonAsync<DirectoryResponse>(
$"/api/schools/{school.Id}/directory",
TestContext.Current.CancellationToken);
Assert.NotNull(directory);
Assert.NotEmpty(directory.People);
Assert.All(directory.People, person =>
{
Assert.False(string.IsNullOrWhiteSpace(person.Id));
Assert.False(string.IsNullOrWhiteSpace(person.FullName));
});
var page = await GetPeopleAsync(client, school.Id, "pageSize=10");
Assert.Contains(directory.People, person => person.Id == page.People[0].Id && person.FullName == page.People[0].FullName);
using var missing = await client.GetAsync("/api/schools/999999/directory", TestContext.Current.CancellationToken);
Assert.Equal(HttpStatusCode.NotFound, missing.StatusCode);
Assert.Equal("unknown-school", await ProblemCodeAsync(missing));
}
[Fact]
public async Task List_UnknownSchool_IsNotFound()
{
@@ -204,4 +230,8 @@ public class PeopleApiTests(AppHostFixture fixture)
IReadOnlyList<PersonRelResponse> Partners);
private sealed record PersonRelResponse(string Id, string FullName, bool Female);
private sealed record DirectoryResponse(IReadOnlyList<DirectoryPersonResponse> People);
private sealed record DirectoryPersonResponse(string Id, string FullName);
}