Make answering own the inbox state transition
This commit is contained in:
@@ -103,7 +103,7 @@ func (m *Manager) AnswerAgain(ctx context.Context, creator api.User, create api.
|
|||||||
}
|
}
|
||||||
open := item
|
open := item
|
||||||
open.State = api.Open
|
open.State = api.Open
|
||||||
_, err = CheckResponse(open, create)
|
err = checkResponse(open, create)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return api.Task{}, err
|
return api.Task{}, err
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-17
@@ -19,7 +19,7 @@ func (m *Manager) Respond(ctx context.Context, user string, creates []api.InboxR
|
|||||||
return nil, fmt.Errorf("%w: responses is empty", ErrInvalid)
|
return nil, fmt.Errorf("%w: responses is empty", ErrInvalid)
|
||||||
}
|
}
|
||||||
|
|
||||||
resolutions := []store.Resolution{}
|
responses := []api.InboxResponse{}
|
||||||
sessions := []string{}
|
sessions := []string{}
|
||||||
seen := map[string]bool{}
|
seen := map[string]bool{}
|
||||||
|
|
||||||
@@ -34,21 +34,18 @@ func (m *Manager) Respond(ctx context.Context, user string, creates []api.InboxR
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
state, err := CheckResponse(item, create)
|
err = checkResponse(item, create)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resolutions = append(resolutions, store.Resolution{
|
responses = append(responses, newResponse(item.Id, user, create))
|
||||||
State: state,
|
|
||||||
Response: newResponse(item.Id, user, create),
|
|
||||||
})
|
|
||||||
if !slices.Contains(sessions, item.AgentSessionId) {
|
if !slices.Contains(sessions, item.AgentSessionId) {
|
||||||
sessions = append(sessions, item.AgentSessionId)
|
sessions = append(sessions, item.AgentSessionId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := m.store.Respond(ctx, user, resolutions)
|
err := m.store.Respond(ctx, user, responses)
|
||||||
if errors.Is(err, store.ErrNotOpen) {
|
if errors.Is(err, store.ErrNotOpen) {
|
||||||
return nil, fmt.Errorf("%w: %w", ErrConflict, err)
|
return nil, fmt.Errorf("%w: %w", ErrConflict, err)
|
||||||
}
|
}
|
||||||
@@ -56,8 +53,8 @@ func (m *Manager) Respond(ctx context.Context, user string, creates []api.InboxR
|
|||||||
slog.Error("record inbox responses", "user", user, "err", err)
|
slog.Error("record inbox responses", "user", user, "err", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, res := range resolutions {
|
for _, resp := range responses {
|
||||||
slog.Info("inbox response recorded", "item", res.Response.ItemId, "response", res.Response.Id, "type", res.Response.Type, "user", user)
|
slog.Info("inbox response recorded", "item", resp.ItemId, "response", resp.Id, "type", resp.Type, "user", user)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, id := range sessions {
|
for _, id := range sessions {
|
||||||
@@ -70,8 +67,8 @@ func (m *Manager) Respond(ctx context.Context, user string, creates []api.InboxR
|
|||||||
}
|
}
|
||||||
|
|
||||||
items := []api.InboxItem{}
|
items := []api.InboxItem{}
|
||||||
for _, res := range resolutions {
|
for _, resp := range responses {
|
||||||
item, err := m.store.GetInboxItem(ctx, res.Response.ItemId)
|
item, err := m.store.GetInboxItem(ctx, resp.ItemId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -126,9 +123,9 @@ func (m *Manager) Dismiss(ctx context.Context, user, itemID string) (api.InboxIt
|
|||||||
return m.store.GetInboxItem(ctx, itemID)
|
return m.store.GetInboxItem(ctx, itemID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckResponse(item api.InboxItem, c api.InboxResponseCreate) (api.InboxState, error) {
|
func checkResponse(item api.InboxItem, c api.InboxResponseCreate) error {
|
||||||
if item.State != api.Open {
|
if item.State != api.Open {
|
||||||
return "", fmt.Errorf("%w: item %s is %s", ErrConflict, item.Id, item.State)
|
return fmt.Errorf("%w: item %s is %s", ErrConflict, item.Id, item.State)
|
||||||
}
|
}
|
||||||
|
|
||||||
text := ""
|
text := ""
|
||||||
@@ -136,8 +133,8 @@ func CheckResponse(item api.InboxItem, c api.InboxResponseCreate) (api.InboxStat
|
|||||||
text = strings.TrimSpace(*c.Text)
|
text = strings.TrimSpace(*c.Text)
|
||||||
}
|
}
|
||||||
images := c.Images != nil && len(*c.Images) > 0
|
images := c.Images != nil && len(*c.Images) > 0
|
||||||
bad := func(format string, args ...any) (api.InboxState, error) {
|
bad := func(format string, args ...any) error {
|
||||||
return "", fmt.Errorf("%w: item %s: "+format, append([]any{ErrInvalid, item.Id}, args...)...)
|
return fmt.Errorf("%w: item %s: "+format, append([]any{ErrInvalid, item.Id}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch c.Type {
|
switch c.Type {
|
||||||
@@ -158,13 +155,13 @@ func CheckResponse(item api.InboxItem, c api.InboxResponseCreate) (api.InboxStat
|
|||||||
}
|
}
|
||||||
seen[o] = true
|
seen[o] = true
|
||||||
}
|
}
|
||||||
return api.Answered, nil
|
return nil
|
||||||
|
|
||||||
case api.Other:
|
case api.Other:
|
||||||
if text == "" && !images {
|
if text == "" && !images {
|
||||||
return bad("other needs text or images")
|
return bad("other needs text or images")
|
||||||
}
|
}
|
||||||
return api.Answered, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return bad("unknown response type %q", c.Type)
|
return bad("unknown response type %q", c.Type)
|
||||||
|
|||||||
@@ -111,17 +111,11 @@ func (s *Store) ListInbox(ctx context.Context, f InboxFilter) ([]api.InboxItem,
|
|||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Resolution struct {
|
func (s *Store) Respond(ctx context.Context, actor string, responses []api.InboxResponse) error {
|
||||||
Response api.InboxResponse
|
|
||||||
State api.InboxState
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Store) Respond(ctx context.Context, actor string, resolutions []Resolution) error {
|
|
||||||
return s.write(ctx, func(tx *sql.Tx, emit emitFunc) error {
|
return s.write(ctx, func(tx *sql.Tx, emit emitFunc) error {
|
||||||
for _, r := range resolutions {
|
for _, resp := range responses {
|
||||||
resp := r.Response
|
|
||||||
res, err := tx.ExecContext(ctx, `UPDATE inbox_items SET state = ?, resolved_by = ?, resolved_at = ? WHERE id = ? AND state = ?`,
|
res, err := tx.ExecContext(ctx, `UPDATE inbox_items SET state = ?, resolved_by = ?, resolved_at = ? WHERE id = ? AND state = ?`,
|
||||||
string(r.State), actor, now(), resp.ItemId, string(api.Open))
|
string(api.Answered), actor, now(), resp.ItemId, string(api.Open))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user