generated from mathias/template-go-web
feat(gitea): surface mathias's own open Gitea issues on stage 03 (#4)
TDD: IssueNodes parses /repos/issues/search into stage nodes (title, repo tag, clickable html_url). gitea.MyIssues() reads GITEA_TOKEN and skips gracefully when unset, mirroring the existing liveOverlay fallback pattern. Single-operator homelab, not per-visitor OAuth: a static read-only PAT gates on "cleared Authentik forward-auth", not per-user token exchange — see #4 discussion. GITEA_TOKEN provisioning in infra (ExternalSecret) is a separate follow-up; without it the overlay is inert (no crash, just no live nodes), so this ships safely ahead of that wiring. Nodes with a url now render as clickable <a class="node"> instead of <div class="node">.
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
package atlas
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// IssueNodes parses a Gitea `/repos/issues/search` response (the
|
||||
// authenticated user's own open issues, newest first) into one node per
|
||||
// issue, linking out to the issue.
|
||||
func IssueNodes(searchJSON []byte) ([]Node, error) {
|
||||
var issues []struct {
|
||||
Number int `json:"number"`
|
||||
Title string `json:"title"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
Repository struct {
|
||||
FullName string `json:"full_name"`
|
||||
} `json:"repository"`
|
||||
}
|
||||
if err := json.Unmarshal(searchJSON, &issues); err != nil {
|
||||
return nil, fmt.Errorf("parse issues: %w", err)
|
||||
}
|
||||
nodes := make([]Node, 0, len(issues))
|
||||
for _, i := range issues {
|
||||
nodes = append(nodes, Node{
|
||||
Title: fmt.Sprintf("#%d %s", i.Number, i.Title),
|
||||
Tags: []string{"live · Gitea", i.Repository.FullName},
|
||||
URL: i.HTMLURL,
|
||||
})
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
Reference in New Issue
Block a user