Skip to content

Commit 6784190

Browse files
michaelchuclaude
andcommitted
feat: add unique constraint on strategy name
Adds V7 migration with unique index on strategies.name. Upsert now checks for existing name and updates the existing row instead of creating duplicates. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 726f09c commit 6784190

2 files changed

Lines changed: 15 additions & 1 deletion

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- Add unique constraint on strategy name to prevent duplicates.
2+
CREATE UNIQUE INDEX idx_strategies_name_unique ON strategies(name);

src/data/strategy_store.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,18 @@ impl SqliteStrategyStore {
187187
.map(|r| serde_json::to_string(r).unwrap_or_default());
188188
let now = chrono::Utc::now().to_rfc3339();
189189

190+
// Check if a strategy with this name already exists (different id)
191+
let existing_id: Option<String> = conn
192+
.query_row(
193+
"SELECT id FROM strategies WHERE name = ?1 AND id != ?2",
194+
rusqlite::params![row.name, row.id],
195+
|r| r.get(0),
196+
)
197+
.ok();
198+
199+
// If name exists under a different id, update that row instead
200+
let effective_id = existing_id.as_deref().unwrap_or(&row.id);
201+
190202
conn.execute(
191203
"INSERT INTO strategies (id, name, description, category, hypothesis, tags, regime, source, created_at, updated_at)
192204
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)
@@ -200,7 +212,7 @@ impl SqliteStrategyStore {
200212
source = excluded.source,
201213
updated_at = excluded.updated_at",
202214
rusqlite::params![
203-
row.id,
215+
effective_id,
204216
row.name,
205217
row.description,
206218
row.category,

0 commit comments

Comments
 (0)