api: add new mood enhancements to match the class design
Parents:
ce4428d2 file(s) changed
- api/migrations/002_mood_enhancements.sql +53 -0
- api/src/setup-db.js +22 -10
api/migrations/002_mood_enhancements.sql
@@ -0,0 +1,54 @@
1 + -- Drop and recreate mood table with enhanced fields
2 + DROP TABLE IF EXISTS mood;
3 +
4 + CREATE TABLE IF NOT EXISTS mood (
5 + id INTEGER PRIMARY KEY AUTOINCREMENT,
6 + user_id INTEGER NOT NULL,
7 + rating INTEGER CHECK (rating BETWEEN 1 AND 10),
8 + stress_level INTEGER NOT NULL CHECK (stress_level BETWEEN 1 AND 10),
9 + anxiety_level INTEGER NOT NULL CHECK (anxiety_level BETWEEN 1 AND 10),
10 + energy_level INTEGER NOT NULL CHECK (energy_level BETWEEN 1 AND 10),
11 + title TEXT,
12 + description TEXT,
13 + recorded_at DATETIME NOT NULL,
14 + created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
15 + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
16 + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
17 + );
18 +
19 + -- Mood components table for emotional breakdown
20 + CREATE TABLE IF NOT EXISTS mood_components (
21 + id INTEGER PRIMARY KEY AUTOINCREMENT,
22 + mood_id INTEGER NOT NULL,
23 + emotion TEXT NOT NULL CHECK (emotion IN ('joy', 'trust', 'fear', 'surprise', 'sad', 'disgust', 'angry', 'anxiety')),
24 + intensity INTEGER NOT NULL CHECK (intensity BETWEEN 1 AND 10),
25 + created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
26 + FOREIGN KEY (mood_id) REFERENCES mood(id) ON DELETE CASCADE,
27 + UNIQUE(mood_id, emotion)
28 + );
29 +
30 + -- Indexes for performance
31 + CREATE INDEX IF NOT EXISTS idx_mood_user_id ON mood(user_id);
32 + CREATE INDEX IF NOT EXISTS idx_mood_recorded_at ON mood(recorded_at);
33 + CREATE INDEX IF NOT EXISTS idx_mood_user_date ON mood(user_id, recorded_at);
34 + CREATE INDEX IF NOT EXISTS idx_mood_components_mood_id ON mood_components(mood_id);
35 +
36 + -- Recreate users table with new fields (SQLite doesn't support ALTER TABLE ADD COLUMN well)
37 + CREATE TABLE IF NOT EXISTS users_new (
38 + id INTEGER PRIMARY KEY AUTOINCREMENT,
39 + email TEXT UNIQUE NOT NULL,
40 + password TEXT NOT NULL,
41 + first_name TEXT NOT NULL,
42 + last_name TEXT NOT NULL,
43 + timezone TEXT DEFAULT 'UTC',
44 + created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
45 + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
46 + );
47 +
48 + -- Copy existing data
49 + INSERT OR IGNORE INTO users_new (id, email, password, first_name, last_name, created_at)
50 + SELECT id, email, password, first_name, last_name, created_at FROM users;
51 +
52 + -- Drop old table and rename new one
53 + DROP TABLE IF EXISTS users;
54 + ALTER TABLE users_new RENAME TO users;
api/src/setup-db.js
@@ -9,13 +9,19 @@
9 9 export function setupDatabase(dbPath = 'orbit.db') {
10 10 const db = new Database(dbPath);
11 11
12 - // Read and execute migrations
12 + // Read and execute migrations in order
13 13 const migrationsDir = path.join(__dirname, '..', 'migrations');
14 - const migrationFile = path.join(migrationsDir, '001_initial_schema.sql');
14 + const migrationFiles = [
15 + '001_initial_schema.sql',
16 + '002_mood_enhancements.sql'
17 + ];
15 18
16 - if (fs.existsSync(migrationFile)) {
17 - const migration = fs.readFileSync(migrationFile, 'utf8');
18 - db.exec(migration);
19 + for (const file of migrationFiles) {
20 + const migrationPath = path.join(migrationsDir, file);
21 + if (fs.existsSync(migrationPath)) {
22 + const migration = fs.readFileSync(migrationPath, 'utf8');
23 + db.exec(migration);
24 + }
19 25 }
20 26
21 27 return db;
@@ -25,13 +31,19 @@ export function setupTestDatabase() {
25 31 // Use in-memory database for tests
26 32 const db = new Database(':memory:');
27 33
28 - // Read and execute migrations
34 + // Read and execute migrations in order
29 35 const migrationsDir = path.join(__dirname, '..', 'migrations');
30 - const migrationFile = path.join(migrationsDir, '001_initial_schema.sql');
36 + const migrationFiles = [
37 + '001_initial_schema.sql',
38 + '002_mood_enhancements.sql'
39 + ];
31 40
32 - if (fs.existsSync(migrationFile)) {
33 - const migration = fs.readFileSync(migrationFile, 'utf8');
34 - db.exec(migration);
41 + for (const file of migrationFiles) {
42 + const migrationPath = path.join(migrationsDir, file);
43 + if (fs.existsSync(migrationPath)) {
44 + const migration = fs.readFileSync(migrationPath, 'utf8');
45 + db.exec(migration);
46 + }
35 47 }
36 48
37 49 return db;