user report gtound work
This commit is contained in:
1 parent
1be2de05fa
commit
74f0d0dbed
42 files changed
+8127
-5
No files matched your search
@@ -5,6 +5,7 @@ import {
|
||||
real,
|
||||
index,
|
||||
unique,
|
||||
uniqueIndex,
|
||||
} from "drizzle-orm/sqlite-core";
|
||||
|
||||
export const users = sqliteTable(
|
||||
@@ -380,6 +381,193 @@ export const recommendations = sqliteTable(
|
||||
}),
|
||||
);
|
||||
|
||||
// Daily nutrition tracking table
|
||||
export const dailyNutrition = sqliteTable(
|
||||
"daily_nutrition",
|
||||
{
|
||||
id: text("id").primaryKey(),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
date: text("date").notNull(), // YYYY-MM-DD format
|
||||
totalCalories: real("total_calories").notNull().default(0),
|
||||
calorieGoal: real("calorie_goal").notNull().default(2000),
|
||||
meals: text("meals", { mode: "json" }).$type<
|
||||
Array<{
|
||||
type: "breakfast" | "lunch" | "dinner" | "snack";
|
||||
name: string;
|
||||
calories: number;
|
||||
time?: string;
|
||||
}>
|
||||
>(),
|
||||
createdAt: integer("created_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date()),
|
||||
updatedAt: integer("updated_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date()),
|
||||
},
|
||||
(table) => ({
|
||||
userIdIdx: index("daily_nutrition_user_id_idx").on(table.userId),
|
||||
dateIdx: index("daily_nutrition_date_idx").on(table.date),
|
||||
userDateIdx: uniqueIndex("daily_nutrition_user_date_idx").on(
|
||||
table.userId,
|
||||
table.date,
|
||||
),
|
||||
}),
|
||||
);
|
||||
|
||||
// Individual meal entries table
|
||||
export const mealEntries = sqliteTable(
|
||||
"meal_entries",
|
||||
{
|
||||
id: text("id").primaryKey(),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
dailyNutritionId: text("daily_nutrition_id").references(
|
||||
() => dailyNutrition.id,
|
||||
{ onDelete: "cascade" },
|
||||
),
|
||||
mealType: text("meal_type", {
|
||||
enum: ["breakfast", "lunch", "dinner", "snack"],
|
||||
}).notNull(),
|
||||
foodName: text("food_name").notNull(),
|
||||
calories: real("calories").notNull(),
|
||||
protein: real("protein"), // grams (optional)
|
||||
carbs: real("carbs"), // grams (optional)
|
||||
fats: real("fats"), // grams (optional)
|
||||
timestamp: integer("timestamp", { mode: "timestamp" }).notNull(),
|
||||
createdAt: integer("created_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date()),
|
||||
},
|
||||
(table) => ({
|
||||
userIdIdx: index("meal_entries_user_id_idx").on(table.userId),
|
||||
timestampIdx: index("meal_entries_timestamp_idx").on(table.timestamp),
|
||||
dailyNutritionIdIdx: index("meal_entries_daily_nutrition_id_idx").on(
|
||||
table.dailyNutritionId,
|
||||
),
|
||||
}),
|
||||
);
|
||||
|
||||
// Daily hydration tracking table
|
||||
export const dailyHydration = sqliteTable(
|
||||
"daily_hydration",
|
||||
{
|
||||
id: text("id").primaryKey(),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
date: text("date").notNull(), // YYYY-MM-DD format
|
||||
totalWater: real("total_water").notNull().default(0), // ml
|
||||
waterGoal: real("water_goal").notNull().default(2000), // ml
|
||||
entries: text("entries", { mode: "json" }).$type<
|
||||
Array<{ amount: number; time: string }>
|
||||
>(),
|
||||
createdAt: integer("created_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date()),
|
||||
updatedAt: integer("updated_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date()),
|
||||
},
|
||||
(table) => ({
|
||||
userIdIdx: index("daily_hydration_user_id_idx").on(table.userId),
|
||||
dateIdx: index("daily_hydration_date_idx").on(table.date),
|
||||
userDateIdx: uniqueIndex("daily_hydration_user_date_idx").on(
|
||||
table.userId,
|
||||
table.date,
|
||||
),
|
||||
}),
|
||||
);
|
||||
|
||||
// Fitness profile history tracking table
|
||||
export const fitnessProfileHistory = sqliteTable(
|
||||
"fitness_profile_history",
|
||||
{
|
||||
id: text("id").primaryKey(),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
fitnessProfileId: text("fitness_profile_id")
|
||||
.notNull()
|
||||
.references(() => fitnessProfiles.id, { onDelete: "cascade" }),
|
||||
changeType: text("change_type", {
|
||||
enum: [
|
||||
"weight",
|
||||
"height",
|
||||
"age",
|
||||
"activity_level",
|
||||
"goals",
|
||||
"medical",
|
||||
"other",
|
||||
],
|
||||
}).notNull(),
|
||||
fieldName: text("field_name").notNull(), // "weight", "height", etc.
|
||||
previousValue: text("previous_value"), // JSON string for flexibility
|
||||
newValue: text("new_value"), // JSON string
|
||||
changedAt: integer("changed_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date()),
|
||||
createdAt: integer("created_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date()),
|
||||
},
|
||||
(table) => ({
|
||||
userIdIdx: index("fitness_profile_history_user_id_idx").on(table.userId),
|
||||
changedAtIdx: index("fitness_profile_history_changed_at_idx").on(
|
||||
table.changedAt,
|
||||
),
|
||||
userChangedIdx: index("fitness_profile_history_user_changed_idx").on(
|
||||
table.userId,
|
||||
table.changedAt,
|
||||
),
|
||||
changeTypeIdx: index("fitness_profile_history_change_type_idx").on(
|
||||
table.changeType,
|
||||
),
|
||||
}),
|
||||
);
|
||||
|
||||
// Trainer-client assignment table
|
||||
export const trainerClientAssignments = sqliteTable(
|
||||
"trainer_client_assignments",
|
||||
{
|
||||
id: text("id").primaryKey(),
|
||||
trainerId: text("trainer_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
clientId: text("client_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
assignedAt: integer("assigned_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date()),
|
||||
assignedBy: text("assigned_by").references(() => users.id),
|
||||
isActive: integer("is_active", { mode: "boolean" }).notNull().default(true),
|
||||
createdAt: integer("created_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date()),
|
||||
updatedAt: integer("updated_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date()),
|
||||
},
|
||||
(table) => ({
|
||||
trainerIdx: index("trainer_client_assignments_trainer_idx").on(
|
||||
table.trainerId,
|
||||
),
|
||||
clientIdx: index("trainer_client_assignments_client_idx").on(
|
||||
table.clientId,
|
||||
),
|
||||
trainerClientIdx: uniqueIndex(
|
||||
"trainer_client_assignments_trainer_client_idx",
|
||||
).on(table.trainerId, table.clientId),
|
||||
isActiveIdx: index("trainer_client_assignments_is_active_idx").on(
|
||||
table.isActive,
|
||||
),
|
||||
}),
|
||||
);
|
||||
|
||||
export type User = typeof users.$inferSelect;
|
||||
export type NewUser = typeof users.$inferInsert;
|
||||
export type Client = typeof clients.$inferSelect;
|
||||
@@ -396,3 +584,16 @@ export type FitnessGoal = typeof fitnessGoals.$inferSelect;
|
||||
export type NewFitnessGoal = typeof fitnessGoals.$inferInsert;
|
||||
export type Recommendation = typeof recommendations.$inferSelect;
|
||||
export type NewRecommendation = typeof recommendations.$inferInsert;
|
||||
export type DailyNutrition = typeof dailyNutrition.$inferSelect;
|
||||
export type NewDailyNutrition = typeof dailyNutrition.$inferInsert;
|
||||
export type MealEntry = typeof mealEntries.$inferSelect;
|
||||
export type NewMealEntry = typeof mealEntries.$inferInsert;
|
||||
export type DailyHydration = typeof dailyHydration.$inferSelect;
|
||||
export type NewDailyHydration = typeof dailyHydration.$inferInsert;
|
||||
export type FitnessProfileHistory = typeof fitnessProfileHistory.$inferSelect;
|
||||
export type NewFitnessProfileHistory =
|
||||
typeof fitnessProfileHistory.$inferInsert;
|
||||
export type TrainerClientAssignment =
|
||||
typeof trainerClientAssignments.$inferSelect;
|
||||
export type NewTrainerClientAssignment =
|
||||
typeof trainerClientAssignments.$inferInsert;
|
||||
Reference in new issue
Block a user