Without AUTOINCREMENT, SQLite can reassign the highest deleted ROWID to a new row. This is a data integrity bug: a deleted entity's ID could be assigned to a completely different entity, breaking bookmarks, API caches, and URL stability.
30 lines
1.1 KiB
SQL
30 lines
1.1 KiB
SQL
-- Timeline events and AI usage tracking
|
|
|
|
CREATE TABLE timeline_events (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
entity_type TEXT NOT NULL CHECK (entity_type IN ('roaster', 'roast', 'bag', 'gear', 'brew', 'cafe', 'cup')),
|
|
entity_id INTEGER NOT NULL,
|
|
action TEXT NOT NULL,
|
|
occurred_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
title TEXT NOT NULL,
|
|
details_json TEXT,
|
|
tasting_notes_json TEXT,
|
|
slug TEXT,
|
|
roaster_slug TEXT,
|
|
brew_data_json TEXT
|
|
);
|
|
CREATE INDEX idx_timeline_events_entity ON timeline_events(entity_type, entity_id);
|
|
CREATE INDEX idx_timeline_events_occurred_at ON timeline_events(occurred_at DESC);
|
|
|
|
CREATE TABLE ai_usage (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
model TEXT NOT NULL,
|
|
endpoint TEXT NOT NULL,
|
|
prompt_tokens INTEGER NOT NULL,
|
|
completion_tokens INTEGER NOT NULL,
|
|
total_tokens INTEGER NOT NULL,
|
|
cost REAL NOT NULL,
|
|
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
|
);
|
|
CREATE INDEX idx_ai_usage_user_id ON ai_usage(user_id);
|