dbd90ee52a
Player-service play-session tracker (floor + 3-bucket classify), SharePopover share tracker with debounce, sendBeacon interop, proxied rate-limited POST api/event/{play,share}, append-only event logs + incremental play_counter with server-side release resolution. Migration authored, not applied. No anonId, no read surface.
35 lines
1.4 KiB
C#
35 lines
1.4 KiB
C#
using DeepDrftModels.Enums;
|
|
|
|
namespace DeepDrftModels.Entities;
|
|
|
|
/// <summary>
|
|
/// Append-only log row for one recorded share (Phase 16 §4.2). Written once per share action that
|
|
/// survives the per-(target,channel) client debounce; never updated or deleted. Like <see cref="PlayEvent"/>
|
|
/// it is deliberately NOT a <c>BaseEntity</c> — an immutable fact with no soft-delete lifecycle. Shares
|
|
/// carry their target directly (the popover knows track vs. release), so no server-side resolution step.
|
|
/// </summary>
|
|
public class ShareEvent
|
|
{
|
|
public long Id { get; set; }
|
|
|
|
/// <summary>Whether the share targets a track or a release.</summary>
|
|
public ShareTargetType TargetType { get; set; }
|
|
|
|
/// <summary>
|
|
/// The shared target's key: a track's vault <c>EntryKey</c> or a release's public <c>EntryKey</c>,
|
|
/// selected by <see cref="TargetType"/>. Stored as the opaque key, not resolved to a SQL id — the
|
|
/// share metric is a simple per-target tally and needs no join in wave 16.1.
|
|
/// </summary>
|
|
public required string TargetKey { get; set; }
|
|
|
|
/// <summary>The channel the share was performed through (link vs. embed).</summary>
|
|
public ShareChannel Channel { get; set; }
|
|
|
|
/// <summary>
|
|
/// Anonymous listener token (Phase 16 §3, wave 16.3). Reserved nullable; unused in wave 16.1.
|
|
/// </summary>
|
|
public string? AnonId { get; set; }
|
|
|
|
public DateTime CreatedAt { get; set; }
|
|
}
|