fix: Wire real data sources across players, analytics, status, and maps services
All checks were successful
Test Asgard Runner / test (push) Successful in 3s
All checks were successful
Test Asgard Runner / test (push) Successful in 3s
- players: Primary data from player_sessions (online status, playtime aggregates);
ban/unban status overlaid from player_actions latest action per steam_id.
Register PlayerSession entity in PlayersModule. Extend NATS forwarding to
include 'unban' alongside kick and ban.
- analytics: Fix retention period boundary bug — sessions were queried with only
a lower-bound filter (MoreThan), causing all future cycles to bleed into earlier
wipe windows. Replaced with Between(wipeDate, endDate) for correct isolation.
- status: Replace hardcoded player_count=0/max_players=0 with live data from
most-recent server_stats row per license. Register ServerStats entity in
StatusModule. Falls back to 0 gracefully when no stats exist yet.
- maps: File buffer was computed and discarded — never written to disk.
Now writes to /app/map_data/{licenseId}/{timestamp}_{filename} (tenant-isolated,
docker volume map_data). Creates directories with mkdirSync(recursive:true).
Logs success/failure via NestJS Logger. Throws 500 on disk write failure
instead of silently losing data.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository, MoreThan } from 'typeorm';
|
||||
import { Repository, MoreThan, Between } from 'typeorm';
|
||||
import { ServerStatsHourly } from '../../entities/server-stats-hourly.entity';
|
||||
import { ServerStats } from '../../entities/server-stats.entity';
|
||||
import { WipeHistory } from '../../entities/wipe-history.entity';
|
||||
@@ -169,13 +169,18 @@ export class AnalyticsService {
|
||||
const retentionData = await Promise.all(
|
||||
recentWipes.map(async (wipe) => {
|
||||
const wipeDate = wipe.started_at;
|
||||
const nextWipe = recentWipes.find(w => w.started_at && wipeDate && w.started_at > wipeDate);
|
||||
// Find the next wipe chronologically after this one (wipes are DESC ordered)
|
||||
const nextWipe = recentWipes
|
||||
.slice()
|
||||
.reverse()
|
||||
.find(w => w.started_at && wipeDate && w.started_at > wipeDate);
|
||||
const endDate = nextWipe?.started_at || new Date();
|
||||
|
||||
// Query sessions strictly within this wipe cycle: [wipeDate, endDate)
|
||||
const sessionsInPeriod = await this.playerSessionRepo.find({
|
||||
where: {
|
||||
license_id: licenseId,
|
||||
session_start: MoreThan(wipeDate!),
|
||||
session_start: Between(wipeDate!, endDate),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -183,6 +188,7 @@ export class AnalyticsService {
|
||||
|
||||
return {
|
||||
wipe_date: wipeDate,
|
||||
end_date: endDate,
|
||||
unique_players: uniquePlayers,
|
||||
total_sessions: sessionsInPeriod.length,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user