feat: 支持课后评价与成长档案

完成后即可评价并订阅提醒,馆主可记录体测、笔记与成长照片,首页展示匿名星级均分。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
richarjiang
2026-09-09 15:55:48 +08:00
parent c3e46f7ffa
commit 139882d7a1
50 changed files with 1307 additions and 15 deletions

View File

@@ -85,6 +85,9 @@ model User {
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
bodyMetrics BodyMetric[]
memberNotes MemberNote[]
progressPhotos ProgressPhoto[]
lessonSupplements LessonSupplement[]
memberships Membership[]
bookings Booking[]
@@ -226,6 +229,11 @@ model Booking {
membership Membership @relation(fields: [membershipId], references: [id])
qualifiedInviteReferrals InviteReferral[]
review BookingReview?
memberNotes MemberNote[]
reviewReminderDueAt DateTime? @map("review_reminder_due_at")
reviewReminderClaimedAt DateTime? @map("review_reminder_claimed_at")
reviewReminderSentAt DateTime? @map("review_reminder_sent_at")
statusHistory BookingStatusHistory[]
@@unique([userId, timeSlotId])
@@ -402,3 +410,63 @@ model LessonSupplement {
@@index([userId, revokedAt, createdAt])
@@map("lesson_supplements")
}
model BookingReview {
id String @id @default(uuid())
bookingId String @unique @map("booking_id")
rating Int
recommendation Int?
tags Json
comment String @db.VarChar(200)
createdAt DateTime @default(now()) @map("created_at")
booking Booking @relation(fields: [bookingId], references: [id])
@@index([createdAt])
@@map("booking_reviews")
}
model BodyMetric {
id String @id @default(uuid())
userId String @map("user_id")
recordedAt DateTime @db.Date @map("recorded_at")
weight Float?
bodyFat Float? @map("body_fat")
waist Float?
hip Float?
flexibility Float?
remark String @default("") @db.VarChar(200)
operatorId String @map("operator_id")
createdAt DateTime @default(now()) @map("created_at")
user User @relation(fields: [userId], references: [id])
@@index([userId, recordedAt])
@@map("body_metrics")
}
model MemberNote {
id String @id @default(uuid())
userId String @map("user_id")
bookingId String? @map("booking_id")
content String @db.VarChar(1000)
shared Boolean @default(false)
operatorId String @map("operator_id")
createdAt DateTime @default(now()) @map("created_at")
user User @relation(fields: [userId], references: [id])
booking Booking? @relation(fields: [bookingId], references: [id])
@@index([userId, createdAt])
@@map("member_notes")
}
model ProgressPhoto {
id String @id @default(uuid())
userId String @map("user_id")
objectKey String @unique @map("object_key")
caption String @default("") @db.VarChar(200)
recordedAt DateTime @db.Date @map("recorded_at")
uploadedAt DateTime? @map("uploaded_at")
consentedAt DateTime? @map("consented_at")
revokedAt DateTime? @map("revoked_at")
operatorId String @map("operator_id")
createdAt DateTime @default(now()) @map("created_at")
user User @relation(fields: [userId], references: [id])
@@index([userId, recordedAt])
@@map("progress_photos")
}