package models
import (
"sync"
"time"
"github.com/google/uuid"
)
// Session represents a user workspace session
type Session struct {
ID string
UserID string
CreatedAt time.Time
LastUsed time.Time
}
const SessionTimeout = 30 * time.Minute
var (
sessions = make(map[string]*Session)
mu sync.RWMutex
)
// GetOrCreateSession retrieves or creates a session for the given ID and user
func GetOrCreateSession(sessionID, userID string) *Session {
mu.Lock()
defer mu.Unlock()
// Validate session ID format
if _, err := uuid.Parse(sessionID); err != nil {
sessionID = GenerateSessionID()
}
if session, ok := sessions[sessionID]; ok {
if session.UserID == userID {
session.LastUsed = time.Now()
return session
}
}
// Create new session
session := &Session{
ID: sessionID,
UserID: userID,
CreatedAt: time.Now(),
LastUsed: time.Now(),
}
sessions[sessionID] = session
return session
}
// GenerateSessionID creates a new UUID for sessions
func GenerateSessionID() string {
return uuid.New().String()
}
// CleanupStaleSessions removes sessions that have been idle for too long
func CleanupStaleSessions() {
mu.Lock()
defer mu.Unlock()
cutoff := time.Now().Add(-SessionTimeout)
for id, session := range sessions {
if session.LastUsed.Before(cutoff) {
delete(sessions, id)
}
}
}
Add rich text formatting and block styling to editor
Simple demo of Patch Seq on The Skyscape