| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- package models
- import (
- "time"
- )
- // CelestiaSession represents a field record ("现场记录") session
- type CelestiaSession struct {
- ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
- UserID string `gorm:"type:uuid;not null;index;uniqueIndex:idx_session_user_client" json:"userId"`
- ClientID *string `gorm:"size:100;uniqueIndex:idx_session_user_client" json:"clientId,omitempty"`
- Title string `gorm:"size:200;not null" json:"title"`
- StartTime time.Time `gorm:"not null" json:"startTime"`
- EndTime *time.Time `json:"endTime,omitempty"`
- DurationMs int64 `gorm:"default:0" json:"durationMs"`
- LocalAudioPath string `gorm:"size:500" json:"localAudioPath,omitempty"`
- IsSynced bool `gorm:"default:true" json:"isSynced"`
- PhotoCount int `gorm:"default:0" json:"photoCount"`
- NoteCount int `gorm:"default:0" json:"noteCount"`
- Events []TimelineEvent `gorm:"foreignKey:SessionID;constraint:OnDelete:CASCADE" json:"events"`
- Assets []MediaAsset `gorm:"foreignKey:SessionID;constraint:OnDelete:CASCADE" json:"assets"`
- Revision int64 `gorm:"default:1" json:"revision"`
- DeletedAt *time.Time `gorm:"index" json:"deletedAt,omitempty"`
- CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"`
- UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updatedAt"`
- }
- // SessionSyncIndexItem is the lightweight first phase of synchronization.
- // Events and asset descriptors are intentionally omitted; clients fetch the
- // full session only when UpdatedAt or Revision differs from local state.
- type SessionSyncIndexItem struct {
- ID string `json:"id"`
- ClientID *string `json:"clientId,omitempty"`
- Title string `json:"title"`
- StartTime time.Time `json:"startTime"`
- EndTime *time.Time `json:"endTime,omitempty"`
- DurationMs int64 `json:"durationMs"`
- PhotoCount int `json:"photoCount"`
- NoteCount int `json:"noteCount"`
- Revision int64 `json:"revision"`
- DeletedAt *time.Time `json:"deletedAt,omitempty"`
- UpdatedAt time.Time `json:"updatedAt"`
- }
- func (session CelestiaSession) SyncIndexItem() SessionSyncIndexItem {
- return SessionSyncIndexItem{
- ID: session.ID,
- ClientID: session.ClientID,
- Title: session.Title,
- StartTime: session.StartTime,
- EndTime: session.EndTime,
- DurationMs: session.DurationMs,
- PhotoCount: session.PhotoCount,
- NoteCount: session.NoteCount,
- Revision: session.Revision,
- DeletedAt: session.DeletedAt,
- UpdatedAt: session.UpdatedAt,
- }
- }
- // TimelineEvent represents an event (NOTE, PHOTO, MARKER, VOICE) within a session
- type TimelineEvent struct {
- ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
- SessionID string `gorm:"type:uuid;not null;index;uniqueIndex:idx_event_session_client" json:"sessionId"`
- ClientID *string `gorm:"size:100;uniqueIndex:idx_event_session_client" json:"clientId,omitempty"`
- RelativeTimeMs int64 `gorm:"not null" json:"relativeTimeMs"`
- EventType string `gorm:"size:20;not null" json:"eventType"` // PHOTO, NOTE, MARKER, VOICE
- TextContent string `gorm:"type:text" json:"textContent,omitempty"`
- LocalFilePath string `gorm:"size:500" json:"localFilePath,omitempty"`
- VoiceStartOffsetMs *int64 `json:"voiceStartOffsetMs,omitempty"`
- VoiceEndOffsetMs *int64 `json:"voiceEndOffsetMs,omitempty"`
- LocationName string `gorm:"size:200" json:"locationName,omitempty"`
- LocationAddress string `gorm:"size:500" json:"locationAddress,omitempty"`
- Latitude *float64 `json:"latitude,omitempty"`
- Longitude *float64 `json:"longitude,omitempty"`
- CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"`
- }
- // MediaAsset is an uploaded audio or photo belonging to a session. StoragePath
- // is never serialized because it is an implementation detail of the server.
- type MediaAsset struct {
- ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
- SessionID string `gorm:"type:uuid;not null;index;uniqueIndex:idx_asset_session_client" json:"sessionId"`
- UserID string `gorm:"type:uuid;not null;index" json:"userId"`
- ClientID string `gorm:"size:120;not null;uniqueIndex:idx_asset_session_client" json:"clientId"`
- Kind string `gorm:"size:20;not null" json:"kind"`
- FileName string `gorm:"size:255;not null" json:"fileName"`
- MIMEType string `gorm:"size:120" json:"mimeType"`
- SizeBytes int64 `gorm:"not null" json:"sizeBytes"`
- SHA256 string `gorm:"size:64;not null;index" json:"sha256"`
- StoragePath string `gorm:"size:1000;not null" json:"-"`
- CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"`
- }
- type CreateSessionRequest struct {
- ClientID string `json:"clientId" binding:"required"`
- Title string `json:"title" binding:"required"`
- StartTime time.Time `json:"startTime" binding:"required"`
- EndTime *time.Time `json:"endTime"`
- DurationMs int64 `json:"durationMs"`
- LocalAudioPath string `json:"localAudioPath"`
- Events []CreateEventSubSchema `json:"events"`
- BaseRevision *int64 `json:"baseRevision"`
- DeletedEventClientIds []string `json:"deletedEventClientIds"`
- }
- type CreateEventSubSchema struct {
- ClientID string `json:"clientId" binding:"required"`
- RelativeTimeMs int64 `json:"relativeTimeMs"`
- EventType string `json:"eventType" binding:"required"`
- TextContent string `json:"textContent"`
- LocalFilePath string `json:"localFilePath"`
- VoiceStartOffsetMs *int64 `json:"voiceStartOffsetMs"`
- VoiceEndOffsetMs *int64 `json:"voiceEndOffsetMs"`
- LocationName string `json:"locationName"`
- LocationAddress string `json:"locationAddress"`
- Latitude *float64 `json:"latitude"`
- Longitude *float64 `json:"longitude"`
- }
- type CreateEventRequest struct {
- ClientID string `json:"clientId" binding:"required"`
- RelativeTimeMs int64 `json:"relativeTimeMs"`
- EventType string `json:"eventType" binding:"required"`
- TextContent string `json:"textContent"`
- LocalFilePath string `json:"localFilePath"`
- VoiceStartOffsetMs *int64 `json:"voiceStartOffsetMs"`
- VoiceEndOffsetMs *int64 `json:"voiceEndOffsetMs"`
- LocationName string `json:"locationName"`
- LocationAddress string `json:"locationAddress"`
- Latitude *float64 `json:"latitude"`
- Longitude *float64 `json:"longitude"`
- }
|