Add Cloudflare email and collaboration workflows
This commit is contained in:
@@ -3,6 +3,8 @@ package httpserver
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/tim/cairnquire/apps/server/internal/collaboration"
|
||||
@@ -32,11 +34,12 @@ func (s *Server) handleListComments(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
anchorHash := r.URL.Query().Get("anchor_hash")
|
||||
includeResolved := r.URL.Query().Get("include_resolved") == "true"
|
||||
var comments []collaboration.Comment
|
||||
if anchorHash != "" {
|
||||
comments, err = s.collaboration.ListCommentsByAnchor(r.Context(), documentID, anchorHash)
|
||||
comments, err = s.collaboration.ListCommentsByAnchor(r.Context(), documentID, anchorHash, includeResolved)
|
||||
} else {
|
||||
comments, err = s.collaboration.ListComments(r.Context(), documentID)
|
||||
comments, err = s.collaboration.ListComments(r.Context(), documentID, includeResolved)
|
||||
}
|
||||
if err != nil {
|
||||
s.logger.Warn("list comments", "error", err)
|
||||
@@ -128,8 +131,13 @@ func (s *Server) handleListNotifications(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
unreadOnly := r.URL.Query().Get("unread") == "true"
|
||||
limit := 50
|
||||
if r.URL.Query().Get("limit") != "" {
|
||||
// Parse limit if needed, but for now just use default
|
||||
if rawLimit := r.URL.Query().Get("limit"); rawLimit != "" {
|
||||
parsed, err := strconv.Atoi(rawLimit)
|
||||
if err != nil || parsed < 1 || parsed > 100 {
|
||||
writeJSONWithStatus(w, http.StatusBadRequest, map[string]string{"error": "limit must be between 1 and 100"})
|
||||
return
|
||||
}
|
||||
limit = parsed
|
||||
}
|
||||
|
||||
notifications, err := s.collaboration.ListNotifications(r.Context(), principal, unreadOnly, limit)
|
||||
@@ -204,6 +212,21 @@ func (s *Server) handleWatchDocument(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSONWithStatus(w, http.StatusBadRequest, map[string]string{"error": "invalid request body"})
|
||||
return
|
||||
}
|
||||
req.DocumentID = strings.TrimSpace(req.DocumentID)
|
||||
document, err := s.repository.GetDocumentByID(r.Context(), req.DocumentID)
|
||||
if err != nil {
|
||||
writeJSONWithStatus(w, http.StatusNotFound, map[string]string{"error": "document not found"})
|
||||
return
|
||||
}
|
||||
canRead, err := s.canReadDocumentRecord(r, *document)
|
||||
if err != nil {
|
||||
writeJSONWithStatus(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if !canRead {
|
||||
writeJSONWithStatus(w, http.StatusNotFound, map[string]string{"error": "document not found"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.collaboration.WatchDocument(r.Context(), principal, req.DocumentID); err != nil {
|
||||
s.logger.Warn("watch document", "error", err)
|
||||
@@ -227,6 +250,7 @@ func (s *Server) handleUnwatchDocument(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSONWithStatus(w, http.StatusBadRequest, map[string]string{"error": "invalid request body"})
|
||||
return
|
||||
}
|
||||
req.DocumentID = strings.TrimSpace(req.DocumentID)
|
||||
|
||||
if err := s.collaboration.UnwatchDocument(r.Context(), principal, req.DocumentID); err != nil {
|
||||
s.logger.Warn("unwatch document", "error", err)
|
||||
@@ -250,8 +274,17 @@ func (s *Server) handleWatchFolder(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSONWithStatus(w, http.StatusBadRequest, map[string]string{"error": "invalid request body"})
|
||||
return
|
||||
}
|
||||
normalized, err := collaboration.NormalizeFolderPath(req.FolderPath)
|
||||
if err != nil {
|
||||
writeJSONWithStatus(w, http.StatusBadRequest, map[string]string{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if !s.canReadFolder(r, normalized) {
|
||||
writeJSONWithStatus(w, http.StatusNotFound, map[string]string{"error": "folder not found"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.collaboration.WatchFolder(r.Context(), principal, req.FolderPath); err != nil {
|
||||
if err := s.collaboration.WatchFolder(r.Context(), principal, normalized); err != nil {
|
||||
s.logger.Warn("watch folder", "error", err)
|
||||
writeJSONWithStatus(w, http.StatusBadRequest, map[string]string{"error": err.Error()})
|
||||
return
|
||||
@@ -273,8 +306,13 @@ func (s *Server) handleUnwatchFolder(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSONWithStatus(w, http.StatusBadRequest, map[string]string{"error": "invalid request body"})
|
||||
return
|
||||
}
|
||||
normalized, err := collaboration.NormalizeFolderPath(req.FolderPath)
|
||||
if err != nil {
|
||||
writeJSONWithStatus(w, http.StatusBadRequest, map[string]string{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.collaboration.UnwatchFolder(r.Context(), principal, req.FolderPath); err != nil {
|
||||
if err := s.collaboration.UnwatchFolder(r.Context(), principal, normalized); err != nil {
|
||||
s.logger.Warn("unwatch folder", "error", err)
|
||||
writeJSONWithStatus(w, http.StatusBadRequest, map[string]string{"error": err.Error()})
|
||||
return
|
||||
@@ -290,6 +328,20 @@ func (s *Server) handleIsWatching(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
documentID := r.URL.Query().Get("document_id")
|
||||
document, err := s.repository.GetDocumentByID(r.Context(), documentID)
|
||||
if err != nil {
|
||||
writeJSONWithStatus(w, http.StatusNotFound, map[string]string{"error": "document not found"})
|
||||
return
|
||||
}
|
||||
canRead, err := s.canReadDocumentRecord(r, *document)
|
||||
if err != nil {
|
||||
writeJSONWithStatus(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if !canRead {
|
||||
writeJSONWithStatus(w, http.StatusNotFound, map[string]string{"error": "document not found"})
|
||||
return
|
||||
}
|
||||
watching, err := s.collaboration.IsWatching(r.Context(), principal, documentID)
|
||||
if err != nil {
|
||||
s.logger.Warn("is watching", "error", err)
|
||||
|
||||
Reference in New Issue
Block a user