aboutsummaryrefslogtreecommitdiffhomepage
path: root/backend/graphql/resolver/schema.resolvers.go
diff options
context:
space:
mode:
Diffstat (limited to 'backend/graphql/resolver/schema.resolvers.go')
-rw-r--r--backend/graphql/resolver/schema.resolvers.go461
1 files changed, 0 insertions, 461 deletions
diff --git a/backend/graphql/resolver/schema.resolvers.go b/backend/graphql/resolver/schema.resolvers.go
deleted file mode 100644
index 0392945..0000000
--- a/backend/graphql/resolver/schema.resolvers.go
+++ /dev/null
@@ -1,461 +0,0 @@
-package resolver
-
-// This file will be automatically regenerated based on the schema, any resolver implementations
-// will be copied through when generating and any unknown code will be moved to the end.
-// Code generated by github.com/99designs/gqlgen version v0.17.76
-
-import (
- "context"
- "database/sql"
- "fmt"
- "strconv"
- "time"
-
- "undef.ninja/x/feedaka/auth"
- "undef.ninja/x/feedaka/db"
- "undef.ninja/x/feedaka/feed"
- gql "undef.ninja/x/feedaka/graphql"
- "undef.ninja/x/feedaka/graphql/model"
-)
-
-// AddFeed is the resolver for the addFeed field.
-func (r *mutationResolver) AddFeed(ctx context.Context, url string) (*model.Feed, error) {
- userID, err := getUserIDFromContext(ctx)
- if err != nil {
- return nil, err
- }
-
- // Fetch the feed to get its title
- f, err := feed.Fetch(ctx, url)
- if err != nil {
- return nil, fmt.Errorf("failed to parse feed: %w", err)
- }
-
- // Insert the feed into the database
- dbFeed, err := r.Queries.CreateFeed(ctx, db.CreateFeedParams{
- Url: url,
- Title: f.Title,
- FetchedAt: time.Now().UTC().Format(time.RFC3339),
- UserID: userID,
- })
- if err != nil {
- return nil, fmt.Errorf("failed to insert feed: %w", err)
- }
-
- // Sync articles from the feed
- if err := feed.Sync(ctx, r.Queries, dbFeed.ID, f); err != nil {
- return nil, fmt.Errorf("failed to sync articles: %w", err)
- }
-
- return &model.Feed{
- ID: strconv.FormatInt(dbFeed.ID, 10),
- URL: dbFeed.Url,
- Title: dbFeed.Title,
- FetchedAt: dbFeed.FetchedAt,
- IsSubscribed: dbFeed.IsSubscribed == 1,
- }, nil
-}
-
-// UnsubscribeFeed is the resolver for the unsubscribeFeed field.
-func (r *mutationResolver) UnsubscribeFeed(ctx context.Context, id string) (bool, error) {
- userID, err := getUserIDFromContext(ctx)
- if err != nil {
- return false, err
- }
-
- feedID, err := strconv.ParseInt(id, 10, 64)
- if err != nil {
- return false, fmt.Errorf("invalid feed ID: %w", err)
- }
-
- // Fetch feed
- feed, err := r.Queries.GetFeed(ctx, feedID)
- if err != nil {
- if err == sql.ErrNoRows {
- return false, fmt.Errorf("feed not found")
- }
- return false, fmt.Errorf("failed to query feed: %w", err)
- }
-
- // Check authorization
- if feed.UserID != userID {
- return false, fmt.Errorf("forbidden: you don't have access to this feed")
- }
-
- err = r.Queries.UnsubscribeFeed(ctx, feed.ID)
- if err != nil {
- return false, fmt.Errorf("failed to unsubscribe from feed: %w", err)
- }
-
- return true, nil
-}
-
-// MarkArticleRead is the resolver for the markArticleRead field.
-func (r *mutationResolver) MarkArticleRead(ctx context.Context, id string) (*model.Article, error) {
- userID, err := getUserIDFromContext(ctx)
- if err != nil {
- return nil, err
- }
-
- articleID, err := strconv.ParseInt(id, 10, 64)
- if err != nil {
- return nil, fmt.Errorf("invalid article ID: %w", err)
- }
-
- // Fetch article
- article, err := r.Queries.GetArticle(ctx, articleID)
- if err != nil {
- if err == sql.ErrNoRows {
- return nil, fmt.Errorf("article not found")
- }
- return nil, fmt.Errorf("failed to query article: %w", err)
- }
-
- // Check authorization (article belongs to a feed owned by user)
- feed, err := r.Queries.GetFeed(ctx, article.FeedID)
- if err != nil {
- return nil, fmt.Errorf("failed to query feed: %w", err)
- }
- if feed.UserID != userID {
- return nil, fmt.Errorf("forbidden: you don't have access to this article")
- }
-
- // Update the article's read status
- err = r.Queries.UpdateArticleReadStatus(ctx, db.UpdateArticleReadStatusParams{
- IsRead: 1,
- ID: article.ID,
- })
- if err != nil {
- return nil, fmt.Errorf("failed to mark article as read: %w", err)
- }
-
- // Fetch the updated article
- return r.Query().Article(ctx, id)
-}
-
-// MarkArticleUnread is the resolver for the markArticleUnread field.
-func (r *mutationResolver) MarkArticleUnread(ctx context.Context, id string) (*model.Article, error) {
- userID, err := getUserIDFromContext(ctx)
- if err != nil {
- return nil, err
- }
-
- articleID, err := strconv.ParseInt(id, 10, 64)
- if err != nil {
- return nil, fmt.Errorf("invalid article ID: %w", err)
- }
-
- // Fetch article
- article, err := r.Queries.GetArticle(ctx, articleID)
- if err != nil {
- if err == sql.ErrNoRows {
- return nil, fmt.Errorf("article not found")
- }
- return nil, fmt.Errorf("failed to query article: %w", err)
- }
-
- // Check authorization (article belongs to a feed owned by user)
- feed, err := r.Queries.GetFeed(ctx, article.FeedID)
- if err != nil {
- return nil, fmt.Errorf("failed to query feed: %w", err)
- }
- if feed.UserID != userID {
- return nil, fmt.Errorf("forbidden: you don't have access to this article")
- }
-
- // Update the article's read status
- err = r.Queries.UpdateArticleReadStatus(ctx, db.UpdateArticleReadStatusParams{
- IsRead: 0,
- ID: article.ID,
- })
- if err != nil {
- return nil, fmt.Errorf("failed to mark article as unread: %w", err)
- }
-
- // Fetch the updated article
- return r.Query().Article(ctx, id)
-}
-
-// MarkFeedRead is the resolver for the markFeedRead field.
-func (r *mutationResolver) MarkFeedRead(ctx context.Context, id string) (*model.Feed, error) {
- userID, err := getUserIDFromContext(ctx)
- if err != nil {
- return nil, err
- }
-
- feedID, err := strconv.ParseInt(id, 10, 64)
- if err != nil {
- return nil, fmt.Errorf("invalid feed ID: %w", err)
- }
-
- // Fetch feed
- feed, err := r.Queries.GetFeed(ctx, feedID)
- if err != nil {
- if err == sql.ErrNoRows {
- return nil, fmt.Errorf("feed not found")
- }
- return nil, fmt.Errorf("failed to query feed: %w", err)
- }
-
- // Check authorization
- if feed.UserID != userID {
- return nil, fmt.Errorf("forbidden: you don't have access to this feed")
- }
-
- // Update all articles in the feed to be read
- err = r.Queries.MarkFeedArticlesRead(ctx, feed.ID)
- if err != nil {
- return nil, fmt.Errorf("failed to mark feed as read: %w", err)
- }
-
- // Fetch the updated feed
- return r.Query().Feed(ctx, id)
-}
-
-// MarkFeedUnread is the resolver for the markFeedUnread field.
-func (r *mutationResolver) MarkFeedUnread(ctx context.Context, id string) (*model.Feed, error) {
- userID, err := getUserIDFromContext(ctx)
- if err != nil {
- return nil, err
- }
-
- feedID, err := strconv.ParseInt(id, 10, 64)
- if err != nil {
- return nil, fmt.Errorf("invalid feed ID: %w", err)
- }
-
- // Fetch feed
- feed, err := r.Queries.GetFeed(ctx, feedID)
- if err != nil {
- if err == sql.ErrNoRows {
- return nil, fmt.Errorf("feed not found")
- }
- return nil, fmt.Errorf("failed to query feed: %w", err)
- }
-
- // Check authorization
- if feed.UserID != userID {
- return nil, fmt.Errorf("forbidden: you don't have access to this feed")
- }
-
- // Update all articles in the feed to be unread
- err = r.Queries.MarkFeedArticlesUnread(ctx, feed.ID)
- if err != nil {
- return nil, fmt.Errorf("failed to mark feed as unread: %w", err)
- }
-
- // Fetch the updated feed
- return r.Query().Feed(ctx, id)
-}
-
-// Login is the resolver for the login field.
-func (r *mutationResolver) Login(ctx context.Context, username string, password string) (*model.AuthPayload, error) {
- // Verify user credentials
- user, err := r.Queries.GetUserByUsername(ctx, username)
- if err != nil {
- if err == sql.ErrNoRows {
- return nil, fmt.Errorf("invalid credentials")
- }
- return nil, fmt.Errorf("failed to query user: %w", err)
- }
-
- // Verify password
- if !auth.VerifyPassword(user.PasswordHash, password) {
- return nil, fmt.Errorf("invalid credentials")
- }
-
- // Get Echo context to create session
- echoCtx, err := getEchoContext(ctx)
- if err != nil {
- return nil, fmt.Errorf("failed to get echo context: %w", err)
- }
-
- // Create session and store user ID
- if err := r.SessionConfig.SetUserID(echoCtx, user.ID); err != nil {
- return nil, fmt.Errorf("failed to create session: %w", err)
- }
-
- return &model.AuthPayload{
- User: &model.User{
- ID: strconv.FormatInt(user.ID, 10),
- Username: user.Username,
- },
- }, nil
-}
-
-// Logout is the resolver for the logout field.
-func (r *mutationResolver) Logout(ctx context.Context) (bool, error) {
- // Get Echo context to destroy session
- echoCtx, err := getEchoContext(ctx)
- if err != nil {
- return false, fmt.Errorf("failed to get echo context: %w", err)
- }
-
- // Destroy session
- if err := r.SessionConfig.DestroySession(echoCtx); err != nil {
- return false, fmt.Errorf("failed to destroy session: %w", err)
- }
-
- return true, nil
-}
-
-// Feeds is the resolver for the feeds field.
-func (r *queryResolver) Feeds(ctx context.Context) ([]*model.Feed, error) {
- userID, err := getUserIDFromContext(ctx)
- if err != nil {
- return nil, err
- }
-
- dbFeeds, err := r.Queries.GetFeeds(ctx, userID)
- if err != nil {
- return nil, fmt.Errorf("failed to query feeds: %w", err)
- }
-
- // Fetch unread counts for all feeds
- unreadCounts, err := r.Queries.GetFeedUnreadCounts(ctx, userID)
- if err != nil {
- return nil, fmt.Errorf("failed to query unread counts: %w", err)
- }
- countMap := make(map[int64]int64, len(unreadCounts))
- for _, uc := range unreadCounts {
- countMap[uc.FeedID] = uc.UnreadCount
- }
-
- var feeds []*model.Feed
- for _, dbFeed := range dbFeeds {
- feeds = append(feeds, &model.Feed{
- ID: strconv.FormatInt(dbFeed.ID, 10),
- URL: dbFeed.Url,
- Title: dbFeed.Title,
- FetchedAt: dbFeed.FetchedAt,
- IsSubscribed: dbFeed.IsSubscribed == 1,
- UnreadCount: int32(countMap[dbFeed.ID]),
- })
- }
-
- return feeds, nil
-}
-
-// UnreadArticles is the resolver for the unreadArticles field.
-func (r *queryResolver) UnreadArticles(ctx context.Context, feedID *string, after *string, first *int32) (*model.ArticleConnection, error) {
- return r.paginatedArticles(ctx, 0, feedID, after, first)
-}
-
-// ReadArticles is the resolver for the readArticles field.
-func (r *queryResolver) ReadArticles(ctx context.Context, feedID *string, after *string, first *int32) (*model.ArticleConnection, error) {
- return r.paginatedArticles(ctx, 1, feedID, after, first)
-}
-
-// Feed is the resolver for the feed field.
-func (r *queryResolver) Feed(ctx context.Context, id string) (*model.Feed, error) {
- userID, err := getUserIDFromContext(ctx)
- if err != nil {
- return nil, err
- }
-
- feedID, err := strconv.ParseInt(id, 10, 64)
- if err != nil {
- return nil, fmt.Errorf("invalid feed ID: %w", err)
- }
-
- // Fetch feed
- dbFeed, err := r.Queries.GetFeed(ctx, feedID)
- if err != nil {
- if err == sql.ErrNoRows {
- return nil, fmt.Errorf("feed not found")
- }
- return nil, fmt.Errorf("failed to query feed: %w", err)
- }
-
- // Check authorization
- if dbFeed.UserID != userID {
- return nil, fmt.Errorf("forbidden: you don't have access to this feed")
- }
-
- return &model.Feed{
- ID: strconv.FormatInt(dbFeed.ID, 10),
- URL: dbFeed.Url,
- Title: dbFeed.Title,
- FetchedAt: dbFeed.FetchedAt,
- IsSubscribed: dbFeed.IsSubscribed == 1,
- }, nil
-}
-
-// Article is the resolver for the article field.
-func (r *queryResolver) Article(ctx context.Context, id string) (*model.Article, error) {
- userID, err := getUserIDFromContext(ctx)
- if err != nil {
- return nil, err
- }
-
- articleID, err := strconv.ParseInt(id, 10, 64)
- if err != nil {
- return nil, fmt.Errorf("invalid article ID: %w", err)
- }
-
- // Fetch article
- row, err := r.Queries.GetArticle(ctx, articleID)
- if err != nil {
- if err == sql.ErrNoRows {
- return nil, fmt.Errorf("article not found")
- }
- return nil, fmt.Errorf("failed to query article: %w", err)
- }
-
- // Check authorization (article's feed belongs to user)
- // Note: GetArticle already joins with feeds table and returns feed info,
- // but we need to check the user_id. Since GetArticleRow doesn't include user_id,
- // we need to fetch the feed separately.
- feed, err := r.Queries.GetFeed(ctx, row.FeedID)
- if err != nil {
- return nil, fmt.Errorf("failed to query feed: %w", err)
- }
- if feed.UserID != userID {
- return nil, fmt.Errorf("forbidden: you don't have access to this article")
- }
-
- return &model.Article{
- ID: strconv.FormatInt(row.ID, 10),
- FeedID: strconv.FormatInt(row.FeedID, 10),
- GUID: row.Guid,
- Title: row.Title,
- URL: row.Url,
- IsRead: row.IsRead == 1,
- Feed: &model.Feed{
- ID: strconv.FormatInt(row.FeedID2, 10),
- URL: row.FeedUrl,
- Title: row.FeedTitle,
- },
- }, nil
-}
-
-// CurrentUser is the resolver for the currentUser field.
-func (r *queryResolver) CurrentUser(ctx context.Context) (*model.User, error) {
- userID, err := getUserIDFromContext(ctx)
- if err != nil {
- // Not authenticated - return nil (not an error)
- return nil, nil
- }
-
- user, err := r.Queries.GetUserByID(ctx, userID)
- if err != nil {
- if err == sql.ErrNoRows {
- return nil, nil
- }
- return nil, fmt.Errorf("failed to query user: %w", err)
- }
-
- return &model.User{
- ID: strconv.FormatInt(user.ID, 10),
- Username: user.Username,
- }, nil
-}
-
-// Mutation returns gql.MutationResolver implementation.
-func (r *Resolver) Mutation() gql.MutationResolver { return &mutationResolver{r} }
-
-// Query returns gql.QueryResolver implementation.
-func (r *Resolver) Query() gql.QueryResolver { return &queryResolver{r} }
-
-type mutationResolver struct{ *Resolver }
-type queryResolver struct{ *Resolver }