feat(missions): /mission/info, /mission/retire, /mission/change_receive_setting
Three endpoints + 9 integration tests. Captured-data-is-catalog: viewer's achievement Level starts at MIN(Level) per type from the catalog (not 1), so the assembler always has a row to render against. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -38,17 +38,19 @@ public sealed class ViewerMissionStateService : IViewerMissionStateService
|
||||
|
||||
private async Task MaterializeAchievementsAsync(long viewerId, List<ViewerAchievement> existing, CancellationToken ct)
|
||||
{
|
||||
var catalogTypes = await _catalog.GetAllAchievementTypesAsync(ct);
|
||||
if (catalogTypes.Count == 0) return;
|
||||
var minLevelByType = await _catalog.GetMinLevelByAchievementTypeAsync(ct);
|
||||
if (minLevelByType.Count == 0) return;
|
||||
var existingTypes = existing.Select(a => a.AchievementType).ToHashSet();
|
||||
foreach (var type in catalogTypes)
|
||||
foreach (var (type, minLevel) in minLevelByType)
|
||||
{
|
||||
if (existingTypes.Contains(type)) continue;
|
||||
// Start at the lowest captured tier — with captured-data-is-catalog, a "fresh" viewer
|
||||
// is conceptually at whichever tier we first know about for that type.
|
||||
_viewerRepo.AddAchievement(new ViewerAchievement
|
||||
{
|
||||
ViewerId = viewerId,
|
||||
AchievementType = type,
|
||||
Level = 1,
|
||||
Level = minLevel,
|
||||
AchievementStatus = 0,
|
||||
NowAchievedLevel = 0,
|
||||
ResultAnnounceSawLevel = 0,
|
||||
|
||||
Reference in New Issue
Block a user