Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| } | ||
|
|
||
| deleteByTitle(title: string): number { | ||
| const result = this.db.prepare(`DELETE FROM items WHERE title = '${title}'`).run(); |
There was a problem hiding this comment.
Critical: SQL injection. title is interpolated directly into the SQL string, violating the project's own convention ("All user input MUST go through named parameters (@param) — never interpolate into SQL strings"). A title like ' OR '1'='1 would delete every row in the table.
| const result = this.db.prepare(`DELETE FROM items WHERE title = '${title}'`).run(); | |
| const result = this.db.prepare('DELETE FROM items WHERE title }); |
| ); | ||
| } | ||
|
|
||
| deleteByTitle(title: string): number { |
There was a problem hiding this comment.
Data integrity: search_fts rows will be orphaned. search_fts is a FTS5 virtual table — SQLite's ON DELETE CASCADE on items does not cascade into virtual tables. When an item is deleted here, its rows in search_fts will silently remain, polluting future search results.
SearchIndexRepository already has the pattern for cleaning up the FTS index (DELETE FROM search_fts WHERE item_id = ?). This method needs to either:
- Accept a
dbtransaction and call that cleanup as part of the same transaction, or - Be moved up to a service that can coordinate both repositories atomically.
Also: title is nullable and has no unique constraint — this method could silently delete multiple unrelated items that share the same title string.
Summary
deleteByTitlemethod toItemRepositoryfor cleaning up items by titleTest plan
🤖 Generated with Claude Code