// Package store defines the storage interface for URIT BBS. // // In the original TAG-BBS, data access was done through direct file I/O: // open("User.Data"), lseek() to a slot offset, read()/write() a raw struct. // Each data type (users, boards, mail, libraries) had its own flat file. // // The Store interface abstracts all of that behind methods that the BBS // logic calls without knowing whether the backend is SQLite, PostgreSQL, // or something else entirely. The default implementation is SQLite // (see sqlite.go), which provides zero-configuration embedded storage. // // To add a new backend (e.g., PostgreSQL for clustered deployments), // implement this interface in a new file and wire it up in the config // loader. The BBS application code needs zero changes. package store import ( "github.com/urit/urit/internal/models" ) // Store is the complete data access interface for the BBS. // Every method that can fail returns an error. type Store interface { // Lifecycle Close() error // Users — replaces Load_Account, Save_Account, Find_Open_Account, // ForceSave_Account from ACCOUNTS.C CreateUser(user *models.User) error GetUser(id int64) (*models.User, error) GetUserByName(name string) (*models.User, error) UpdateUser(user *models.User) error DeleteUser(id int64) error // Soft delete (sets active=false) HardDeleteUser(id int64) error // Permanent delete (removes record and mail) ListUsers(offset, limit int) ([]*models.User, error) ListAllUsers(offset, limit int) ([]*models.User, error) CountUsers() (int, error) // Boards — replaces the in-memory linked list of Board_Header // that was loaded from System.Data at startup CreateBoard(board *models.Board) error GetBoard(id int64) (*models.Board, error) ListBoards() ([]*models.Board, error) UpdateBoard(board *models.Board) error DeleteBoard(id int64) error // Messages — replaces the .Keys + .Data file pair per board CreateMessage(msg *models.Message) error GetMessage(id int64) (*models.Message, error) ListMessages(boardID int64, offset, limit int) ([]*models.Message, error) ListMessagesSince(boardID int64, since int64) ([]*models.Message, error) CountMessages(boardID int64) (int, error) DeleteMessage(id int64) error // Mail — replaces the Mail .Keys + .Data files CreateMail(mail *models.Mail) error GetMail(id int64) (*models.Mail, error) ListMailFor(userID int64) ([]*models.Mail, error) CountUnreadMail(userID int64) (int, error) MarkMailRead(id int64) error DeleteMail(id int64) error // Libraries — replaces the in-memory linked list of Library_Header CreateLibrary(lib *models.Library) error GetLibrary(id int64) (*models.Library, error) ListLibraries() ([]*models.Library, error) UpdateLibrary(lib *models.Library) error DeleteLibrary(id int64) error // Library files — replaces the .Keys file per library CreateLibraryFile(file *models.LibraryFile) error GetLibraryFile(id int64) (*models.LibraryFile, error) ListLibraryFiles(libraryID int64, offset, limit int) ([]*models.LibraryFile, error) CountLibraryFiles(libraryID int64) (int, error) DeleteLibraryFile(id int64) error IncrementDownloads(fileID int64) error // Bulletins — replaces the linked list of Bulletin_Header CreateBulletin(b *models.Bulletin) error GetBulletin(id int64) (*models.Bulletin, error) ListBulletins() ([]*models.Bulletin, error) UpdateBulletin(b *models.Bulletin) error DeleteBulletin(id int64) error // Call log — replaces Append_Stat(STAT_LOGON/LOGOFF) from TAG.C LogEvent(event string, userID int64, userName string, node int, remoteAddr, detail string) error ListCallLog(limit int) ([]*models.CallLogEntry, error) ListCallLogForUser(userID int64, limit int) ([]*models.CallLogEntry, error) GetLastCaller(excludeUserID int64) (*models.CallLogEntry, error) // Stats counters — replaces Daily_Statistics/Overall_Statistics IncrementStat(key string, delta int64) error GetStat(key string) (int64, error) GetAllStats() (map[string]int64, error) // Web sessions — HTTP auth tokens for browser-based library access CreateWebSession(s *models.WebSession) error GetWebSession(token string) (*models.WebSession, error) DeleteWebSession(token string) error CleanExpiredWebSessions() (int64, error) }