session.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package models
  2. import (
  3. "time"
  4. )
  5. // CelestiaSession represents a field record ("现场记录") session
  6. type CelestiaSession struct {
  7. ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
  8. UserID string `gorm:"type:uuid;not null;index;uniqueIndex:idx_session_user_client" json:"userId"`
  9. ClientID *string `gorm:"size:100;uniqueIndex:idx_session_user_client" json:"clientId,omitempty"`
  10. Title string `gorm:"size:200;not null" json:"title"`
  11. StartTime time.Time `gorm:"not null" json:"startTime"`
  12. EndTime *time.Time `json:"endTime,omitempty"`
  13. DurationMs int64 `gorm:"default:0" json:"durationMs"`
  14. LocalAudioPath string `gorm:"size:500" json:"localAudioPath,omitempty"`
  15. IsSynced bool `gorm:"default:true" json:"isSynced"`
  16. PhotoCount int `gorm:"default:0" json:"photoCount"`
  17. NoteCount int `gorm:"default:0" json:"noteCount"`
  18. Events []TimelineEvent `gorm:"foreignKey:SessionID;constraint:OnDelete:CASCADE" json:"events"`
  19. Assets []MediaAsset `gorm:"foreignKey:SessionID;constraint:OnDelete:CASCADE" json:"assets"`
  20. Revision int64 `gorm:"default:1" json:"revision"`
  21. DeletedAt *time.Time `gorm:"index" json:"deletedAt,omitempty"`
  22. CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"`
  23. UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updatedAt"`
  24. }
  25. // TimelineEvent represents an event (NOTE, PHOTO, MARKER, VOICE) within a session
  26. type TimelineEvent struct {
  27. ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
  28. SessionID string `gorm:"type:uuid;not null;index;uniqueIndex:idx_event_session_client" json:"sessionId"`
  29. ClientID *string `gorm:"size:100;uniqueIndex:idx_event_session_client" json:"clientId,omitempty"`
  30. RelativeTimeMs int64 `gorm:"not null" json:"relativeTimeMs"`
  31. EventType string `gorm:"size:20;not null" json:"eventType"` // PHOTO, NOTE, MARKER, VOICE
  32. TextContent string `gorm:"type:text" json:"textContent,omitempty"`
  33. LocalFilePath string `gorm:"size:500" json:"localFilePath,omitempty"`
  34. VoiceStartOffsetMs *int64 `json:"voiceStartOffsetMs,omitempty"`
  35. VoiceEndOffsetMs *int64 `json:"voiceEndOffsetMs,omitempty"`
  36. LocationName string `gorm:"size:200" json:"locationName,omitempty"`
  37. LocationAddress string `gorm:"size:500" json:"locationAddress,omitempty"`
  38. Latitude *float64 `json:"latitude,omitempty"`
  39. Longitude *float64 `json:"longitude,omitempty"`
  40. CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"`
  41. }
  42. // MediaAsset is an uploaded audio or photo belonging to a session. StoragePath
  43. // is never serialized because it is an implementation detail of the server.
  44. type MediaAsset struct {
  45. ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
  46. SessionID string `gorm:"type:uuid;not null;index;uniqueIndex:idx_asset_session_client" json:"sessionId"`
  47. UserID string `gorm:"type:uuid;not null;index" json:"userId"`
  48. ClientID string `gorm:"size:120;not null;uniqueIndex:idx_asset_session_client" json:"clientId"`
  49. Kind string `gorm:"size:20;not null" json:"kind"`
  50. FileName string `gorm:"size:255;not null" json:"fileName"`
  51. MIMEType string `gorm:"size:120" json:"mimeType"`
  52. SizeBytes int64 `gorm:"not null" json:"sizeBytes"`
  53. SHA256 string `gorm:"size:64;not null;index" json:"sha256"`
  54. StoragePath string `gorm:"size:1000;not null" json:"-"`
  55. CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"`
  56. }
  57. type CreateSessionRequest struct {
  58. ClientID string `json:"clientId" binding:"required"`
  59. Title string `json:"title" binding:"required"`
  60. StartTime time.Time `json:"startTime" binding:"required"`
  61. EndTime *time.Time `json:"endTime"`
  62. DurationMs int64 `json:"durationMs"`
  63. LocalAudioPath string `json:"localAudioPath"`
  64. Events []CreateEventSubSchema `json:"events"`
  65. BaseRevision *int64 `json:"baseRevision"`
  66. DeletedEventClientIds []string `json:"deletedEventClientIds"`
  67. }
  68. type CreateEventSubSchema struct {
  69. ClientID string `json:"clientId" binding:"required"`
  70. RelativeTimeMs int64 `json:"relativeTimeMs"`
  71. EventType string `json:"eventType" binding:"required"`
  72. TextContent string `json:"textContent"`
  73. LocalFilePath string `json:"localFilePath"`
  74. VoiceStartOffsetMs *int64 `json:"voiceStartOffsetMs"`
  75. VoiceEndOffsetMs *int64 `json:"voiceEndOffsetMs"`
  76. LocationName string `json:"locationName"`
  77. LocationAddress string `json:"locationAddress"`
  78. Latitude *float64 `json:"latitude"`
  79. Longitude *float64 `json:"longitude"`
  80. }
  81. type CreateEventRequest struct {
  82. ClientID string `json:"clientId" binding:"required"`
  83. RelativeTimeMs int64 `json:"relativeTimeMs"`
  84. EventType string `json:"eventType" binding:"required"`
  85. TextContent string `json:"textContent"`
  86. LocalFilePath string `json:"localFilePath"`
  87. VoiceStartOffsetMs *int64 `json:"voiceStartOffsetMs"`
  88. VoiceEndOffsetMs *int64 `json:"voiceEndOffsetMs"`
  89. LocationName string `json:"locationName"`
  90. LocationAddress string `json:"locationAddress"`
  91. Latitude *float64 `json:"latitude"`
  92. Longitude *float64 `json:"longitude"`
  93. }