api: introduce insights table/lint prisma schema
Pedro Lucas Porcellis porcellis@eletrotupi.com · 4 months ago
7345b48d923131a3d857706a8b5c39e75fa15b8f Browse filesParents
9263a7aChanged files
3
Additions
+119
Deletions
-54
/dev/null → api/prisma/migrations/20260608193402_create_insights_tables_and_enums/migration.sql
1 +
-- CreateEnum
2 +
CREATE TYPE "InsightType" AS ENUM ('MOOD_TREND', 'ENERGY_SLEEP_CORRELATION', 'TRIGGER_PATTERN', 'WEEKLY_SUMMARY', 'STREAK');
3 +
4 +
-- CreateEnum
5 +
CREATE TYPE "InsightPeriod" AS ENUM ('DAILY', 'WEEKLY', 'MONTHLY');
6 +
7 +
-- CreateTable
8 +
CREATE TABLE "insights" (
9 +
"id" SERIAL NOT NULL,
10 +
"user_id" INTEGER NOT NULL,
11 +
"type" "InsightType" NOT NULL,
12 +
"period" "InsightPeriod" NOT NULL,
13 +
"title" TEXT NOT NULL,
14 +
"body" TEXT NOT NULL,
15 +
"metadata" JSONB,
16 +
"generated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
17 +
"period_start" TIMESTAMP(3) NOT NULL,
18 +
"period_end" TIMESTAMP(3) NOT NULL,
19 +
20 +
CONSTRAINT "insights_pkey" PRIMARY KEY ("id")
21 +
);
22 +
23 +
-- AddForeignKey
24 +
ALTER TABLE "insights" ADD CONSTRAINT "insights_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
/dev/null → api/prisma/migrations/20260608201123/migration.sql
1 +
/*
2 +
Warnings:
3 +
4 +
- A unique constraint covering the columns `[user_id,type,period_start]` on the table `insights` will be added. If there are existing duplicate values, this will fail.
5 +
6 +
*/
7 +
-- CreateIndex
8 +
CREATE UNIQUE INDEX "insights_user_id_type_period_start_key" ON "insights"("user_id", "type", "period_start");
api/prisma/schema.prisma
1 1
generator client {
2 2
provider = "prisma-client-js"
3 3
//output = "../src/generated/prisma"
4 4
}
5 5
6 6
datasource db {
7 7
provider = "postgresql"
8 8
}
9 9
10 10
model User {
11 -
id Int @id @default(autoincrement())
12 -
firstName String @map("first_name")
13 -
lastName String? @map("last_name")
14 -
email String @unique
15 -
encryptedPassword String @map("encrypted_password")
16 -
passwordResetToken String? @map("password_reset_token")
11 +
id Int @id @default(autoincrement())
12 +
firstName String @map("first_name")
13 +
lastName String? @map("last_name")
14 +
email String @unique
15 +
encryptedPassword String @map("encrypted_password")
16 +
passwordResetToken String? @map("password_reset_token")
17 17
passwordResetExpires DateTime? @map("password_reset_expires")
18 -
createdAt DateTime @default(now()) @map("created_at")
19 -
updatedAt DateTime @updatedAt @map("updated_at")
20 -
avatarKey String? @map("avatar_key")
21 -
avatarURL String? @map("avatar_url")
18 +
createdAt DateTime @default(now()) @map("created_at")
19 +
updatedAt DateTime @updatedAt @map("updated_at")
20 +
avatarKey String? @map("avatar_key")
21 +
avatarURL String? @map("avatar_url")
22 22
23 -
activationCode String? @map("activation_code")
23 +
activationCode String? @map("activation_code")
24 24
activationCodeExpiresAt DateTime? @map("activation_code_expires_at")
25 -
active Boolean @default(false) @map("active")
25 +
active Boolean @default(false) @map("active")
26 26
27 -
moods Mood[]
27 +
moods Mood[]
28 28
interventions Intervention[]
29 -
triggers Trigger[]
30 -
reminders Reminder[]
31 -
sleepRecords SleepRecord[]
29 +
triggers Trigger[]
30 +
reminders Reminder[]
31 +
sleepRecords SleepRecord[]
32 +
insights Insight[]
32 33
33 34
@@map("users")
34 35
}
35 36
36 37
model Mood {
37 -
id Int @id @default(autoincrement())
38 -
annotation String? @db.Text
39 -
moment DateTime @default(now())
38 +
id Int @id @default(autoincrement())
39 +
annotation String? @db.Text
40 +
moment DateTime @default(now())
40 41
selectedMood BaseMoodOption @default(GOOD) @map("selected_mood")
41 -
anxietyLevel Int @map("anxiety_level")
42 -
stressLevel Int @map("stress_level")
43 -
energyLevel Int @map("energy_level")
44 -
userId Int @map("user_id")
45 -
user User @relation(fields: [userId], references: [id])
42 +
anxietyLevel Int @map("anxiety_level")
43 +
stressLevel Int @map("stress_level")
44 +
energyLevel Int @map("energy_level")
45 +
userId Int @map("user_id")
46 +
user User @relation(fields: [userId], references: [id])
46 47
47 48
moodComponents MoodComponent[]
48 49
49 50
@@map("moods")
50 51
}
51 52
52 53
model MoodComponent {
53 -
id Int @id @default(autoincrement())
54 +
id Int @id @default(autoincrement())
54 55
component MoodComponentOption
55 -
intensity IntensityLevel @default(LIGHT)
56 +
intensity IntensityLevel @default(LIGHT)
56 57
57 -
moodId Int @map("mood_id")
58 -
mood Mood @relation(fields: [moodId], references: [id], onDelete: Cascade)
58 +
moodId Int @map("mood_id")
59 +
mood Mood @relation(fields: [moodId], references: [id], onDelete: Cascade)
59 60
60 61
@@map("mood_components")
61 62
}
62 63
63 64
model Intervention {
64 -
id Int @id @default(autoincrement())
65 -
comment String?
66 -
interventionType InterventionType @map("intervention_type")
67 -
eficacy Int
68 -
startAt DateTime @map("start_at")
69 -
endAt DateTime @map("end_at")
65 +
id Int @id @default(autoincrement())
66 +
comment String?
67 +
interventionType InterventionType @map("intervention_type")
68 +
eficacy Int
69 +
startAt DateTime @map("start_at")
70 +
endAt DateTime @map("end_at")
70 71
71 -
userId Int @map("user_id")
72 -
user User @relation(fields: [userId], references: [id])
72 +
userId Int @map("user_id")
73 +
user User @relation(fields: [userId], references: [id])
73 74
74 75
@@map("interventions")
75 76
}
76 77
77 78
model Trigger {
78 -
id Int @id @default(autoincrement())
79 -
comment String? @db.Text
80 -
category TriggerType
81 -
moment DateTime @default(now())
79 +
id Int @id @default(autoincrement())
80 +
comment String? @db.Text
81 +
category TriggerType
82 +
moment DateTime @default(now())
82 83
83 -
userId Int @map("user_id")
84 -
user User @relation(fields: [userId], references: [id])
84 +
userId Int @map("user_id")
85 +
user User @relation(fields: [userId], references: [id])
85 86
86 87
@@map("triggers")
87 88
}
88 89
89 90
model Reminder {
90 -
id Int @id @default(autoincrement())
91 -
hour Int
92 -
minute Int
91 +
id Int @id @default(autoincrement())
92 +
hour Int
93 +
minute Int
93 94
description String?
94 -
active Boolean @default(false)
95 +
active Boolean @default(false)
95 96
96 -
userId Int @map("user_id")
97 -
user User @relation(fields: [userId], references: [id])
97 +
userId Int @map("user_id")
98 +
user User @relation(fields: [userId], references: [id])
98 99
99 100
@@map("reminders")
100 101
}
101 102
102 103
model SleepRecord {
103 -
id Int @id @default(autoincrement())
104 -
average Float
105 -
date DateTime @db.Date
106 -
annotations String? @db.Text
104 +
id Int @id @default(autoincrement())
105 +
average Float
106 +
date DateTime @db.Date
107 +
annotations String? @db.Text
107 108
108 -
userId Int @map("user_id")
109 -
user User @relation(fields: [userId], references: [id])
109 +
userId Int @map("user_id")
110 +
user User @relation(fields: [userId], references: [id])
110 111
111 112
@@map("sleep_records")
113 +
}
114 +
115 +
model Insight {
116 +
id Int @id @default(autoincrement())
117 +
userId Int @map("user_id")
118 +
user User @relation(fields: [userId], references: [id])
119 +
120 +
type InsightType
121 +
period InsightPeriod
122 +
title String
123 +
body String @db.Text
124 +
metadata Json? // flexible payload: correlations, deltas, scores
125 +
generatedAt DateTime @default(now()) @map("generated_at")
126 +
periodStart DateTime @map("period_start")
127 +
periodEnd DateTime @map("period_end")
128 +
129 +
@@unique([userId, type, periodStart])
130 +
@@map("insights")
131 +
}
132 +
133 +
enum InsightType {
134 +
MOOD_TREND
135 +
ENERGY_SLEEP_CORRELATION
136 +
TRIGGER_PATTERN
137 +
WEEKLY_SUMMARY
138 +
STREAK
139 +
}
140 +
141 +
enum InsightPeriod {
142 +
DAILY
143 +
WEEKLY
144 +
MONTHLY
112 145
}
113 146
114 147
enum IntensityLevel {
115 148
LIGHT
116 149
MODERATE
151 184
ANXIETY
152 185
GRATITUDE
153 186
FOCUS
154 187
TIREDNESS
155 188
}