mirror of
https://github.com/warmbly/warmbly.git
synced 2026-08-19 00:01:14 +00:00
2430095197
Remove DynamoDB-backed storage paths, add Postgres/HTTP repositories for mailbox state maps, wire the internal message-map API, and add provisioning runner/migration plumbing.
122 lines
3.6 KiB
Go
122 lines
3.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"github.com/warmbly/warmbly/internal/repository"
|
|
)
|
|
|
|
// Internal email-message-map endpoints. Workers call these instead of touching
|
|
// Postgres directly (per CLAUDE.md), mirroring the DEK endpoints. Auth via
|
|
// middleware.InternalAuthMiddleware (static bearer token in INTERNAL_API_TOKEN).
|
|
//
|
|
// PUT /api/v1/internal/email-message-map body {user_id,email_id,message_id,id,thread_id} -> 204
|
|
// GET /api/v1/internal/email-message-map?user_id=&email_id=&message_id=
|
|
// -> 200 {...} | 404 (no mapping)
|
|
// DELETE /api/v1/internal/email-message-map?user_id=&email_id=&message_id=&id= -> 204
|
|
|
|
type emailMessageMapPayload struct {
|
|
UserID string `json:"user_id"`
|
|
EmailID string `json:"email_id"`
|
|
MessageID string `json:"message_id"`
|
|
ID string `json:"id"`
|
|
ThreadID string `json:"thread_id"`
|
|
}
|
|
|
|
func (h *Handler) InternalPutEmailMessageMap(c *gin.Context) {
|
|
body, err := io.ReadAll(c.Request.Body)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "read body"})
|
|
return
|
|
}
|
|
var p emailMessageMapPayload
|
|
if err := json.Unmarshal(body, &p); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "decode body"})
|
|
return
|
|
}
|
|
if p.UserID == "" || p.EmailID == "" || p.MessageID == "" || p.ID == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "user_id, email_id, message_id, id required"})
|
|
return
|
|
}
|
|
err = h.EmailMessageMap.Add(c.Request.Context(), repository.EmailMessageData{
|
|
UserID: p.UserID,
|
|
EmailID: p.EmailID,
|
|
MessageID: p.MessageID,
|
|
ID: p.ID,
|
|
ThreadID: p.ThreadID,
|
|
})
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.Status(http.StatusNoContent)
|
|
}
|
|
|
|
func (h *Handler) InternalGetEmailMessageMap(c *gin.Context) {
|
|
userID, emailID, messageID, ok := parseEmailMessageMapKey(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
data, err := h.EmailMessageMap.Get(c.Request.Context(), userID, emailID, messageID)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if data == nil {
|
|
c.Status(http.StatusNotFound)
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, emailMessageMapPayload{
|
|
UserID: data.UserID,
|
|
EmailID: data.EmailID,
|
|
MessageID: data.MessageID,
|
|
ID: data.ID,
|
|
ThreadID: data.ThreadID,
|
|
})
|
|
}
|
|
|
|
func (h *Handler) InternalDeleteEmailMessageMap(c *gin.Context) {
|
|
userID, emailID, messageID, ok := parseEmailMessageMapKey(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var id uuid.UUID
|
|
if raw := c.Query("id"); raw != "" {
|
|
parsed, err := uuid.Parse(raw)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
|
|
return
|
|
}
|
|
id = parsed
|
|
}
|
|
if err := h.EmailMessageMap.Del(c.Request.Context(), userID, emailID, messageID, id); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.Status(http.StatusNoContent)
|
|
}
|
|
|
|
func parseEmailMessageMapKey(c *gin.Context) (userID, emailID uuid.UUID, messageID string, ok bool) {
|
|
var err error
|
|
userID, err = uuid.Parse(c.Query("user_id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid user_id"})
|
|
return uuid.Nil, uuid.Nil, "", false
|
|
}
|
|
emailID, err = uuid.Parse(c.Query("email_id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid email_id"})
|
|
return uuid.Nil, uuid.Nil, "", false
|
|
}
|
|
messageID = c.Query("message_id")
|
|
if messageID == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "message_id required"})
|
|
return uuid.Nil, uuid.Nil, "", false
|
|
}
|
|
return userID, emailID, messageID, true
|
|
}
|