Add registry, ingest, timeline, tickets features

This commit is contained in:
2026-02-05 22:49:11 +03:00
parent 1aba59fca5
commit fe9e08f1a6
44 changed files with 3514 additions and 31 deletions

64
internal/api/timeline.go Normal file
View File

@@ -0,0 +1,64 @@
package api
import (
"net/http"
"strconv"
"strings"
"reanimator/internal/repository/timeline"
)
func writeTimelineResponse(w http.ResponseWriter, r *http.Request, repo *timeline.EventRepository, subjectType string, subjectID int64) {
limit := 50
if raw := r.URL.Query().Get("limit"); raw != "" {
if parsed, err := strconv.Atoi(raw); err == nil {
limit = parsed
} else {
writeError(w, http.StatusBadRequest, "invalid limit")
return
}
}
var cursor *timeline.Cursor
if raw := r.URL.Query().Get("cursor"); raw != "" {
decoded, err := timeline.DecodeCursor(raw)
if err != nil {
writeError(w, http.StatusBadRequest, "invalid cursor")
return
}
cursor = &decoded
}
items, next, err := repo.List(r.Context(), subjectType, subjectID, limit, cursor)
if err != nil {
writeError(w, http.StatusInternalServerError, "list timeline failed")
return
}
var nextCursor *string
if next != nil {
value := timeline.EncodeCursor(*next)
nextCursor = &value
}
writeJSON(w, http.StatusOK, map[string]any{
"items": items,
"next_cursor": nextCursor,
})
}
func parseTimelineID(path, prefix string) int64 {
if !strings.HasPrefix(path, prefix) || !strings.HasSuffix(path, "/timeline") {
return 0
}
trimmed := strings.TrimPrefix(path, prefix)
trimmed = strings.TrimSuffix(trimmed, "/timeline")
if trimmed == "" || strings.Contains(trimmed, "/") {
return 0
}
id, err := strconv.ParseInt(trimmed, 10, 64)
if err != nil || id <= 0 {
return 0
}
return id
}