Documentation
¶
Index ¶
- type AdminTokenEntity
- type Article
- type ArticleEntity
- type ArticlePaginationResult
- type AuditLog
- type AuditLogEntity
- type DB
- func (db *DB) AddArticle(article *Article) error
- func (db *DB) AddFeed(feed *Feed) error
- func (db *DB) BatchSetUserArticleStatus(userID int, articles []Article, isRead, isStarred bool) error
- func (db *DB) CleanupOrphanedUserArticles(olderThanDays int) (int, error)
- func (db *DB) Close() error
- func (db *DB) CreateAuditLog(log *AuditLog) error
- func (db *DB) CreateIndexes() error
- func (db *DB) CreateSession(session *Session) error
- func (db *DB) CreateTables() error
- func (db *DB) CreateUser(user *User) error
- func (db *DB) DeleteExpiredSessions() error
- func (db *DB) DeleteFeed(id int) error
- func (db *DB) DeleteSession(sessionID string) error
- func (db *DB) FindArticleByURL(url string) (*Article, error)
- func (db *DB) GetAllUserFeeds() ([]Feed, error)
- func (db *DB) GetArticles(feedID int) ([]Article, error)
- func (db *DB) GetAuditLogs(limit, offset int, filters map[string]interface{}) ([]AuditLog, error)
- func (db *DB) GetFeedByURL(url string) (*Feed, error)
- func (db *DB) GetFeeds() ([]Feed, error)
- func (db *DB) GetSession(sessionID string) (*Session, error)
- func (db *DB) GetUserArticleStatus(userID, articleID int) (*UserArticle, error)
- func (db *DB) GetUserArticles(userID int) ([]Article, error)
- func (db *DB) GetUserArticlesPaginated(userID int, limit int, cursor string, unreadOnly bool) (*ArticlePaginationResult, error)
- func (db *DB) GetUserByEmail(email string) (*User, error)
- func (db *DB) GetUserByGoogleID(googleID string) (*User, error)
- func (db *DB) GetUserByID(userID int) (*User, error)
- func (db *DB) GetUserFeedArticles(userID, feedID int) ([]Article, error)
- func (db *DB) GetUserFeedCount(userID int) (int, error)
- func (db *DB) GetUserFeeds(userID int) ([]Feed, error)
- func (db *DB) GetUserUnreadCounts(userID int) (map[int]int, error)
- func (db *DB) GrantFreeMonths(userID int, months int) error
- func (db *DB) IsUserSubscriptionActive(userID int) (bool, error)
- func (db *DB) MarkUserArticleRead(userID, articleID int, isRead bool) error
- func (db *DB) SetUserAdmin(userID int, isAdmin bool) error
- func (db *DB) SetUserArticleStatus(userID, articleID int, isRead, isStarred bool) error
- func (db *DB) SubscribeUserToFeed(userID, feedID int) error
- func (db *DB) ToggleUserArticleStar(userID, articleID int) error
- func (db *DB) UnsubscribeUserFromFeed(userID, feedID int) error
- func (db *DB) UpdateFeed(feed *Feed) error
- func (db *DB) UpdateFeedLastFetch(feedID int, lastFetch time.Time) error
- func (db *DB) UpdateFeedTracking(feedID int, lastChecked, lastHadNewContent time.Time, ...) error
- func (db *DB) UpdateUserMaxArticlesOnFeedAdd(userID int, maxArticles int) error
- func (db *DB) UpdateUserSubscription(userID int, status, subscriptionID string, ...) error
- type Database
- type DatastoreDB
- func (db *DatastoreDB) AddArticle(article *Article) error
- func (db *DatastoreDB) AddFeed(feed *Feed) error
- func (db *DatastoreDB) BatchSetUserArticleStatus(userID int, articles []Article, isRead, isStarred bool) error
- func (db *DatastoreDB) CleanupOrphanedUserArticles(olderThanDays int) (int, error)
- func (db *DatastoreDB) Close() error
- func (db *DatastoreDB) CreateAuditLog(log *AuditLog) error
- func (db *DatastoreDB) CreateSession(session *Session) error
- func (db *DatastoreDB) CreateUser(user *User) error
- func (db *DatastoreDB) DeleteExpiredSessions() error
- func (db *DatastoreDB) DeleteFeed(id int) error
- func (db *DatastoreDB) DeleteSession(sessionID string) error
- func (db *DatastoreDB) FindArticleByURL(url string) (*Article, error)
- func (db *DatastoreDB) GetAllUserFeeds() ([]Feed, error)
- func (db *DatastoreDB) GetArticles(feedID int) ([]Article, error)
- func (db *DatastoreDB) GetAuditLogs(limit, offset int, filters map[string]interface{}) ([]AuditLog, error)
- func (db *DatastoreDB) GetClient() *datastore.Client
- func (db *DatastoreDB) GetFeedByID(feedID int) (*Feed, error)
- func (db *DatastoreDB) GetFeedByURL(url string) (*Feed, error)
- func (db *DatastoreDB) GetFeeds() ([]Feed, error)
- func (db *DatastoreDB) GetSession(sessionID string) (*Session, error)
- func (db *DatastoreDB) GetUserArticleStatus(userID, articleID int) (*UserArticle, error)
- func (db *DatastoreDB) GetUserArticles(userID int) ([]Article, error)
- func (db *DatastoreDB) GetUserArticlesPaginated(userID int, limit int, cursor string, unreadOnly bool) (*ArticlePaginationResult, error)
- func (db *DatastoreDB) GetUserByEmail(email string) (*User, error)
- func (db *DatastoreDB) GetUserByGoogleID(googleID string) (*User, error)
- func (db *DatastoreDB) GetUserByID(userID int) (*User, error)
- func (db *DatastoreDB) GetUserFeedArticles(userID, feedID int) ([]Article, error)
- func (db *DatastoreDB) GetUserFeedCount(userID int) (int, error)
- func (db *DatastoreDB) GetUserFeeds(userID int) ([]Feed, error)
- func (db *DatastoreDB) GetUserUnreadCounts(userID int) (map[int]int, error)
- func (db *DatastoreDB) GrantFreeMonths(userID int, months int) error
- func (db *DatastoreDB) IsUserSubscriptionActive(userID int) (bool, error)
- func (db *DatastoreDB) MarkUserArticleRead(userID, articleID int, isRead bool) error
- func (db *DatastoreDB) SetUserAdmin(userID int, isAdmin bool) error
- func (db *DatastoreDB) SetUserArticleStatus(userID, articleID int, isRead, isStarred bool) error
- func (db *DatastoreDB) SubscribeUserToFeed(userID, feedID int) error
- func (db *DatastoreDB) ToggleUserArticleStar(userID, articleID int) error
- func (db *DatastoreDB) UnsubscribeUserFromFeed(userID, feedID int) error
- func (db *DatastoreDB) UpdateFeed(feed *Feed) error
- func (db *DatastoreDB) UpdateFeedLastFetch(feedID int, lastFetch time.Time) error
- func (db *DatastoreDB) UpdateFeedTracking(feedID int, lastChecked, lastHadNewContent time.Time, ...) error
- func (db *DatastoreDB) UpdateUserMaxArticlesOnFeedAdd(userID int, maxArticles int) error
- func (db *DatastoreDB) UpdateUserSubscription(userID int, status, subscriptionID string, ...) error
- type Feed
- type FeedEntity
- type Session
- type SessionEntity
- type User
- type UserArticle
- type UserArticleEntity
- type UserEntity
- type UserFeed
- type UserFeedEntity
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AdminTokenEntity ¶
type Article ¶
type Article struct {
ID int `json:"id"`
FeedID int `json:"feed_id"`
FeedTitle string `json:"feed_title,omitempty"`
Title string `json:"title"`
URL string `json:"url"`
Content string `json:"content"`
Description string `json:"description"`
Author string `json:"author"`
PublishedAt time.Time `json:"published_at"`
CreatedAt time.Time `json:"created_at"`
IsRead bool `json:"is_read"`
IsStarred bool `json:"is_starred"`
}
type ArticleEntity ¶
type ArticleEntity struct {
ID int64 `datastore:"-"`
FeedID int64 `datastore:"feed_id"`
Title string `datastore:"title"`
URL string `datastore:"url"`
Content string `datastore:"content,noindex"`
Description string `datastore:"description,noindex"`
Author string `datastore:"author"`
PublishedAt time.Time `datastore:"published_at"`
CreatedAt time.Time `datastore:"created_at"`
IsRead bool `datastore:"is_read"`
IsStarred bool `datastore:"is_starred"`
}
type ArticlePaginationResult ¶
type ArticlePaginationResult struct {
Articles []Article
NextCursor string // Empty string means no more results
}
ArticlePaginationResult contains paginated articles and a cursor for the next page
type AuditLog ¶
type AuditLog struct {
ID int `json:"id"`
Timestamp time.Time `json:"timestamp"`
AdminUserID int `json:"admin_user_id"`
AdminEmail string `json:"admin_email"`
OperationType string `json:"operation_type"`
TargetUserID int `json:"target_user_id"`
TargetUserEmail string `json:"target_user_email"`
OperationDetails string `json:"operation_details"` // JSON string
IPAddress string `json:"ip_address"`
Result string `json:"result"` // "success" or "failure"
ErrorMessage string `json:"error_message"`
}
type AuditLogEntity ¶
type AuditLogEntity struct {
ID int64 `datastore:"-"`
Timestamp time.Time `datastore:"timestamp"`
AdminUserID int64 `datastore:"admin_user_id"`
AdminEmail string `datastore:"admin_email"`
OperationType string `datastore:"operation_type"`
TargetUserID int64 `datastore:"target_user_id"`
TargetUserEmail string `datastore:"target_user_email"`
OperationDetails string `datastore:"operation_details,noindex"`
IPAddress string `datastore:"ip_address"`
Result string `datastore:"result"`
ErrorMessage string `datastore:"error_message,noindex"`
}
type DB ¶
func (*DB) AddArticle ¶
func (*DB) BatchSetUserArticleStatus ¶
func (*DB) CleanupOrphanedUserArticles ¶
CleanupOrphanedUserArticles removes user_articles that reference articles from feeds the user is no longer subscribed to. Only cleans up articles older than the specified number of days. Returns the number of records deleted.
func (*DB) CreateAuditLog ¶
Audit log methods for SQLite
func (*DB) CreateIndexes ¶
CreateIndexes creates all database indexes (public for testing)
func (*DB) CreateSession ¶
Session methods for SQLite
func (*DB) CreateTables ¶
CreateTables creates all necessary database tables (public for testing)
func (*DB) DeleteExpiredSessions ¶
func (*DB) DeleteFeed ¶
func (*DB) DeleteSession ¶
func (*DB) GetAllUserFeeds ¶
func (*DB) GetAuditLogs ¶
func (*DB) GetUserArticleStatus ¶
func (db *DB) GetUserArticleStatus(userID, articleID int) (*UserArticle, error)
User article status methods
func (*DB) GetUserArticles ¶
User article methods
func (*DB) GetUserArticlesPaginated ¶
func (db *DB) GetUserArticlesPaginated(userID int, limit int, cursor string, unreadOnly bool) (*ArticlePaginationResult, error)
GetUserArticlesPaginated fetches user articles with cursor-based pagination Uses keyset pagination for efficient querying without scanning skipped rows
func (*DB) GetUserFeedArticles ¶
func (*DB) IsUserSubscriptionActive ¶
func (*DB) MarkUserArticleRead ¶
func (*DB) SetUserAdmin ¶
Admin management methods
func (*DB) SetUserArticleStatus ¶
func (*DB) SubscribeUserToFeed ¶
func (*DB) ToggleUserArticleStar ¶
func (*DB) UnsubscribeUserFromFeed ¶
func (*DB) UpdateFeed ¶
func (*DB) UpdateFeedLastFetch ¶
func (*DB) UpdateFeedTracking ¶
func (*DB) UpdateUserMaxArticlesOnFeedAdd ¶
type Database ¶
type Database interface {
// User methods
CreateUser(user *User) error
GetUserByGoogleID(googleID string) (*User, error)
GetUserByID(userID int) (*User, error)
UpdateUserSubscription(userID int, status, subscriptionID string, lastPaymentDate, nextBillingDate time.Time) error
IsUserSubscriptionActive(userID int) (bool, error)
GetUserFeedCount(userID int) (int, error)
UpdateUserMaxArticlesOnFeedAdd(userID int, maxArticles int) error
// Admin methods
SetUserAdmin(userID int, isAdmin bool) error
GrantFreeMonths(userID int, months int) error
GetUserByEmail(email string) (*User, error)
// Feed methods
AddFeed(feed *Feed) error
UpdateFeed(feed *Feed) error
UpdateFeedTracking(feedID int, lastChecked, lastHadNewContent time.Time, averageUpdateInterval int) error
GetFeeds() ([]Feed, error)
GetFeedByURL(url string) (*Feed, error)
GetUserFeeds(userID int) ([]Feed, error)
GetAllUserFeeds() ([]Feed, error)
DeleteFeed(id int) error
SubscribeUserToFeed(userID, feedID int) error
UnsubscribeUserFromFeed(userID, feedID int) error
// Article methods
AddArticle(article *Article) error
GetArticles(feedID int) ([]Article, error)
FindArticleByURL(url string) (*Article, error)
GetUserArticles(userID int) ([]Article, error)
GetUserArticlesPaginated(userID int, limit int, cursor string, unreadOnly bool) (*ArticlePaginationResult, error)
GetUserFeedArticles(userID, feedID int) ([]Article, error)
// User article status methods
GetUserArticleStatus(userID, articleID int) (*UserArticle, error)
SetUserArticleStatus(userID, articleID int, isRead, isStarred bool) error
BatchSetUserArticleStatus(userID int, articles []Article, isRead, isStarred bool) error
MarkUserArticleRead(userID, articleID int, isRead bool) error
ToggleUserArticleStar(userID, articleID int) error
GetUserUnreadCounts(userID int) (map[int]int, error)
CleanupOrphanedUserArticles(olderThanDays int) (int, error)
// Session methods
CreateSession(session *Session) error
GetSession(sessionID string) (*Session, error)
DeleteSession(sessionID string) error
DeleteExpiredSessions() error
// Audit log methods
CreateAuditLog(log *AuditLog) error
GetAuditLogs(limit, offset int, filters map[string]interface{}) ([]AuditLog, error)
UpdateFeedLastFetch(feedID int, lastFetch time.Time) error
Close() error
}
type DatastoreDB ¶
type DatastoreDB struct {
// contains filtered or unexported fields
}
func NewDatastoreDB ¶
func NewDatastoreDB(projectID string) (*DatastoreDB, error)
func (*DatastoreDB) AddArticle ¶
func (db *DatastoreDB) AddArticle(article *Article) error
func (*DatastoreDB) AddFeed ¶
func (db *DatastoreDB) AddFeed(feed *Feed) error
func (*DatastoreDB) BatchSetUserArticleStatus ¶
func (db *DatastoreDB) BatchSetUserArticleStatus(userID int, articles []Article, isRead, isStarred bool) error
func (*DatastoreDB) CleanupOrphanedUserArticles ¶
func (db *DatastoreDB) CleanupOrphanedUserArticles(olderThanDays int) (int, error)
CleanupOrphanedUserArticles removes UserArticle entities that reference articles from feeds the user is no longer subscribed to. Only cleans up articles older than the specified number of days. Returns the number of records deleted.
func (*DatastoreDB) Close ¶
func (db *DatastoreDB) Close() error
func (*DatastoreDB) CreateAuditLog ¶
func (db *DatastoreDB) CreateAuditLog(log *AuditLog) error
Audit log methods for Datastore
func (*DatastoreDB) CreateSession ¶
func (db *DatastoreDB) CreateSession(session *Session) error
Session methods for Datastore
func (*DatastoreDB) CreateUser ¶
func (db *DatastoreDB) CreateUser(user *User) error
User methods for Datastore
func (*DatastoreDB) DeleteExpiredSessions ¶
func (db *DatastoreDB) DeleteExpiredSessions() error
func (*DatastoreDB) DeleteFeed ¶
func (db *DatastoreDB) DeleteFeed(id int) error
func (*DatastoreDB) DeleteSession ¶
func (db *DatastoreDB) DeleteSession(sessionID string) error
func (*DatastoreDB) FindArticleByURL ¶
func (db *DatastoreDB) FindArticleByURL(url string) (*Article, error)
func (*DatastoreDB) GetAllUserFeeds ¶
func (db *DatastoreDB) GetAllUserFeeds() ([]Feed, error)
func (*DatastoreDB) GetArticles ¶
func (db *DatastoreDB) GetArticles(feedID int) ([]Article, error)
func (*DatastoreDB) GetAuditLogs ¶
func (db *DatastoreDB) GetAuditLogs(limit, offset int, filters map[string]interface{}) ([]AuditLog, error)
func (*DatastoreDB) GetClient ¶
func (db *DatastoreDB) GetClient() *datastore.Client
GetClient returns the underlying datastore client for direct access
func (*DatastoreDB) GetFeedByID ¶
func (db *DatastoreDB) GetFeedByID(feedID int) (*Feed, error)
func (*DatastoreDB) GetFeedByURL ¶
func (db *DatastoreDB) GetFeedByURL(url string) (*Feed, error)
func (*DatastoreDB) GetFeeds ¶
func (db *DatastoreDB) GetFeeds() ([]Feed, error)
func (*DatastoreDB) GetSession ¶
func (db *DatastoreDB) GetSession(sessionID string) (*Session, error)
func (*DatastoreDB) GetUserArticleStatus ¶
func (db *DatastoreDB) GetUserArticleStatus(userID, articleID int) (*UserArticle, error)
func (*DatastoreDB) GetUserArticles ¶
func (db *DatastoreDB) GetUserArticles(userID int) ([]Article, error)
func (*DatastoreDB) GetUserArticlesPaginated ¶
func (db *DatastoreDB) GetUserArticlesPaginated(userID int, limit int, cursor string, unreadOnly bool) (*ArticlePaginationResult, error)
func (*DatastoreDB) GetUserByEmail ¶
func (db *DatastoreDB) GetUserByEmail(email string) (*User, error)
func (*DatastoreDB) GetUserByGoogleID ¶
func (db *DatastoreDB) GetUserByGoogleID(googleID string) (*User, error)
func (*DatastoreDB) GetUserByID ¶
func (db *DatastoreDB) GetUserByID(userID int) (*User, error)
func (*DatastoreDB) GetUserFeedArticles ¶
func (db *DatastoreDB) GetUserFeedArticles(userID, feedID int) ([]Article, error)
func (*DatastoreDB) GetUserFeedCount ¶
func (db *DatastoreDB) GetUserFeedCount(userID int) (int, error)
func (*DatastoreDB) GetUserFeeds ¶
func (db *DatastoreDB) GetUserFeeds(userID int) ([]Feed, error)
func (*DatastoreDB) GetUserUnreadCounts ¶
func (db *DatastoreDB) GetUserUnreadCounts(userID int) (map[int]int, error)
func (*DatastoreDB) GrantFreeMonths ¶
func (db *DatastoreDB) GrantFreeMonths(userID int, months int) error
func (*DatastoreDB) IsUserSubscriptionActive ¶
func (db *DatastoreDB) IsUserSubscriptionActive(userID int) (bool, error)
func (*DatastoreDB) MarkUserArticleRead ¶
func (db *DatastoreDB) MarkUserArticleRead(userID, articleID int, isRead bool) error
func (*DatastoreDB) SetUserAdmin ¶
func (db *DatastoreDB) SetUserAdmin(userID int, isAdmin bool) error
Admin management methods
func (*DatastoreDB) SetUserArticleStatus ¶
func (db *DatastoreDB) SetUserArticleStatus(userID, articleID int, isRead, isStarred bool) error
func (*DatastoreDB) SubscribeUserToFeed ¶
func (db *DatastoreDB) SubscribeUserToFeed(userID, feedID int) error
func (*DatastoreDB) ToggleUserArticleStar ¶
func (db *DatastoreDB) ToggleUserArticleStar(userID, articleID int) error
func (*DatastoreDB) UnsubscribeUserFromFeed ¶
func (db *DatastoreDB) UnsubscribeUserFromFeed(userID, feedID int) error
func (*DatastoreDB) UpdateFeed ¶
func (db *DatastoreDB) UpdateFeed(feed *Feed) error
func (*DatastoreDB) UpdateFeedLastFetch ¶
func (db *DatastoreDB) UpdateFeedLastFetch(feedID int, lastFetch time.Time) error
func (*DatastoreDB) UpdateFeedTracking ¶
func (*DatastoreDB) UpdateUserMaxArticlesOnFeedAdd ¶
func (db *DatastoreDB) UpdateUserMaxArticlesOnFeedAdd(userID int, maxArticles int) error
func (*DatastoreDB) UpdateUserSubscription ¶
func (db *DatastoreDB) UpdateUserSubscription(userID int, status, subscriptionID string, lastPaymentDate, nextBillingDate time.Time) error
Subscription management methods
type Feed ¶
type Feed struct {
ID int `json:"id"`
Title string `json:"title"`
URL string `json:"url"`
Description string `json:"description"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
LastFetch time.Time `json:"last_fetch"`
LastChecked time.Time `json:"last_checked"` // When we last attempted to check for updates
LastHadNewContent time.Time `json:"last_had_new_content"` // When we last found new articles
AverageUpdateInterval int `json:"average_update_interval"` // Average seconds between updates (0 = unknown)
}
type FeedEntity ¶
type FeedEntity struct {
ID int64 `datastore:"-"`
Title string `datastore:"title"`
URL string `datastore:"url"`
Description string `datastore:"description"`
CreatedAt time.Time `datastore:"created_at"`
UpdatedAt time.Time `datastore:"updated_at"`
LastFetch time.Time `datastore:"last_fetch"`
LastChecked time.Time `datastore:"last_checked"`
LastHadNewContent time.Time `datastore:"last_had_new_content"`
AverageUpdateInterval int `datastore:"average_update_interval"`
}
type SessionEntity ¶
type User ¶
type User struct {
ID int `json:"id"`
GoogleID string `json:"google_id"`
Email string `json:"email"`
Name string `json:"name"`
Avatar string `json:"avatar"`
CreatedAt time.Time `json:"created_at"`
SubscriptionStatus string `json:"subscription_status"` // 'trial', 'active', 'cancelled', 'expired', 'admin'
SubscriptionID string `json:"subscription_id"` // Stripe subscription ID
TrialEndsAt time.Time `json:"trial_ends_at"` // When free trial expires
LastPaymentDate time.Time `json:"last_payment_date"` // Last successful payment
NextBillingDate time.Time `json:"next_billing_date"` // Next billing date for active subscriptions
IsAdmin bool `json:"is_admin"` // Admin users bypass subscription limits
FreeMonthsRemaining int `json:"free_months_remaining"` // Additional free months granted
MaxArticlesOnFeedAdd int `json:"max_articles_on_feed_add"` // Max articles to import when adding a new feed (0 = unlimited)
}
type UserArticle ¶
type UserArticleEntity ¶
type UserEntity ¶
type UserEntity struct {
ID int64 `datastore:"-"`
GoogleID string `datastore:"google_id"`
Email string `datastore:"email"`
Name string `datastore:"name"`
Avatar string `datastore:"avatar"`
CreatedAt time.Time `datastore:"created_at"`
SubscriptionStatus string `datastore:"subscription_status"`
SubscriptionID string `datastore:"subscription_id"`
TrialEndsAt time.Time `datastore:"trial_ends_at"`
LastPaymentDate time.Time `datastore:"last_payment_date"`
NextBillingDate time.Time `datastore:"next_billing_date"`
IsAdmin bool `datastore:"is_admin"`
FreeMonthsRemaining int `datastore:"free_months_remaining"`
MaxArticlesOnFeedAdd int `datastore:"max_articles_on_feed_add"`
}