diff --git a/SVSim.Database/Models/ViewerPresent.cs b/SVSim.Database/Models/ViewerPresent.cs
new file mode 100644
index 0000000..6527577
--- /dev/null
+++ b/SVSim.Database/Models/ViewerPresent.cs
@@ -0,0 +1,57 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace SVSim.Database.Models;
+
+///
+/// One row per gift in a viewer's inbox. Replaces the tutorial-only
+/// ViewerClaimedTutorialGift receipts model with a unified status-enum row that
+/// serves both /gift/top + /gift/receive_gift (prod) and /tutorial/gift_top +
+/// /tutorial/gift_receive (tutorial alias).
+///
+public class ViewerPresent
+{
+ public long Id { get; set; }
+
+ public long ViewerId { get; set; }
+ public Viewer Viewer { get; set; } = null!;
+
+ /// Wire id ("71409625" in the prod capture). String to match the wire.
+ public string PresentId { get; set; } = string.Empty;
+
+ public PresentStatus Status { get; set; }
+
+ /// UserGoodsType-compatible int. Wire is stringified — see PresentMapper.
+ public int RewardType { get; set; }
+ public long RewardDetailId { get; set; }
+ public long RewardCount { get; set; }
+ public int ConditionNumber { get; set; }
+ public int PresentLimitType { get; set; }
+ public long RewardLimitTime { get; set; }
+ public int? ItemType { get; set; }
+ public string Message { get; set; } = string.Empty;
+
+ public DateTime CreatedAt { get; set; }
+ public DateTime? ClaimedAt { get; set; }
+
+ ///
+ /// Free-form provenance tag for future producers ("tutorial", "challenge_win",
+ /// "payment_refund:<txid>", "event:<id>"). Nothing in the receive handler reads
+ /// this today — the tutorial-step advance is route-gated, not Source-gated.
+ ///
+ public string? Source { get; set; }
+
+ ///
+ /// EF Core optimistic concurrency for the claim path. Two concurrent claims of the
+ /// same PresentId: first wins, second's CommitAsync throws DbUpdateConcurrencyException.
+ ///
+ [Timestamp]
+ public byte[] RowVersion { get; set; } = Array.Empty();
+}
+
+public enum PresentStatus : byte
+{
+ Unclaimed = 0,
+ Claimed = 1,
+ Deleted = 2,
+ Expired = 3,
+}