Documentation
¶
Overview ¶
Package store owns the database schema, GORM models, repositories, and the goose-driven migration runner. Callers depend on small interfaces declared where they consume the store (handler packages); only this package needs to know about GORM.
Index ¶
- Variables
- func MigrateDown(ctx context.Context, db *gorm.DB) error
- func MigrateStatus(ctx context.Context, db *gorm.DB) (string, error)
- func MigrateUp(ctx context.Context, db *gorm.DB) error
- func NewTestDB(t *testing.T) *gorm.DB
- func Open(url string) (*gorm.DB, error)
- func RawCreateForTest(db *gorm.DB, pr PullRequest) error
- func SQLDB(db *gorm.DB) (*sql.DB, error)
- type Message
- type PullRequest
- type PullRequests
- func (r *PullRequests) AddMessage(ctx context.Context, repository string, prNumber int, ...) error
- func (r *PullRequests) Delete(ctx context.Context, repository string, prNumber int) error
- func (r *PullRequests) DeleteStaleBefore(ctx context.Context, cutoff time.Time) (int64, error)
- func (r *PullRequests) FindStuck(ctx context.Context, cutoff time.Time) ([]PullRequest, error)
- func (r *PullRequests) ListOpen(ctx context.Context) ([]PullRequest, error)
- func (r *PullRequests) MarkClosed(ctx context.Context, repository string, prNumber int) error
- func (r *PullRequests) Messages(ctx context.Context, repository string, prNumber int) ([]Message, error)
- func (r *PullRequests) Touch(ctx context.Context, repository string, prNumber int) error
- type Reactions
- type RepoMapping
- type Target
Constants ¶
This section is empty.
Variables ¶
var ErrNotFound = errors.New("store: not found")
ErrNotFound is returned when a lookup matches no row.
Functions ¶
func MigrateDown ¶
MigrateDown rolls back the most recent migration.
func MigrateStatus ¶
MigrateStatus returns a human-readable list of each migration and whether it has been applied.
func NewTestDB ¶
NewTestDB returns a *gorm.DB backed by a fresh on-disk SQLite database inside t.TempDir, with all migrations applied. The database is closed and removed automatically when the test completes.
We use an on-disk file rather than `:memory:` because the goose-sqlite driver expects a stable database name to record migration state, and multiple in-memory connections in the same process are not always shared.
func Open ¶
Open opens a SQLite database for production use. The url accepts either a raw file path or the "file:..." DSN form used in our config defaults.
GORM's logger is silenced for "record not found" because we treat ErrNotFound as a normal return value, not a warning condition.
func RawCreateForTest ¶
func RawCreateForTest(db *gorm.DB, pr PullRequest) error
RawCreateForTest inserts a pull_requests row preserving the caller's CreatedAt/UpdatedAt/ClosedAt, bypassing GORM's autoCreate/UpdateTime. Used by tests that need to seed PRs with a controlled age and open/closed state. A zero CreatedAt defaults to UpdatedAt.
Types ¶
type Message ¶ added in v0.20.0
type Message struct {
ID uint `gorm:"primaryKey"`
PullRequestID uint `gorm:"column:pull_request_id;not null"`
Channel string `gorm:"column:channel;not null"`
MessageID string `gorm:"column:message_id;not null"`
}
Message is one posted messenger message for a PR. (PullRequestID, Channel) is unique — at most one message per channel per PR. Channel is a room in the messenger; MessageID is the messenger's id for the post (Slack's ts).
type PullRequest ¶ added in v0.20.0
type PullRequest struct {
ID uint `gorm:"primaryKey"`
Repository string `gorm:"column:gh_repository;not null"`
PRNumber int `gorm:"column:pr_number;not null"`
CreatedAt time.Time `gorm:"column:created_at;not null"`
UpdatedAt time.Time `gorm:"column:updated_at;not null"`
ClosedAt *time.Time `gorm:"column:closed_at"`
Messages []Message `gorm:"foreignKey:PullRequestID;constraint:OnDelete:CASCADE"`
}
PullRequest is one tracked PR. (Repository, PRNumber) is the natural key; CreatedAt is kept for later statistics, UpdatedAt is the activity clock (bumped on open and every review/comment) driving digest idle-detection and cleanup, and ClosedAt (nil = open) marks merged/closed so the digest skips it.
func (PullRequest) TableName ¶ added in v0.20.0
func (PullRequest) TableName() string
TableName pins the table name; do not rely on GORM pluralization.
type PullRequests ¶ added in v0.20.0
type PullRequests struct {
// contains filtered or unexported fields
}
PullRequests persists tracked PRs and their per-channel messenger messages.
func NewPullRequests ¶ added in v0.20.0
func NewPullRequests(db *gorm.DB) *PullRequests
NewPullRequests constructs a PullRequests repository bound to db.
func (*PullRequests) AddMessage ¶ added in v0.20.0
func (r *PullRequests) AddMessage(ctx context.Context, repository string, prNumber int, channel, messageID string) error
AddMessage records one posted message, creating the PR row on first sight. Insertion is idempotent on (pull_request_id, channel): re-adding the same channel for the same PR is a no-op, which makes the open fan-out safe to replay after a partial failure or GitHub redelivery.
func (*PullRequests) Delete ¶ added in v0.20.0
Delete removes the PR and (by cascade) its messages. Missing PR is a no-op.
func (*PullRequests) DeleteStaleBefore ¶ added in v0.20.0
DeleteStaleBefore removes PRs idle since before cutoff (messages cascade).
func (*PullRequests) FindStuck ¶ added in v0.20.0
func (r *PullRequests) FindStuck(ctx context.Context, cutoff time.Time) ([]PullRequest, error)
FindStuck returns open PRs idle since before cutoff, messages preloaded, oldest first.
func (*PullRequests) ListOpen ¶ added in v0.20.0
func (r *PullRequests) ListOpen(ctx context.Context) ([]PullRequest, error)
ListOpen returns every not-yet-closed PR, ordered for stable output.
func (*PullRequests) MarkClosed ¶ added in v0.20.0
MarkClosed sets closed_at. Missing PR is a no-op.
type Reactions ¶ added in v0.18.0
type Reactions struct {
Enabled bool
NewPR string
MergedPR string
ClosedPR string
Approved string
Commented string
RequestChange string
BotReview string
}
Reactions is the resolved per-repo reaction-emoji set (Slack emoji names without colons). Enabled gates whether close/review reactions are added at all. Empty BotReview disables the bot-reviewer marker.
type RepoMapping ¶
type RepoMapping struct {
Repository string
SlackChannel string
Mentions []string
// Resolved per-repo behavioral config (global config.yaml defaults merged
// with org/* and org/repo overrides). Formatting-only — not part of
// validation or the lock.
Reactions Reactions
IgnoreAIReviews bool
DependabotFormat bool
}
RepoMapping is the value object handlers and validators consume — a GitHub repository routed to a Slack channel with an optional mentions list, and resolved behavioral config (global defaults merged with org/* and org/repo overrides). The source of truth for routing lives in config.yaml's mappings: section (loaded by internal/config / internal/mappings); the type stays here so consumers don't have to know who produced it.