Summary
installation.deleted cleanup uses a raw where clause with installationId instead of DB column installation_id:
.where("installationId = :id", { id: String(installationId) })
Because this is a raw SQL fragment, entity property names are not guaranteed to map to snake_case DB columns. Cleanup may fail to match rows.
Impact
High / state integrity:
- Repos may remain linked to removed installation after uninstall.
registered/installation state can drift from GitHub app reality.
- Future lifecycle events/backfill decisions can run against stale installation linkage.
Repro (conceptual)
- Install app for repos (rows have
installation_id set).
- Trigger
installation.deleted.
- Observe cleanup query uses
installationId in raw where fragment.
- Rows may not be cleared due to column-name mismatch.
Expected behavior
Uninstall cleanup should reliably clear all repos by installation_id and set registered=false.
Suggested fix direction
- Use DB column name in raw fragment:
where("installation_id = :id", { id: ... })
- Or use object-based criteria API to avoid column-name mismatch risk.
- Add regression test for uninstall cleanup.
Summary
installation.deletedcleanup uses a raw where clause withinstallationIdinstead of DB columninstallation_id:Because this is a raw SQL fragment, entity property names are not guaranteed to map to snake_case DB columns. Cleanup may fail to match rows.
Impact
High / state integrity:
registered/installation state can drift from GitHub app reality.Repro (conceptual)
installation_idset).installation.deleted.installationIdin raw where fragment.Expected behavior
Uninstall cleanup should reliably clear all repos by
installation_idand setregistered=false.Suggested fix direction
where("installation_id = :id", { id: ... })