Go · 2227 bytes Raw Blame History
1 // SPDX-License-Identifier: AGPL-3.0-or-later
2
3 package policy
4
5 // RepoRef is the policy-side projection of a repos row. Construct from
6 // either reposdb.Repo or any of the GetRepoBy* row types via NewRepoRef
7 // helpers in the policy package's adapters file (kept policy-internal
8 // so the policy package never imports reposdb directly — sqlc rows
9 // flow in via constructors at call boundaries).
10 //
11 // OwnerOrgID is the S31-shape: zero today; populated when org-owned
12 // repos ship. Can() already branches on OwnerOrgID > 0 so that S31's
13 // org membership lookup plugs in cleanly.
14 type RepoRef struct {
15 ID int64
16 OwnerUserID int64
17 OwnerOrgID int64
18 Visibility string // "public" | "private"
19 IsArchived bool
20 IsDeleted bool
21
22 // AuthorUserID is the author of the *issue or PR* being acted on,
23 // when the action is one that grants author-self privileges
24 // (`ActionIssueClose`, `ActionPullClose`). Zero means "no author
25 // context" — e.g. a repo-level read or write — and is the default.
26 // Handlers populate this only on the close paths; everywhere else
27 // it stays zero.
28 //
29 // This is a pragmatic v1 shape: instead of introducing an
30 // IssueRef/PullRef parallel to RepoRef, we widen RepoRef with the
31 // one fact the close gate needs. When/if more issue-level rules
32 // land (assignee privileges, labeler privileges) we'll graduate
33 // to a proper IssueRef. The audit captured the design tradeoff;
34 // don't add new fields here without re-reading that note.
35 AuthorUserID int64
36 }
37
38 // IsPublic returns true when the repo's visibility column is "public".
39 // Other code paths must not parse Visibility directly — read it through
40 // these helpers so the canonical strings live in one place.
41 func (r RepoRef) IsPublic() bool { return r.Visibility == "public" }
42
43 // IsPrivate is the inverse. Use whichever phrasing reads better at the
44 // call site.
45 func (r RepoRef) IsPrivate() bool { return r.Visibility == "private" }
46
47 // IsOwnedByUser reports whether userID is the direct user owner. Keep
48 // ownership interpretation here so handlers do not grow inline owner
49 // checks next to request behavior.
50 func (r RepoRef) IsOwnedByUser(userID int64) bool {
51 return userID != 0 && r.OwnerUserID == userID
52 }
53