Resolve external opponent TTR ratings and show lookup diagnostics
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 1m0s

This commit is contained in:
Torsten Schulz (local)
2026-10-28 11:03:46 +01:00
parent c473b64150
commit ecee9e0a00
6 changed files with 249 additions and 70 deletions

View File

@@ -640,6 +640,8 @@
</tbody></table>
</div>
<p v-if="ttrUnavailablePlayers.length" class="ttr-preview-empty">Noch ohne Wert: {{ ttrUnavailablePlayers.join(', ') }}.</p>
<p v-if="ttrPlayers.length" class="ttr-preview-empty">{{ ttrPlayers.length - ttrUnavailablePlayers.length }} von {{ ttrPlayers.length }} TTR-Werten geladen.</p>
<p v-for="(diagnostic, index) in ttrDiagnostics" :key="`ttr-diagnostic-${index}`" class="ttr-preview-empty" role="status">{{ diagnostic.message }}</p>
</div>
<div v-else-if="activeSection === 'completion'" class="completion-content">
@@ -954,6 +956,7 @@ export default {
ttrPlayers: [],
ttrLoading: false,
ttrError: '',
ttrDiagnostics: [],
// Fehlermeldungen für Satzeingaben
errors: [],
// Aktive Zelle der schwebenden Satz-Tastatur: { matchIndex, setIndex } oder null
@@ -3351,7 +3354,15 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
},
ttrLineupPlayers(side) {
const key = side === 'home' ? 'teamLineupHomePlayers' : 'teamLineupGuestPlayers';
return (this.meetingDetails?.[key] || []).filter((player) => player?.isSelected && player?.nuLigaPersonId > 0 && this.isSingleLineupPlayer(player));
const lineup = this.meetingDetails?.[key] || [];
// The displayed singles are authoritative, including older nuScore
// lineups without positionSingle/isSelected metadata.
const names = [...new Set(this.results.filter(match => !this.isTtrDouble(match))
.map(match => side === 'home' ? match.homeName : match.guestName).filter(Boolean))];
if (names.length) return names.map(name => lineup.find(player =>
this.normalizeTtrName([player.firstname || player.firstName, player.lastname || player.lastName].filter(Boolean).join(' ')) === this.normalizeTtrName(name)
) || { name });
return lineup.filter((player) => player?.isSelected && player?.nuLigaPersonId > 0 && this.isSingleLineupPlayer(player));
},
async openTtrSection() {
if (!this.canOpenTtrPreview) return;
@@ -3362,6 +3373,7 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
if (!this.canOpenTtrPreview || !this.meetingDetails) return;
this.ttrLoading = true;
this.ttrError = '';
this.ttrDiagnostics = [];
try {
if (this.standaloneTest) {
const response = await apiClient.post('/matches/ttr-preview/standalone', {
@@ -3370,7 +3382,10 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
guestPlayers: this.ttrLineupPlayers('guest'),
homeTeamName: this.meetingData?.homeTeamname,
guestTeamName: this.meetingData?.guestTeamname,
homeClubName: this.meetingData?.homeClub,
guestClubName: this.meetingData?.guestClub,
});
this.ttrDiagnostics = response.data?.diagnostics || [];
this.applyTtrPreviewPlayers(Array.isArray(response.data?.players) ? response.data.players : []);
return;
}
@@ -3383,7 +3398,10 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
guestPlayers: this.ttrLineupPlayers('guest'),
homeTeamName: this.meetingData?.homeTeamname,
guestTeamName: this.meetingData?.guestTeamname,
homeClubName: this.meetingData?.homeClub,
guestClubName: this.meetingData?.guestClub,
});
this.ttrDiagnostics = response.data?.diagnostics || [];
this.applyTtrPreviewPlayers(Array.isArray(response.data?.players) ? response.data.players : []);
} catch (error) {
this.ttrError = error.response?.data?.error || 'TTR-Werte konnten nicht geladen werden.';

View File

@@ -84,3 +84,40 @@ test('standalone test mode calls the API and keeps real pairings without inventi
assert.equal(rows[0].homeTtr, null);
assert.equal(rows[0].preview, null);
});
test('TTR requests include displayed singles even when legacy lineup metadata is missing', () => {
const report = dialog();
report.meetingDetails = { teamLineupHomePlayers: [{ firstname: 'Anton', lastname: 'Schottdorf', nuLigaPersonId: 123 }] };
const home = report.ttrLineupPlayers('home');
assert.equal(home.length, 1);
assert.equal(home[0].nuLigaPersonId, 123);
const guest = report.ttrLineupPlayers('guest');
assert.equal(guest.length, 1);
assert.equal(guest[0].name, 'Yumin Kim');
});
test('test mode on a saved report calls the real endpoint and exposes lookup diagnostics', async () => {
const report = dialog();
Object.assign(report, {
standaloneTest: false,
isTestMode: true,
canOpenTtrPreview: true,
match: { id: 42 },
meetingDetails: {},
meetingData: { homeClub: 'TSV 1875 Bonames', guestClub: 'Eintracht Frankfurt' },
});
const originalPost = context.apiClient.post;
context.apiClient.post = async (url, body) => {
assert.equal(url, '/matches/42/ttr-preview');
assert.equal(body.homeClubName, 'TSV 1875 Bonames');
assert.equal(body.homePlayers[0].name, 'Anton Schottdorf');
return { data: { players: [], diagnostics: [{ side: 'home', message: 'Session abgelaufen' }] } };
};
try {
await report.loadTtrPreview();
assert.equal(report.ttrDiagnostics[0].message, 'Session abgelaufen');
assert.equal(report.ttrLoading, false);
} finally {
context.apiClient.post = originalPost;
}
});