feat(epic-3): implémentation du Dashboard, mode lecture et notifications temps réel

This commit is contained in:
Michael committed 2026-02-04 15:12:54 +01:00
1 parent 1d31de95ec
commit dc26f22f51
20 files changed
+1237 -107

No files matched your search

+26
View File
@@ -8,6 +8,7 @@ import (
"github.com/google/uuid"
"github.com/michael/flowreader/internal/domain"
"github.com/michael/flowreader/internal/service"
"github.com/michael/flowreader/internal/utils"
)
// ArticleHandler handles article-related HTTP requests.
@@ -15,6 +16,7 @@ type ArticleHandler struct {
articleRepo domain.ArticleRepository
feedService *service.FeedService
authService *service.AuthService
sanitizer *utils.ContentSanitizer
}
// NewArticleHandler creates a new article handler.
@@ -23,6 +25,7 @@ func NewArticleHandler(articleRepo domain.ArticleRepository, feedService *servic
articleRepo: articleRepo,
feedService: feedService,
authService: authService,
sanitizer: utils.NewContentSanitizer(),
}
}
@@ -139,6 +142,13 @@ func (h *ArticleHandler) Get(w http.ResponseWriter, r *http.Request) {
return
}
// Sanitize content
if article.Content != "" {
article.Content = h.sanitizer.Sanitize(article.Content)
} else if article.Summary != "" {
article.Summary = h.sanitizer.Sanitize(article.Summary)
}
respondJSON(w, http.StatusOK, article)
}
@@ -276,6 +286,22 @@ func (h *ArticleHandler) MarkAllRead(w http.ResponseWriter, r *http.Request) {
respondJSON(w, http.StatusOK, map[string]string{"message": "All articles marked as read"})
}
// MarkAllReadGlobal handles POST /api/v1/articles/read-all
func (h *ArticleHandler) MarkAllReadGlobal(w http.ResponseWriter, r *http.Request) {
userID, err := h.getUserFromRequest(r)
if err != nil {
respondError(w, http.StatusUnauthorized, "Not authenticated")
return
}
if err := h.articleRepo.MarkAllAsReadGlobal(userID); err != nil {
respondError(w, http.StatusInternalServerError, "Failed to mark all as read")
return
}
respondJSON(w, http.StatusOK, map[string]string{"message": "All articles marked as read"})
}
// GetFavorites handles GET /api/v1/articles/favorites
func (h *ArticleHandler) GetFavorites(w http.ResponseWriter, r *http.Request) {
userID, err := h.getUserFromRequest(r)
+41
View File
@@ -0,0 +1,41 @@
package handler
import (
"log"
"net/http"
"github.com/michael/flowreader/internal/service"
"github.com/michael/flowreader/internal/ws"
)
// WSHandler handles WebSocket connections.
type WSHandler struct {
hub *ws.Hub
authService *service.AuthService
}
// NewWSHandler creates a new WS handler.
func NewWSHandler(hub *ws.Hub, authService *service.AuthService) *WSHandler {
return &WSHandler{
hub: hub,
authService: authService,
}
}
// Connect handles WebSocket initiation.
func (h *WSHandler) Connect(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("session_id")
if err != nil {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
user, err := h.authService.GetUserByToken(cookie.Value)
if err != nil || user == nil {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
log.Printf("Setting up WS for user %s", user.ID)
h.hub.ServeWS(user.ID, w, r)
}