feat(missions): add 3 viewer entities + Viewer collections

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-05-27 10:08:11 -04:00
parent 9988ed85df
commit 062adefb99
4 changed files with 62 additions and 0 deletions

View File

@@ -59,6 +59,12 @@ public class Viewer : BaseEntity<long>
public List<ViewerBuildDeckProductPurchase> BuildDeckPurchases { get; set; } = new List<ViewerBuildDeckProductPurchase>();
public List<ViewerMission> Missions { get; set; } = new List<ViewerMission>();
public List<ViewerAchievement> Achievements { get; set; } = new List<ViewerAchievement>();
public List<ViewerEventCounter> EventCounters { get; set; } = new List<ViewerEventCounter>();
#endregion
#region Navigation Properties

View File

@@ -0,0 +1,17 @@
namespace SVSim.Database.Models;
/// <summary>
/// Per-viewer state for one achievement type. Composite PK (ViewerId, AchievementType) configured
/// in DbContext. <c>Level</c> is the viewer's current tier; <c>max_level</c> on the wire is
/// derived from catalog as MAX(Level) per type. Lazy-created at /load/index time — one row per
/// AchievementCatalogEntries.AchievementType that the viewer doesn't yet have a row for.
/// </summary>
public class ViewerAchievement
{
public long ViewerId { get; set; }
public int AchievementType { get; set; }
public int Level { get; set; } = 1;
public int AchievementStatus { get; set; }
public int NowAchievedLevel { get; set; }
public int ResultAnnounceSawLevel { get; set; }
}

View File

@@ -0,0 +1,15 @@
namespace SVSim.Database.Models;
/// <summary>
/// Per-viewer "how many times has this happened" counter. Composite PK
/// (ViewerId, EventKey, Period). Period strings: "all-time", "month:YYYY-MM",
/// "week:YYYY-W##", "day:YYYY-MM-DD" — all JST-anchored with 02:00 day-boundary.
/// Single source of truth for total_count / done_number on every wire shape.
/// </summary>
public class ViewerEventCounter
{
public long ViewerId { get; set; }
public string EventKey { get; set; } = "";
public string Period { get; set; } = "";
public int Count { get; set; }
}

View File

@@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations.Schema;
using SVSim.Database.Common;
namespace SVSim.Database.Models;
/// <summary>
/// One assigned mission slot for a viewer. <c>Id</c> is the wire <c>UserMission.id</c> — echoed
/// back as the retire-request parameter, auto-generated. Slot 0 = daily (lot_type=6),
/// Slots 1..3 = weekly (lot_type=2). Progress (<c>total_count</c> on the wire) is NOT stored
/// here — it's read from <see cref="ViewerEventCounter"/> at response-build time, keyed by the
/// catalog row's EventType.
/// </summary>
public class ViewerMission : BaseEntity<long>
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public override long Id { get; set; }
public long ViewerId { get; set; }
public int MissionCatalogId { get; set; }
public int Slot { get; set; }
public long AssignedAt { get; set; }
public long? ClaimedAt { get; set; }
public int MissionStatus { get; set; } = 1;
}