Chat edit with WS notification

- PUT /messages/:msgId now returns {ok, edited:true}
- WS pushes 'message_edited' event to both chat members
- Mobile UI: show 'ред.' marker when edited=true
- Audit log: message.edit action
- Repo: GetMessage helper for fetching after edit
This commit is contained in:
ga 2026-08-20 15:52:57 +00:00
parent 4533ceaf2d
commit 3fe6930af2
2 changed files with 48 additions and 1 deletions

View File

@ -199,6 +199,23 @@ func (r *Repo) EditMessage(ctx context.Context, msgID, senderID uuid.UUID, newBo
return nil
}
func (r *Repo) GetMessage(ctx context.Context, msgID uuid.UUID) (*Message, error) {
m := &Message{}
err := r.pool.QueryRow(ctx, `
SELECT id, chat_id, sender_id, COALESCE(body, ''), COALESCE(photo_url, ''),
read, edited, deleted, created_at, updated_at
FROM messages WHERE id=$1`, msgID,
).Scan(&m.ID, &m.ChatID, &m.SenderID, &m.Body, &m.PhotoURL,
&m.Read, &m.Edited, &m.Deleted, &m.CreatedAt, &m.UpdatedAt)
if errors.Is(err, pgx.ErrNoRows) {
return nil, nil
}
if err != nil {
return nil, err
}
return m, nil
}
func (r *Repo) DeleteMessage(ctx context.Context, msgID, senderID uuid.UUID) error {
res, err := r.pool.Exec(ctx, `
UPDATE messages SET deleted=TRUE, body=NULL, photo_url=NULL, updated_at=NOW()

View File

@ -220,7 +220,37 @@ func (h *ChatHandlers) EditMessage(c *fiber.Ctx) error {
if err := h.Chat.EditMessage(c.UserContext(), msgID, me, body); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"ok": true})
_ = h.Audit.Log(c.UserContext(), &audit.Event{
UserID: &me, Action: "message.edit", TargetType: "message", TargetID: msgID.String(),
IP: c.IP(), UserAgent: c.Get("User-Agent"),
})
// Push WS — обоим участникам чата
m, err := h.Chat.GetMessage(c.UserContext(), msgID)
if err == nil && m != nil {
ch, _ := h.Chat.GetByID(c.UserContext(), m.ChatID)
if ch != nil {
other := ch.UserA
if other == me {
other = ch.UserB
}
for _, uid := range []uuid.UUID{me, other} {
h.Hub.SendTo(uid, ws.Outgoing{
Type: "message_edited",
Payload: fiber.Map{
"id": m.ID,
"chat_id": m.ChatID,
"body": m.Body,
"edited": m.Edited,
"updated_at": m.UpdatedAt,
},
Time: time.Now(),
})
}
}
}
return c.JSON(fiber.Map{"ok": true, "edited": true})
}
func (h *ChatHandlers) DeleteMessage(c *fiber.Ctx) error {