126 lines
4.3 KiB
Go
126 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
|
|
"git.cin.su/m/Assistant/contracts/continuity"
|
|
"git.cin.su/m/Assistant/contracts/identity"
|
|
)
|
|
|
|
type attentionRepository interface {
|
|
AttentionByOwner(context.Context, identity.PrincipalID, int) ([]continuity.AttentionItem, error)
|
|
}
|
|
|
|
func registerCreatorAttentionRoutes(mux *http.ServeMux, identityClient creatorIdentityClient, repository attentionRepository) {
|
|
mux.HandleFunc("GET /v1/creator/attention", func(w http.ResponseWriter, r *http.Request) {
|
|
session, ok := creatorSessionForAttention(w, r, identityClient)
|
|
if !ok {
|
|
return
|
|
}
|
|
limit, err := parseListLimit(r.URL.Query().Get("limit"))
|
|
if err != nil {
|
|
http.Error(w, "invalid attention limit", http.StatusBadRequest)
|
|
return
|
|
}
|
|
items, err := repository.AttentionByOwner(r.Context(), session.PrincipalID, limit)
|
|
if err != nil {
|
|
http.Error(w, "attention unavailable", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Header().Set("Cache-Control", "no-store")
|
|
_ = json.NewEncoder(w).Encode(continuity.AttentionListResult{Items: items})
|
|
})
|
|
mux.HandleFunc("GET /v1/creator/today", func(w http.ResponseWriter, r *http.Request) {
|
|
session, ok := creatorSessionForAttention(w, r, identityClient)
|
|
if !ok {
|
|
return
|
|
}
|
|
items, err := repository.AttentionByOwner(r.Context(), session.PrincipalID, 50)
|
|
if err != nil {
|
|
http.Error(w, "today unavailable", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
result := continuity.TodayResult{Items: make([]continuity.TodayItem, 0, len(items))}
|
|
for _, item := range items {
|
|
result.Items = append(result.Items, continuity.TodayItem{
|
|
Title: item.Summary,
|
|
WhenUnixMillis: item.DueAtUnixMillis,
|
|
AttentionLevel: item.Level,
|
|
AttentionState: item.State,
|
|
HumanState: humanAttentionState(item.State),
|
|
DeliveryState: humanDeliveryState(item),
|
|
SourceDescription: humanAttentionSource(item.SourceKind),
|
|
ResponseHint: humanResponseHint(item),
|
|
})
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Header().Set("Cache-Control", "no-store")
|
|
_ = json.NewEncoder(w).Encode(result)
|
|
})
|
|
}
|
|
|
|
func creatorSessionForAttention(w http.ResponseWriter, r *http.Request, identityClient creatorIdentityClient) (identity.CreatorSession, bool) {
|
|
session, err := identityClient.Session(r.Context(), r.Header.Get("Authorization"))
|
|
if errors.Is(err, errCreatorSessionDenied) {
|
|
http.Error(w, "creator session denied", http.StatusUnauthorized)
|
|
return identity.CreatorSession{}, false
|
|
}
|
|
if err != nil {
|
|
http.Error(w, "identity service unavailable", http.StatusServiceUnavailable)
|
|
return identity.CreatorSession{}, false
|
|
}
|
|
return session, true
|
|
}
|
|
|
|
func humanAttentionState(state continuity.AttentionState) string {
|
|
switch state {
|
|
case continuity.AttentionPending:
|
|
return "ожидает внимания"
|
|
case continuity.AttentionDelivering:
|
|
return "доставляется"
|
|
case continuity.AttentionDelivered:
|
|
return "доставлено"
|
|
case continuity.AttentionResolved:
|
|
return "закрыто"
|
|
case continuity.AttentionSuppressed:
|
|
return "скрыто"
|
|
case continuity.AttentionExpired:
|
|
return "истекло"
|
|
case continuity.AttentionFailed:
|
|
return "не доставлено"
|
|
default:
|
|
return "состояние уточняется"
|
|
}
|
|
}
|
|
|
|
func humanResponseHint(item continuity.AttentionItem) string {
|
|
if item.State == continuity.AttentionDelivered || item.State == continuity.AttentionPending || item.State == continuity.AttentionFailed {
|
|
return "Можно ответить: «Готово», «Отложи на 10 минут» или «Отмени»."
|
|
}
|
|
if item.ResponseOutcome != "" {
|
|
return "Ответ записан: " + string(item.ResponseOutcome)
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func humanDeliveryState(item continuity.AttentionItem) string {
|
|
if item.State == continuity.AttentionDelivered {
|
|
return "уведомление отправлено"
|
|
}
|
|
if item.State == continuity.AttentionDelivering {
|
|
return "уведомление отправляется"
|
|
}
|
|
return "уведомление ещё не отправлено"
|
|
}
|
|
|
|
func humanAttentionSource(kind continuity.AttentionSourceKind) string {
|
|
if kind == continuity.AttentionSourceProspectiveReminder {
|
|
return "напоминание"
|
|
}
|
|
return "событие Домового"
|
|
}
|