repo(viewer): add UDID lookup, anonymous register, Steam link helpers
Extracts the default-loadout body into a private BuildDefaultViewer helper shared by the existing Steam-import path and a new RegisterAnonymousViewer for /tool/signup. LinkSteamToViewer is the seam SteamSessionAuthenticationHandler will call on first-Steam-touch of a UDID-keyed viewer. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -70,6 +70,58 @@ public class ViewerRepository : IViewerRepository
|
||||
|
||||
public async Task<Models.Viewer> RegisterViewer(string displayName, SocialAccountType socialType,
|
||||
ulong socialAccountIdentifier, ulong? shortUdid = null)
|
||||
{
|
||||
var viewer = await BuildDefaultViewer(displayName);
|
||||
viewer.SocialAccountConnections.Add(new SocialAccountConnection
|
||||
{
|
||||
AccountId = socialAccountIdentifier,
|
||||
AccountType = socialType
|
||||
});
|
||||
_dbContext.Set<Models.Viewer>().Add(viewer);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
return viewer;
|
||||
}
|
||||
|
||||
public async Task<Models.Viewer?> GetViewerByUdid(Guid udid)
|
||||
{
|
||||
if (udid == Guid.Empty) return null;
|
||||
return await _dbContext.Set<Models.Viewer>()
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(v => v.Udid == udid);
|
||||
}
|
||||
|
||||
public async Task<Models.Viewer> RegisterAnonymousViewer(Guid udid)
|
||||
{
|
||||
if (udid == Guid.Empty)
|
||||
throw new InvalidOperationException("Cannot register viewer for empty UDID.");
|
||||
|
||||
var viewer = await BuildDefaultViewer("Player");
|
||||
viewer.Udid = udid;
|
||||
_dbContext.Set<Models.Viewer>().Add(viewer);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
return viewer;
|
||||
}
|
||||
|
||||
public async Task LinkSteamToViewer(long viewerId, ulong steamId)
|
||||
{
|
||||
var viewer = await _dbContext.Set<Models.Viewer>()
|
||||
.Include(v => v.SocialAccountConnections)
|
||||
.FirstOrDefaultAsync(v => v.Id == viewerId)
|
||||
?? throw new InvalidOperationException($"Viewer {viewerId} not found for Steam link.");
|
||||
|
||||
bool alreadyLinked = viewer.SocialAccountConnections.Any(sac =>
|
||||
sac.AccountType == SocialAccountType.Steam && sac.AccountId == steamId);
|
||||
if (alreadyLinked) return;
|
||||
|
||||
viewer.SocialAccountConnections.Add(new SocialAccountConnection
|
||||
{
|
||||
AccountId = steamId,
|
||||
AccountType = SocialAccountType.Steam
|
||||
});
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
private async Task<Models.Viewer> BuildDefaultViewer(string displayName)
|
||||
{
|
||||
Models.Viewer viewer = new Models.Viewer
|
||||
{
|
||||
@@ -79,12 +131,6 @@ public class ViewerRepository : IViewerRepository
|
||||
var grants = _config.Get<DefaultGrantsConfig>();
|
||||
var loadout = _config.Get<DefaultLoadoutConfig>();
|
||||
|
||||
viewer.SocialAccountConnections.Add(new SocialAccountConnection
|
||||
{
|
||||
AccountId = socialAccountIdentifier,
|
||||
AccountType = socialType
|
||||
});
|
||||
|
||||
viewer.Info.MaxFriends = player.MaxFriends;
|
||||
viewer.Info.CountryCode = "KOR";
|
||||
viewer.Info.BirthDate = DateTime.UtcNow;
|
||||
@@ -124,8 +170,6 @@ public class ViewerRepository : IViewerRepository
|
||||
if (defaultEmblem is not null) viewer.Emblems.Add(defaultEmblem);
|
||||
if (defaultBg is not null) viewer.MyPageBackgrounds.Add(defaultBg);
|
||||
|
||||
// Grant one of each class's default leader skin. Filter out the synthetic placeholders
|
||||
// (Id=0) and dedupe — skins are many-to-many via SleeveEntryViewer-style join.
|
||||
var grantedSkins = viewer.Classes
|
||||
.Select(vcd => vcd.LeaderSkin)
|
||||
.Where(s => s.Id != 0)
|
||||
@@ -133,8 +177,6 @@ public class ViewerRepository : IViewerRepository
|
||||
.ToList();
|
||||
viewer.LeaderSkins.AddRange(grantedSkins);
|
||||
|
||||
_dbContext.Set<Models.Viewer>().Add(viewer);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
return viewer;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user