70 lines
1.6 KiB
Go
70 lines
1.6 KiB
Go
package store
|
|
|
|
import (
|
|
"embed"
|
|
"encoding/json"
|
|
"fmt"
|
|
"sort"
|
|
"sync"
|
|
|
|
"git.dumerain.org/alban/calcul-astreintes/internal/models"
|
|
)
|
|
|
|
/*
|
|
On embarque internal/store/profiles.json dans le binaire.
|
|
Ça simplifie énormément le "standalone": pas de fichier externe obligatoire.
|
|
*/
|
|
//go:embed profiles.json
|
|
var embeddedFS embed.FS
|
|
|
|
type ProfileRepo struct {
|
|
mu sync.RWMutex
|
|
profiles map[string]models.Profile
|
|
}
|
|
|
|
type embeddedData struct {
|
|
Rules models.GlobalRules `json:"rules"`
|
|
Profiles []models.Profile `json:"profiles"`
|
|
}
|
|
|
|
func NewEmbeddedRepo() (*ProfileRepo, *models.GlobalRules, error) {
|
|
b, err := embeddedFS.ReadFile("profiles.json")
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
var data embeddedData
|
|
if err := json.Unmarshal(b, &data); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
repo := &ProfileRepo{profiles: map[string]models.Profile{}}
|
|
for _, p := range data.Profiles {
|
|
repo.profiles[p.ID] = p
|
|
}
|
|
return repo, &data.Rules, nil
|
|
}
|
|
|
|
// List : profils triés par label (pour un dropdown stable).
|
|
func (r *ProfileRepo) List() ([]models.ProfileListItem, error) {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
items := make([]models.ProfileListItem, 0, len(r.profiles))
|
|
for _, p := range r.profiles {
|
|
items = append(items, models.ProfileListItem{ID: p.ID, Label: p.Label})
|
|
}
|
|
sort.Slice(items, func(i, j int) bool { return items[i].Label < items[j].Label })
|
|
return items, nil
|
|
}
|
|
|
|
func (r *ProfileRepo) Get(id string) (models.Profile, error) {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
p, ok := r.profiles[id]
|
|
if !ok {
|
|
return models.Profile{}, fmt.Errorf("profil introuvable: %s", id)
|
|
}
|
|
return p, nil
|
|
}
|