package store import ( "fmt" "path/filepath" "time" "github.com/google/uuid" "printer.backend/internal/model" "printer.backend/internal/paths" ) // PrintJobStore persists print jobs as JSON files. type PrintJobStore struct { dir string } // NewPrintJobStore creates a store under dir (default data/print_jobs). func NewPrintJobStore(dir string) *PrintJobStore { if dir == "" { dir = paths.PrintJobsDir } return &PrintJobStore{dir: dir} } // List returns all print jobs sorted by creation time (newest first). func (s *PrintJobStore) List() ([]model.PrintJob, error) { return listFromDir(s.dir, func(name string) bool { return filepath.Ext(name) == ".json" }, "print jobs dir", func(j model.PrintJob) time.Time { return j.CreatedAt }, ) } // Get returns a print job by ID. func (s *PrintJobStore) Get(id string) (model.PrintJob, error) { list, err := s.List() if err != nil { return model.PrintJob{}, err } j, err := findByID(list, id, func(j model.PrintJob) string { return j.ID }) if err != nil { return model.PrintJob{}, fmt.Errorf("print job not found: %s", id) } if j.OrderIDs == nil { j.OrderIDs = []string{} } return j, nil } // Save writes a new print job and assigns an ID when empty. func (s *PrintJobStore) Save(j model.PrintJob) (model.PrintJob, error) { if err := ensureDir(s.dir); err != nil { return model.PrintJob{}, err } if j.ID == "" { j.ID = uuid.NewString() } if j.OrderIDs == nil { j.OrderIDs = []string{} } now := stampNew(&j.CreatedAt) j.CreatedAt = now j.UpdatedAt = now path := filepath.Join(s.dir, j.ID+".json") if err := writeJSON(path, j); err != nil { return model.PrintJob{}, fmt.Errorf("write print job: %w", err) } return j, nil } // Update replaces an existing print job (preserves id and created_at). func (s *PrintJobStore) Update(id string, j model.PrintJob) (model.PrintJob, error) { existing, err := s.Get(id) if err != nil { return model.PrintJob{}, err } j.ID = existing.ID j.CreatedAt = existing.CreatedAt j.UpdatedAt = time.Now().UTC() if j.OrderIDs == nil { j.OrderIDs = []string{} } path := filepath.Join(s.dir, id+".json") if err := writeJSON(path, j); err != nil { return model.PrintJob{}, fmt.Errorf("write print job: %w", err) } return j, nil } // Delete removes a print job by ID. func (s *PrintJobStore) Delete(id string) error { path := filepath.Join(s.dir, id+".json") return removeFile(path, fmt.Sprintf("print job not found: %s", id)) }