Gitfed
bastien-mrq/gitfed / internal / store / pins.go
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
}