screentinker/.gitignore
ScreenTinker a93f65b20a Only store a device fingerprint against a device that still exists
A player that reconnects after its row was deleted sends the id it still has
cached. device_fingerprints.device_id has a foreign key to devices(id), so
writing that id back fails the constraint. The throw was caught, which is why
this looked harmless, but the catch abandons the whole fingerprint block:
last_seen is not updated, the reinstall link is not made, and the settings
restore never runs. That restore exists specifically for the post-delete
re-pair, so the failure landed exactly where the feature was meant to help and
a re-paired panel came back with its orientation, name and playlist reset.

Production shows 37 of these, timestamped identically to the "sending unpaired"
log lines — the same event seen from the other side.

The incoming id is preferred, then whatever is already stored, and only an id
that still resolves is written; otherwise NULL, which the column allows and
which ON DELETE SET NULL already leaves behind. The INSERT path a few lines
below had this guard; the UPDATE was missed, and it is the one that fires.

Tests cover the deleted-id reconnect, that last_seen still advances, and that
live ids are unaffected. One asserts the raw unguarded statement really does
raise FOREIGN KEY constraint failed, and another asserts the guard is present
in the handler itself, since the others exercise a mirror of that statement.

Also ignores *.sqlite / *.sqlite3, which the existing *.db rules missed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL
2026-07-28 13:54:40 -05:00

62 lines
1,004 B
Plaintext

# Dependencies
node_modules/
# Databases: SQLite files, WAL/SHM sidecars, and any .db.<suffix> backups
# (e.g. .db.devbak), anywhere in the tree - never commit a database.
*.db
*.db-wal
*.db-shm
*.db.*
# Uploads (user content)
server/uploads/
# Secrets and certificates
server/certs/key.pem
server/certs/cert.pem
server/certs/license_private.pem
server/certs/.jwt_secret
server/certs/.license_key
# Android
android/.gradle/
android/build/
android/app/build/
android/local.properties
android/release-key.jks
*.apk
*.aab
*.wgt
*.tar.gz
# IDE / Editor
.claude/
.idea/
.vscode/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Environment
.env
.env.*
# ...but DO track the documented template (placeholders only, no secrets)
!.env.example
# Local-only marketing assets
video/
# Generated: transition demo (rebuild with `node shared/Transitions/build-demo.js`)
shared/Transitions/demo.html
audit/
.mcp.json
**/.mcp.json
# Local SQLite artifacts (any extension the tooling might produce)
*.sqlite
*.sqlite3