fix(audit léger): stats carrière, présence amis, AddGenericId
Build & Deploy / build (push) Successful in 43s

- GetPlayerStatisticsRequestsClient: renvoyait vide -> renvoie les stats demandées
  (0 pour l'instant, raid client-hosted non traçable) pour que l'écran carrière s'affiche.
- UpdatePlayerPresenceState: persiste {inMatch,lastSeenUtc}; GetFriendList lit la présence
  et calcule onlineState (online si vu <3min, 2=en raid) au lieu de 0 en dur.
- AddGenericId: persiste l'id de service lié (était un no-op).
(Free-loadout non touché: S3 only, pas de free-loadout en S2.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 09:02:45 +02:00
co-authored by Claude Opus 4.8
parent 1b4c1b2606
commit 0a68a97291
4 changed files with 85 additions and 15 deletions
@@ -1,12 +1,51 @@
using Prospect.Server.Api.Services.CloudScript.Models;
using System.Text.Json;
using System.Text.Json.Serialization;
using Prospect.Server.Api.Services.Auth.Extensions;
using Prospect.Server.Api.Services.CloudScript.Models;
using Prospect.Server.Api.Services.UserData;
namespace Prospect.Server.Api.Services.CloudScript.Functions;
// Persisted presence, read back by GetFriendList to show friends' online / in-match state.
public class PlayerPresenceState
{
[JsonPropertyName("inMatch")]
public bool InMatch { get; set; }
[JsonPropertyName("lastSeenUtc")]
public long LastSeenUtc { get; set; }
}
[CloudScriptFunction("UpdatePlayerPresenceState")]
public class UpdatePlayerPresenceState : ICloudScriptFunction<FYUpdatePlayerPresenceStateRequest, object>
{
public Task<object> ExecuteAsync(FYUpdatePlayerPresenceStateRequest request)
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly UserDataService _userDataService;
public UpdatePlayerPresenceState(IHttpContextAccessor httpContextAccessor, UserDataService userDataService)
{
return Task.FromResult<object>(new { });
_httpContextAccessor = httpContextAccessor;
_userDataService = userDataService;
}
}
public async Task<object> ExecuteAsync(FYUpdatePlayerPresenceStateRequest request)
{
var context = _httpContextAccessor.HttpContext;
if (context == null)
{
return new { };
}
var userId = context.User.FindAuthUserId();
var state = new PlayerPresenceState
{
InMatch = request.InMatch,
LastSeenUtc = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
};
await _userDataService.UpdateAsync(
userId, userId,
new Dictionary<string, string> { ["PresenceState"] = JsonSerializer.Serialize(state) }
);
return new { };
}
}