mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-09-16 18:42:03 +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 is CatchInformationItem => typeof value !== 'string';
|
||||
|
||||
function updateCatchRecord(source: UpdateCatchSource) {
|
||||
function updateCatchRecord(source: UpdateCatchSource, changes?: Partial<CatchRecord>) {
|
||||
if (readOnly) return;
|
||||
dispatch('updateCatch', { pokedexEntry, catchRecord, source });
|
||||
dispatch('updateCatch', { pokedexEntry, catchRecord, source, changes });
|
||||
}
|
||||
|
||||
function onCaughtChange() {
|
||||
@@ -50,7 +50,10 @@
|
||||
if (catchRecord.caught) {
|
||||
catchRecord.haveToEvolve = false;
|
||||
}
|
||||
updateCatchRecord('toggle');
|
||||
updateCatchRecord('toggle', {
|
||||
caught: catchRecord.caught,
|
||||
haveToEvolve: catchRecord.haveToEvolve
|
||||
});
|
||||
}
|
||||
|
||||
function onNeedsToEvolveChange() {
|
||||
@@ -60,7 +63,10 @@
|
||||
if (catchRecord.haveToEvolve) {
|
||||
catchRecord.caught = false;
|
||||
}
|
||||
updateCatchRecord('toggle');
|
||||
updateCatchRecord('toggle', {
|
||||
caught: catchRecord.caught,
|
||||
haveToEvolve: catchRecord.haveToEvolve
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -154,7 +160,7 @@
|
||||
type="checkbox"
|
||||
bind:checked={catchRecord.inHome}
|
||||
class="checkbox checkbox-primary"
|
||||
on:change={() => updateCatchRecord('toggle')}
|
||||
on:change={() => updateCatchRecord('toggle', { inHome: catchRecord?.inHome })}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
@@ -168,7 +174,8 @@
|
||||
type="checkbox"
|
||||
bind:checked={catchRecord.hasGigantamaxed}
|
||||
class="checkbox checkbox-primary"
|
||||
on:change={() => updateCatchRecord('toggle')}
|
||||
on:change={() =>
|
||||
updateCatchRecord('toggle', { hasGigantamaxed: catchRecord?.hasGigantamaxed })}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -90,19 +90,27 @@ class CatchRecordRepository {
|
||||
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')
|
||||
.upsert(dbRows, {
|
||||
onConflict: '"userId","pokedexId","pokemonId"'
|
||||
.upsert(group, {
|
||||
onConflict: '"userId","pokedexId","pokemonId"',
|
||||
defaultToNull: false
|
||||
})
|
||||
.select();
|
||||
|
||||
if (error) {
|
||||
console.error('Supabase error bulk upserting catch records:', error);
|
||||
throw new Error(`Failed to bulk upsert catch records: ${error.message}`);
|
||||
if (error) throw new Error(`Failed to bulk upsert catch records: ${error.message}`);
|
||||
saved.push(...(data ?? []).map((row) => this.transformCatchRecord(row)));
|
||||
}
|
||||
|
||||
return (result ?? []).map((row) => this.transformCatchRecord(row));
|
||||
const byPokemon = new Map(saved.map((row) => [row.pokemonId, row]));
|
||||
return records.map((row) => byPokemon.get(row.pokemonId)!);
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<CatchRecord | null> {
|
||||
|
||||
Reference in New Issue
Block a user