fix bypass in production

This commit is contained in:
beo3000 2026-02-21 15:49:52 +01:00
parent 098c9d8ace
commit 9c04b8652c
7 changed files with 40 additions and 7 deletions

View File

@ -16,7 +16,8 @@
"Bash(python3:*)",
"Bash(echo:*)",
"Bash(git -C ka-note check-ignore .env)",
"Bash(git -C . check-ignore ka-note/.env)"
"Bash(git -C . check-ignore ka-note/.env)",
"Bash(git check-ignore:*)"
]
}
}

3
ka-note/.dockerignore Normal file
View File

@ -0,0 +1,3 @@
**/.env.local
**/.env.*.local
**/node_modules

2
ka-note/.gitignore vendored
View File

@ -3,6 +3,8 @@ dist/
.svelte-kit/
build/
.env
.env.local
.env.*.local
*.db
*.sqlite
.DS_Store

View File

@ -1 +1 @@
1.0.9
1.0.11

View File

@ -42,25 +42,25 @@ async function pullAndMerge(since: Date | null): Promise<string> {
await db.transaction('rw', [db.contexts, db.topics, db.historyEntries, db.ratings], async () => {
for (const serverCtx of contexts) {
const local = await db.contexts.get(serverCtx.id);
if (!local || serverCtx.version >= local.version) {
if (!local || serverCtx.version > local.version) {
await db.contexts.put(serverCtx);
}
}
for (const serverTopic of topics) {
const local = await db.topics.get(serverTopic.id);
if (!local || serverTopic.version >= local.version) {
if (!local || serverTopic.version > local.version) {
await db.topics.put(serverTopic);
}
}
for (const serverHe of historyEntries) {
const local = await db.historyEntries.get(serverHe.id);
if (!local || serverHe.version >= local.version) {
if (!local || serverHe.version > local.version) {
await db.historyEntries.put(serverHe);
}
}
for (const serverRating of ratings) {
const local = await db.ratings.get(serverRating.id);
if (!local || serverRating.version >= local.version) {
if (!local || serverRating.version > local.version) {
await db.ratings.put(serverRating);
}
}
@ -95,8 +95,8 @@ export async function sync(): Promise<void> {
async function doSync(since: Date | null): Promise<void> {
syncStatus.set('syncing');
try {
const serverTimestamp = await pullAndMerge(since);
await pushAll();
const serverTimestamp = await pullAndMerge(since);
const syncTime = new Date(serverTimestamp);
lastSyncAt.set(syncTime);
localStorage.setItem('lastSyncAt', syncTime.toISOString());

Binary file not shown.

27
roadmap.md Normal file
View File

@ -0,0 +1,27 @@
# Ka-Note Roadmap
## [LOW] Sync: Soft-delete Restrisiko bei neuem Gerät / DB-Reset
**Problem**
Wenn ein Gerät noch nie gepusht hat (neues Gerät oder IndexedDB gelöscht), ist `!local = true` für alle Pull-Einträge. Der Pull überschreibt dann keine lokale Version, sondern legt neu an — auch wenn der Eintrag auf einem anderen Gerät bereits gelöscht wurde. Das gelöschte Item erscheint wieder, bis das löschende Gerät seinen Push durchführt.
**Bereits gefixt**
- Push läuft jetzt vor Pull (`doSync`)
- Merge-Bedingung auf `>` statt `>=` (lokale Änderung gewinnt bei Versionsgleichstand)
**Restrisiko**
Szenario: Gerät A löscht Item (version N+1), hat aber noch nie gepusht. Gerät B macht Full-Sync: Pull bringt Server-Version N (nicht gelöscht), `!local` → wird eingespielt. Gerät B sieht das Item als vorhanden.
**Lösungsoptionen**
1. **Serverseitig: `deletedAt`-Items aus Pull-Response ausfiltern**
Server gibt bei Pull keine soft-deleted Items zurück. Gerät B bekommt das Item gar nicht erst. Problem: Wenn Gerät B das Item schon lokal hat (z.B. eigene ältere Version), wird es nie als gelöscht markiert.
2. **Tombstone-Tabelle**
Separate Tabelle `deletions(entityId, deletedAt, version)` — wird immer mitübertragen. Client wertet Tombstones aus und löscht lokale Items explizit. Robusteste Lösung, erhöht aber Komplexität.
3. **Server filtert + Client löscht lokale Einträge die der Server nicht mehr liefert**
Server sendet nur aktive Items. Client vergleicht lokale IDs mit Pull-Response und markiert fehlende als `deletedAt`. Einfacher als Tombstones, aber fehleranfällig bei partiellen Pulls (since-Filter).
**Empfehlung**
Option 2 (Tombstones) für korrekte Multi-Gerät-Unterstützung. Option 3 als pragmatischer Zwischenschritt wenn Full-Sync (since=null) garantiert ist.