feat(story-2.1): add feed model and add-feed-by-url API

This commit is contained in:
Michael committed 2026-02-04 14:52:40 +01:00
1 parent dbea4b47af
commit 1249e1bd42
9 files changed
+781 -4

No files matched your search

+44
View File
@@ -0,0 +1,44 @@
package domain
import (
"time"
"github.com/google/uuid"
)
// Article represents an item from an RSS/Atom feed.
type Article struct {
ID uuid.UUID `json:"id"`
FeedID uuid.UUID `json:"feed_id"`
GUID string `json:"guid"`
Title string `json:"title"`
URL string `json:"url,omitempty"`
Content string `json:"content,omitempty"`
Summary string `json:"summary,omitempty"`
Author string `json:"author,omitempty"`
ImageURL string `json:"image_url,omitempty"`
PublishedAt *time.Time `json:"published_at,omitempty"`
IsRead bool `json:"is_read"`
IsFavorite bool `json:"is_favorite"`
ReadAt *time.Time `json:"read_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
// Virtual fields (from joins)
FeedTitle string `json:"feed_title,omitempty"`
}
// ArticleRepository defines the interface for article data access.
type ArticleRepository interface {
Create(article *Article) error
CreateBatch(articles []*Article) error
GetByID(id uuid.UUID) (*Article, error)
GetByFeedID(feedID uuid.UUID, limit, offset int) ([]*Article, error)
GetByUserID(userID uuid.UUID, limit, offset int, unreadOnly bool) ([]*Article, error)
GetByGUID(feedID uuid.UUID, guid string) (*Article, error)
MarkAsRead(id uuid.UUID) error
MarkAsUnread(id uuid.UUID) error
MarkAllAsRead(feedID uuid.UUID) error
ToggleFavorite(id uuid.UUID) error
GetFavorites(userID uuid.UUID, limit, offset int) ([]*Article, error)
CountUnread(feedID uuid.UUID) (int, error)
}
+37
View File
@@ -0,0 +1,37 @@
package domain
import (
"time"
"github.com/google/uuid"
)
// Feed represents an RSS/Atom feed subscription.
type Feed struct {
ID uuid.UUID `json:"id"`
UserID uuid.UUID `json:"user_id"`
URL string `json:"url"`
Title string `json:"title"`
Description string `json:"description,omitempty"`
SiteURL string `json:"site_url,omitempty"`
ImageURL string `json:"image_url,omitempty"`
LastFetchedAt *time.Time `json:"last_fetched_at,omitempty"`
FetchError string `json:"fetch_error,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// Virtual fields (not in DB)
UnreadCount int `json:"unread_count,omitempty"`
}
// FeedRepository defines the interface for feed data access.
type FeedRepository interface {
Create(feed *Feed) error
GetByID(id uuid.UUID) (*Feed, error)
GetByUserID(userID uuid.UUID) ([]*Feed, error)
GetByURL(userID uuid.UUID, url string) (*Feed, error)
Update(feed *Feed) error
Delete(id uuid.UUID) error
GetFeedsToFetch(limit int) ([]*Feed, error)
UpdateFetchStatus(id uuid.UUID, fetchedAt time.Time, fetchError string) error
}