feat(phase-16): anonymous play & share telemetry substrate (wave 16.1)
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.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
using DeepDrftModels.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace DeepDrftData.Data.Configurations;
|
||||
|
||||
/// <summary>
|
||||
/// EF configuration for the <c>play_counter</c> rollup (Phase 16 §4.1 / D6). One row per track, unique
|
||||
/// on track_id so the incremental-on-write bump is an upsert against a single row. <c>TotalPlays</c> is
|
||||
/// a computed C# property (sum of the three bucket columns) and is not mapped — it is derived on read.
|
||||
/// </summary>
|
||||
public class PlayCounterConfiguration : IEntityTypeConfiguration<PlayCounter>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<PlayCounter> builder)
|
||||
{
|
||||
builder.ToTable("play_counter");
|
||||
|
||||
builder.HasKey(e => e.Id);
|
||||
builder.Property(e => e.Id).HasColumnName("id");
|
||||
|
||||
builder.Property(e => e.TrackId)
|
||||
.IsRequired()
|
||||
.HasColumnName("track_id");
|
||||
|
||||
builder.Property(e => e.PartialCount)
|
||||
.IsRequired()
|
||||
.HasDefaultValue(0L)
|
||||
.HasColumnName("partial_count");
|
||||
|
||||
builder.Property(e => e.SampledCount)
|
||||
.IsRequired()
|
||||
.HasDefaultValue(0L)
|
||||
.HasColumnName("sampled_count");
|
||||
|
||||
builder.Property(e => e.CompleteCount)
|
||||
.IsRequired()
|
||||
.HasDefaultValue(0L)
|
||||
.HasColumnName("complete_count");
|
||||
|
||||
// Derived headline figure — never a column.
|
||||
builder.Ignore(e => e.TotalPlays);
|
||||
|
||||
builder.HasIndex(e => e.TrackId)
|
||||
.IsUnique()
|
||||
.HasDatabaseName("IX_play_counter_track_id");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user