package store
import (
"time"
bolt "go.etcd.io/bbolt"
)
// PinnedRepo is a purely local bookmark: a principal's own note that a repo
// on some other (or even the same) instance is worth a link on their
// dashboard. It grants no access by itself — it's a convenience, not a
// credential. Pinning a private repo you don't actually have access to just
// gives you a link that 404s.
type PinnedRepo struct {
Principal string `json:"principal"` // the local account that pinned it
Domain string `json:"domain"` // remote instance domain, e.g. "chez-moi.fr"
Repo string `json:"repo"` // repo name on that instance, e.g. "alice/mon-projet"
Label string `json:"label,omitempty"`
AddedAt time.Time `json:"added_at"`
}
func pinKey(principal, domain, repo string) string {
return principal + "\x00" + domain + "/" + repo
}
// PinRepo records (or updates the label of) a bookmark for principal.
func (s *Store) PinRepo(principal, domain, repo, label string) error {
p := PinnedRepo{Principal: principal, Domain: domain, Repo: repo, Label: label, AddedAt: time.Now().UTC()}
return s.db.Update(func(tx *bolt.Tx) error {
return putJSON(tx, bucketPins, pinKey(principal, domain, repo), p)
})
}
func (s *Store) UnpinRepo(principal, domain, repo string) error {
return s.db.Update(func(tx *bolt.Tx) error {
return deleteKey(tx, bucketPins, pinKey(principal, domain, repo))
})
}
// ListPinnedRepos returns principal's own bookmarks, oldest first.
func (s *Store) ListPinnedRepos(principal string) ([]PinnedRepo, error) {
var out []PinnedRepo
err := s.db.View(func(tx *bolt.Tx) error {
var err error
out, err = listJSONPrefix[PinnedRepo](tx, bucketPins, principal+"\x00")
return err
})
return out, err
}