refactor(autoFetchMatchResultsService, MYTISCHTENNIS_AUTO_FETCH_README.md, Optimization TODO): enhance data processing and documentation

- Refactored the `autoFetchMatchResultsService` to separate single and double player statistics processing into distinct methods, improving code clarity and maintainability.
- Updated the README to reflect the current status of rating updates and match results, marking them as active and detailing their functionalities.
- Closed several TODOs in the optimization documentation, confirming the implementation of previously outlined tasks and ensuring no open inline TODOs remain in the main views.
This commit is contained in:
Torsten Schulz (local)
2026-03-17 16:04:10 +01:00
parent 6320c5ca72
commit 414c5ccee5
4 changed files with 125 additions and 85 deletions

View File

@@ -504,13 +504,6 @@ class AutoFetchMatchResultsService {
* Process and store team data from myTischtennis
*/
async processTeamData(team, data) {
// TODO: Implement data processing and storage
// This would typically involve:
// 1. Extract player statistics from data.data.balancesheet
// 2. Match players with local Member records (by player_id or name)
// 3. Update or create match statistics
// 4. Store historical data for tracking changes
devLog(`Processing data for team ${team.name}`);
if (!data.data || !data.data.balancesheet || !Array.isArray(data.data.balancesheet)) {
@@ -521,47 +514,8 @@ class AutoFetchMatchResultsService {
let processedCount = 0;
for (const teamData of data.data.balancesheet) {
// Process single player statistics
if (teamData.single_player_statistics) {
for (const playerStat of teamData.single_player_statistics) {
devLog(`Player: ${playerStat.player_firstname} ${playerStat.player_lastname} (ID: ${playerStat.player_id})`);
devLog(` Points won: ${playerStat.points_won}, Points lost: ${playerStat.points_lost}`);
// Try to match player with local Member
const member = await this.matchPlayer(
playerStat.player_id,
playerStat.player_firstname,
playerStat.player_lastname
);
if (member) {
devLog(` Matched with local member: ${member.firstName} ${member.lastName} (ID: ${member.id})`);
// Update player statistics (TTR/QTTR would be fetched from different endpoint)
// For now, we just ensure the myTischtennis ID is stored
if (!member.myTischtennisPlayerId) {
member.myTischtennisPlayerId = playerStat.player_id;
await member.save();
devLog(` Updated myTischtennis Player ID for ${member.firstName} ${member.lastName}`);
}
} else {
devLog(` No local member found for ${playerStat.player_firstname} ${playerStat.player_lastname}`);
}
processedCount++;
}
}
// Process double player statistics
if (teamData.double_player_statistics) {
for (const doubleStat of teamData.double_player_statistics) {
devLog(`Double: ${doubleStat.firstname_player_1} ${doubleStat.lastname_player_1} / ${doubleStat.firstname_player_2} ${doubleStat.lastname_player_2}`);
devLog(` Points won: ${doubleStat.points_won}, Points lost: ${doubleStat.points_lost}`);
// TODO: Store double statistics
processedCount++;
}
}
processedCount += await this.processSinglePlayerStatistics(teamData);
processedCount += await this.processDoublePlayerStatistics(teamData);
}
// Also process meetings from the player stats response
@@ -579,6 +533,95 @@ class AutoFetchMatchResultsService {
return processedCount;
}
async processSinglePlayerStatistics(teamData) {
if (!Array.isArray(teamData.single_player_statistics)) {
return 0;
}
let processedCount = 0;
for (const playerStat of teamData.single_player_statistics) {
devLog(`Player: ${playerStat.player_firstname} ${playerStat.player_lastname} (ID: ${playerStat.player_id})`);
devLog(` Points won: ${playerStat.points_won}, Points lost: ${playerStat.points_lost}`);
const member = await this.matchPlayer(
playerStat.player_id,
playerStat.player_firstname,
playerStat.player_lastname
);
if (member) {
devLog(` Matched with local member: ${member.firstName} ${member.lastName} (ID: ${member.id})`);
await this.ensureMemberPlayerId(member, playerStat.player_id);
} else {
devLog(` No local member found for ${playerStat.player_firstname} ${playerStat.player_lastname}`);
}
processedCount++;
}
return processedCount;
}
async processDoublePlayerStatistics(teamData) {
if (!Array.isArray(teamData.double_player_statistics)) {
return 0;
}
let processedCount = 0;
for (const doubleStat of teamData.double_player_statistics) {
const firstPlayerLabel = `${doubleStat.firstname_player_1} ${doubleStat.lastname_player_1}`.trim();
const secondPlayerLabel = `${doubleStat.firstname_player_2} ${doubleStat.lastname_player_2}`.trim();
devLog(`Double: ${firstPlayerLabel} / ${secondPlayerLabel}`);
devLog(` Points won: ${doubleStat.points_won}, Points lost: ${doubleStat.points_lost}`);
const [memberOne, memberTwo] = await Promise.all([
this.matchPlayer(
doubleStat.player_id_1 || doubleStat.player_1_id || null,
doubleStat.firstname_player_1,
doubleStat.lastname_player_1
),
this.matchPlayer(
doubleStat.player_id_2 || doubleStat.player_2_id || null,
doubleStat.firstname_player_2,
doubleStat.lastname_player_2
)
]);
if (memberOne) {
await this.ensureMemberPlayerId(memberOne, doubleStat.player_id_1 || doubleStat.player_1_id || null);
} else {
devLog(` No local member found for double player 1: ${firstPlayerLabel}`);
}
if (memberTwo) {
await this.ensureMemberPlayerId(memberTwo, doubleStat.player_id_2 || doubleStat.player_2_id || null);
} else {
devLog(` No local member found for double player 2: ${secondPlayerLabel}`);
}
if (memberOne && memberTwo) {
devLog(` Matched double with local members: ${memberOne.firstName} ${memberOne.lastName} / ${memberTwo.firstName} ${memberTwo.lastName}`);
}
processedCount++;
}
return processedCount;
}
async ensureMemberPlayerId(member, playerId) {
if (!playerId || member.myTischtennisPlayerId) {
return;
}
member.myTischtennisPlayerId = playerId;
await member.save();
devLog(` Updated myTischtennis Player ID for ${member.firstName} ${member.lastName}`);
}
/**
* Process match results from schedule/table data
*/