Wire up real implementations for Tracking & Config controllers
- TrackingController: Added database persistence for analytics events * Created AnalyticsEvent entity with user/session tracking * Store event type, data (JSON), and timestamp * Graceful fallback if DB write fails (game doesn't break) - ConfigController: Added real player counting * Query active sessions from last 15 minutes * Return actual player count instead of hardcoded 0 * Real-time server status with DB metrics - Added AnalyticsEvents table migration * Stores all game telemetry for analytics * Indexed by UserId for performance * JSON event data for flexibility Controllers now fully wired to database: - 11/18 controllers REAL implementation ✅ - 5/18 controllers STUB (config-based) ⚠️ - 2/18 controllers SERVICE (delegated) ⚠️ Total: 95 endpoints, improving from demo to production Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
1905
RR3CommunityServer/Migrations/20260224010029_AddAnalyticsTracking.Designer.cs
generated
Normal file
1905
RR3CommunityServer/Migrations/20260224010029_AddAnalyticsTracking.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace RR3CommunityServer.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddAnalyticsTracking : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AnalyticsEvents",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
EventType = table.Column<string>(type: "TEXT", nullable: false),
|
||||
UserId = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
SessionId = table.Column<string>(type: "TEXT", nullable: true),
|
||||
EventData = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Timestamp = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AnalyticsEvents", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_AnalyticsEvents_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id");
|
||||
});
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "TimeTrials",
|
||||
keyColumn: "Id",
|
||||
keyValue: 1,
|
||||
columns: new[] { "EndDate", "StartDate" },
|
||||
values: new object[] { new DateTime(2026, 3, 3, 1, 0, 29, 89, DateTimeKind.Utc).AddTicks(3271), new DateTime(2026, 2, 24, 1, 0, 29, 89, DateTimeKind.Utc).AddTicks(3268) });
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "TimeTrials",
|
||||
keyColumn: "Id",
|
||||
keyValue: 2,
|
||||
columns: new[] { "EndDate", "StartDate" },
|
||||
values: new object[] { new DateTime(2026, 3, 3, 1, 0, 29, 89, DateTimeKind.Utc).AddTicks(3281), new DateTime(2026, 2, 24, 1, 0, 29, 89, DateTimeKind.Utc).AddTicks(3280) });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AnalyticsEvents_UserId",
|
||||
table: "AnalyticsEvents",
|
||||
column: "UserId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "AnalyticsEvents");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "TimeTrials",
|
||||
keyColumn: "Id",
|
||||
keyValue: 1,
|
||||
columns: new[] { "EndDate", "StartDate" },
|
||||
values: new object[] { new DateTime(2026, 3, 3, 0, 53, 48, 427, DateTimeKind.Utc).AddTicks(9290), new DateTime(2026, 2, 24, 0, 53, 48, 427, DateTimeKind.Utc).AddTicks(9287) });
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "TimeTrials",
|
||||
keyColumn: "Id",
|
||||
keyValue: 2,
|
||||
columns: new[] { "EndDate", "StartDate" },
|
||||
values: new object[] { new DateTime(2026, 3, 3, 0, 53, 48, 427, DateTimeKind.Utc).AddTicks(9297), new DateTime(2026, 2, 24, 0, 53, 48, 427, DateTimeKind.Utc).AddTicks(9296) });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,36 @@ namespace RR3CommunityServer.Migrations
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.11");
|
||||
|
||||
modelBuilder.Entity("RR3CommunityServer.Data.AnalyticsEvent", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("EventData")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("EventType")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("SessionId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("Timestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AnalyticsEvents");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RR3CommunityServer.Data.Car", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -1375,10 +1405,10 @@ namespace RR3CommunityServer.Migrations
|
||||
Active = true,
|
||||
CarName = "Any Car",
|
||||
CashReward = 10000,
|
||||
EndDate = new DateTime(2026, 3, 3, 0, 53, 48, 427, DateTimeKind.Utc).AddTicks(9290),
|
||||
EndDate = new DateTime(2026, 3, 3, 1, 0, 29, 89, DateTimeKind.Utc).AddTicks(3271),
|
||||
GoldReward = 50,
|
||||
Name = "Daily Sprint Challenge",
|
||||
StartDate = new DateTime(2026, 2, 24, 0, 53, 48, 427, DateTimeKind.Utc).AddTicks(9287),
|
||||
StartDate = new DateTime(2026, 2, 24, 1, 0, 29, 89, DateTimeKind.Utc).AddTicks(3268),
|
||||
TargetTime = 90.5,
|
||||
TrackName = "Silverstone National"
|
||||
},
|
||||
@@ -1388,10 +1418,10 @@ namespace RR3CommunityServer.Migrations
|
||||
Active = true,
|
||||
CarName = "Any Car",
|
||||
CashReward = 25000,
|
||||
EndDate = new DateTime(2026, 3, 3, 0, 53, 48, 427, DateTimeKind.Utc).AddTicks(9297),
|
||||
EndDate = new DateTime(2026, 3, 3, 1, 0, 29, 89, DateTimeKind.Utc).AddTicks(3281),
|
||||
GoldReward = 100,
|
||||
Name = "Speed Demon Trial",
|
||||
StartDate = new DateTime(2026, 2, 24, 0, 53, 48, 427, DateTimeKind.Utc).AddTicks(9296),
|
||||
StartDate = new DateTime(2026, 2, 24, 1, 0, 29, 89, DateTimeKind.Utc).AddTicks(3280),
|
||||
TargetTime = 120.0,
|
||||
TrackName = "Dubai Autodrome"
|
||||
});
|
||||
@@ -1576,6 +1606,15 @@ namespace RR3CommunityServer.Migrations
|
||||
b.ToTable("UserSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RR3CommunityServer.Data.AnalyticsEvent", b =>
|
||||
{
|
||||
b.HasOne("RR3CommunityServer.Data.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RR3CommunityServer.Data.CareerProgress", b =>
|
||||
{
|
||||
b.HasOne("RR3CommunityServer.Data.User", null)
|
||||
|
||||
Reference in New Issue
Block a user