mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-09-16 10:32:10 +00:00
fix(catch-records): stop bulk upserts clobbering fields a toggle never touched
Toggling one checkbox sent the whole record, so a stale copy of the other fields could overwrite newer values. Send only the fields that changed, group rows by the columns they carry, and upsert each group with defaultToNull: false so omitted columns keep their stored value. Results are returned in the caller's order rather than whatever order the groups came back in.
This commit is contained in:
@@ -38,9 +38,9 @@
|
|||||||
value: string | CatchInformationItem
|
value: string | CatchInformationItem
|
||||||
): value is CatchInformationItem => typeof value !== 'string';
|
): value is CatchInformationItem => typeof value !== 'string';
|
||||||
|
|
||||||
function updateCatchRecord(source: UpdateCatchSource) {
|
function updateCatchRecord(source: UpdateCatchSource, changes?: Partial<CatchRecord>) {
|
||||||
if (readOnly) return;
|
if (readOnly) return;
|
||||||
dispatch('updateCatch', { pokedexEntry, catchRecord, source });
|
dispatch('updateCatch', { pokedexEntry, catchRecord, source, changes });
|
||||||
}
|
}
|
||||||
|
|
||||||
function onCaughtChange() {
|
function onCaughtChange() {
|
||||||
@@ -50,7 +50,10 @@
|
|||||||
if (catchRecord.caught) {
|
if (catchRecord.caught) {
|
||||||
catchRecord.haveToEvolve = false;
|
catchRecord.haveToEvolve = false;
|
||||||
}
|
}
|
||||||
updateCatchRecord('toggle');
|
updateCatchRecord('toggle', {
|
||||||
|
caught: catchRecord.caught,
|
||||||
|
haveToEvolve: catchRecord.haveToEvolve
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onNeedsToEvolveChange() {
|
function onNeedsToEvolveChange() {
|
||||||
@@ -60,7 +63,10 @@
|
|||||||
if (catchRecord.haveToEvolve) {
|
if (catchRecord.haveToEvolve) {
|
||||||
catchRecord.caught = false;
|
catchRecord.caught = false;
|
||||||
}
|
}
|
||||||
updateCatchRecord('toggle');
|
updateCatchRecord('toggle', {
|
||||||
|
caught: catchRecord.caught,
|
||||||
|
haveToEvolve: catchRecord.haveToEvolve
|
||||||
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -154,7 +160,7 @@
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
bind:checked={catchRecord.inHome}
|
bind:checked={catchRecord.inHome}
|
||||||
class="checkbox checkbox-primary"
|
class="checkbox checkbox-primary"
|
||||||
on:change={() => updateCatchRecord('toggle')}
|
on:change={() => updateCatchRecord('toggle', { inHome: catchRecord?.inHome })}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -168,7 +174,8 @@
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
bind:checked={catchRecord.hasGigantamaxed}
|
bind:checked={catchRecord.hasGigantamaxed}
|
||||||
class="checkbox checkbox-primary"
|
class="checkbox checkbox-primary"
|
||||||
on:change={() => updateCatchRecord('toggle')}
|
on:change={() =>
|
||||||
|
updateCatchRecord('toggle', { hasGigantamaxed: catchRecord?.hasGigantamaxed })}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -90,19 +90,27 @@ class CatchRecordRepository {
|
|||||||
return mapped;
|
return mapped;
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: result, error } = await this.supabase
|
const groups = new Map<string, Partial<CatchRecordDB>[]>();
|
||||||
|
for (const row of dbRows) {
|
||||||
|
const key = Object.keys(row).sort().join(',');
|
||||||
|
const group = groups.get(key) ?? [];
|
||||||
|
group.push(row);
|
||||||
|
groups.set(key, group);
|
||||||
|
}
|
||||||
|
const saved: CatchRecord[] = [];
|
||||||
|
for (const group of groups.values()) {
|
||||||
|
const { data, error } = await this.supabase
|
||||||
.from('catch_records')
|
.from('catch_records')
|
||||||
.upsert(dbRows, {
|
.upsert(group, {
|
||||||
onConflict: '"userId","pokedexId","pokemonId"'
|
onConflict: '"userId","pokedexId","pokemonId"',
|
||||||
|
defaultToNull: false
|
||||||
})
|
})
|
||||||
.select();
|
.select();
|
||||||
|
if (error) throw new Error(`Failed to bulk upsert catch records: ${error.message}`);
|
||||||
if (error) {
|
saved.push(...(data ?? []).map((row) => this.transformCatchRecord(row)));
|
||||||
console.error('Supabase error bulk upserting catch records:', error);
|
|
||||||
throw new Error(`Failed to bulk upsert catch records: ${error.message}`);
|
|
||||||
}
|
}
|
||||||
|
const byPokemon = new Map(saved.map((row) => [row.pokemonId, row]));
|
||||||
return (result ?? []).map((row) => this.transformCatchRecord(row));
|
return records.map((row) => byPokemon.get(row.pokemonId)!);
|
||||||
}
|
}
|
||||||
|
|
||||||
async findById(id: string): Promise<CatchRecord | null> {
|
async findById(id: string): Promise<CatchRecord | null> {
|
||||||
|
|||||||
Reference in New Issue
Block a user