tenseleyflow/shithub / 8f8c84e

Browse files

api/meta: GET /api/v1/meta capability discovery endpoint

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
8f8c84e14ccfb0c72686e341c06dbc47ea653b98
Parents
4e49e63
Tree
57c7810

1 changed file

StatusFile+-
A internal/web/handlers/api/meta.go 51 0
internal/web/handlers/api/meta.goadded
@@ -0,0 +1,51 @@
1
+// SPDX-License-Identifier: AGPL-3.0-or-later
2
+
3
+package api
4
+
5
+import (
6
+	"net/http"
7
+
8
+	"github.com/go-chi/chi/v5"
9
+
10
+	"github.com/tenseleyFlow/shithub/internal/version"
11
+)
12
+
13
+// APICapabilities is the canonical list of feature capabilities exposed
14
+// by this server. Each S50 batch (§1 user, §2 repos, §3 issues, …)
15
+// appends its capability name here so the CLI can gate behavior. The
16
+// values are short kebab-case identifiers, GitHub-flavored when an
17
+// obvious mapping exists.
18
+//
19
+// Append-only is a soft contract: removing an entry is a breaking
20
+// change for clients that read this list.
21
+var APICapabilities = []string{
22
+	"pat-auth",
23
+	"check-runs",
24
+	"stars",
25
+	"actions-lifecycle",
26
+}
27
+
28
+type metaResponse struct {
29
+	Version      string   `json:"version"`
30
+	Commit       string   `json:"commit"`
31
+	BuiltAt      string   `json:"built_at"`
32
+	Capabilities []string `json:"capabilities"`
33
+}
34
+
35
+// mountMeta registers the capability-discovery endpoint. /api/v1/meta is
36
+// unauthenticated by design — clients use it to negotiate capabilities
37
+// before they have credentials.
38
+func (h *Handlers) mountMeta(r chi.Router) {
39
+	r.Get("/api/v1/meta", h.metaGet)
40
+}
41
+
42
+func (h *Handlers) metaGet(w http.ResponseWriter, _ *http.Request) {
43
+	caps := make([]string, len(APICapabilities))
44
+	copy(caps, APICapabilities)
45
+	writeJSON(w, http.StatusOK, metaResponse{
46
+		Version:      version.Version,
47
+		Commit:       version.Commit,
48
+		BuiltAt:      version.BuiltAt,
49
+		Capabilities: caps,
50
+	})
51
+}