Go · 1593 bytes Raw Blame History
1 // SPDX-License-Identifier: AGPL-3.0-or-later
2
3 package lifecycle
4
5 import (
6 "context"
7 "fmt"
8
9 "github.com/tenseleyFlow/shithub/internal/auth/audit"
10 reposdb "github.com/tenseleyFlow/shithub/internal/repos/sqlc"
11 )
12
13 // Archive sets is_archived=true on the repo. Idempotent in spirit — a
14 // double-archive returns ErrAlreadyArchived so handlers can surface a
15 // "this repo is already archived" friendly message without having to
16 // inspect state up front.
17 func Archive(ctx context.Context, deps Deps, actorUserID, repoID int64) error {
18 rq := reposdb.New()
19 repo, err := rq.GetRepoByID(ctx, deps.Pool, repoID)
20 if err != nil {
21 return fmt.Errorf("load repo: %w", err)
22 }
23 if repo.IsArchived {
24 return ErrAlreadyArchived
25 }
26 if err := rq.ArchiveRepo(ctx, deps.Pool, repoID); err != nil {
27 return fmt.Errorf("archive: %w", err)
28 }
29 if deps.Audit != nil {
30 _ = deps.Audit.Record(ctx, deps.Pool, actorUserID,
31 audit.ActionRepoArchived, audit.TargetRepo, repoID, nil)
32 }
33 return nil
34 }
35
36 // Unarchive clears is_archived. Same idempotency contract as Archive.
37 func Unarchive(ctx context.Context, deps Deps, actorUserID, repoID int64) error {
38 rq := reposdb.New()
39 repo, err := rq.GetRepoByID(ctx, deps.Pool, repoID)
40 if err != nil {
41 return fmt.Errorf("load repo: %w", err)
42 }
43 if !repo.IsArchived {
44 return ErrNotArchived
45 }
46 if err := rq.UnarchiveRepo(ctx, deps.Pool, repoID); err != nil {
47 return fmt.Errorf("unarchive: %w", err)
48 }
49 if deps.Audit != nil {
50 _ = deps.Audit.Record(ctx, deps.Pool, actorUserID,
51 audit.ActionRepoUnarchived, audit.TargetRepo, repoID, nil)
52 }
53 return nil
54 }
55