fix: correct name to Kópáček Ondřej; O (otcovská) looks like D, counts like N

The new worker's surname was misheard: Kropáček → Kópáček everywhere
(default data, both Excel templates, export rosters). The person id
tkb-kropacek is kept. The server now normalises the name in stored
files at startup and in every incoming save, so clients that still
hold the old name cannot write it back.

"O" (otcovská dovolená) is now rendered in the same yellow as "D" in
the app and the month Excel, labelled "Otcovská dovolená", and for the
FPD balance a working-day O is credited like N (a normal worked day)
both in the web FPD check and in the month Excel's FPD column, which
previously counted N and O as zero and disagreed with the web.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Docker Config Backup
2026-09-22 09:28:48 +02:00
parent 09a07b510b
commit 707e18c625
9 changed files with 44 additions and 19 deletions

View File

@@ -94,6 +94,19 @@ function fileMeta(file) {
}
}
// People renamed after data already existed: fix the name wherever it is stored
// (files on disk at startup, and every incoming save from a client that still has the old name)
const PERSON_RENAMES = { 'Kropáček Ondřej': 'Kópáček Ondřej' }
function normalizePeople(data) {
let changed = false
for (const p of (data && data.people) || []) {
const fixed = PERSON_RENAMES[p.name]
if (fixed) { p.name = fixed; changed = true }
}
return changed
}
// Pick draft or published data for a request (?view=published)
function pickData(file, view) {
return view === 'published' && file.published ? file.published : file.data
@@ -130,10 +143,13 @@ migrateIfNeeded()
// Give every existing file a published snapshot (one-time, idempotent)
for (const f of listScheduleFiles()) {
const file = loadScheduleFile(f.id)
if (file && ensurePublished(file)) {
saveScheduleFile(file)
console.log(`Published snapshot initialised for ${file.name} (${file.id})`)
}
if (!file) continue
let dirty = false
if (ensurePublished(file)) { dirty = true; console.log(`Published snapshot initialised for ${file.name} (${file.id})`) }
const renamedDraft = normalizePeople(file.data)
const renamedPublished = normalizePeople(file.published)
if (renamedDraft || renamedPublished) { dirty = true; console.log(`People renamed in ${file.name} (${file.id})`) }
if (dirty) saveScheduleFile(file)
}
// --- Diff computation ---
@@ -389,6 +405,7 @@ app.post('/api/files', (req, res) => {
if (!data || (!data.people && !data.stations) || !data.dayIndex) {
return res.status(400).json({ error: 'Invalid schedule data (need people/stations and dayIndex)' })
}
normalizePeople(data)
const now = new Date().toISOString()
const fileObj = {
id: crypto.randomUUID(),
@@ -419,6 +436,7 @@ app.put('/api/files/:id', (req, res) => {
if ((!data.people && !data.stations) || !data.dayIndex) {
return res.status(400).json({ error: 'Invalid schedule data (need people/stations and dayIndex)' })
}
normalizePeople(data)
file.data = data
}
file.modifiedAt = new Date().toISOString()
@@ -443,6 +461,7 @@ app.post('/api/files/:id/publish', (req, res) => {
if ((!data.people && !data.stations) || !data.dayIndex) {
return res.status(400).json({ error: 'Invalid schedule data (need people/stations and dayIndex)' })
}
normalizePeople(data)
file.data = data
file.modifiedAt = now
}