domain

package
v0.22.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package domain defines the digest domain's ports, DTOs, and constants — the scheduled stuck-PR reminder contracts. It imports only the standard library, the shared kernel, and the routing domain.

Index

Constants

View Source
const (
	GitHubPRURLPrefix = "https://github.com/"
	PullPathSegment   = "/pull/"
)

GitHubPRURLPrefix and PullPathSegment build a PR's github.com web URL as GitHubPRURLPrefix + "owner/repo" + PullPathSegment + number. The store keeps no URL, so it is reconstructed; this assumes github.com (GitHub Enterprise hosts are not handled here).

View Source
const BlockTypeSection = "section"

BlockTypeSection is the block type the digest emits (a Block Kit "section").

Variables

This section is empty.

Functions

This section is empty.

Types

type Block

type Block struct {
	Type string
	Text *TextObject
}

Block is one rendered block of a Message. The digest emits only section blocks (Type == BlockTypeSection, Text set).

type DigestComposer

type DigestComposer interface {
	StuckDigestParent(mentions []string, count int) Message
	StuckDigestList(prs []StuckPR) Message
}

DigestComposer renders the two messages of a channel's stuck-PR digest: a parent headline carrying the mentions and PR count, and a threaded list of one line per stuck PR. Implementations produce a presentation-neutral Message the poster delivers.

type DigestPoster

type DigestPoster interface {
	PostMessage(ctx context.Context, channel string, msg Message) (string, error)
	PostReply(ctx context.Context, channel, threadTS string, msg Message) (string, error)
}

DigestPoster posts a composed message to a channel, either as a top-level post (PostMessage, returning its id) or threaded under one (PostReply).

type DigestReporter

type DigestReporter interface {
	Report(ctx context.Context) error
	ReportSchedule(ctx context.Context, spec string) error
}

DigestReporter runs one stuck-PR digest pass: find open PRs idle since the start of today, group them by channel, and post one reminder per channel. Report includes every enabled repo; ReportSchedule includes only repos whose effective digest is enabled and scheduled at spec.

type DigestResolver

type DigestResolver interface {
	DigestFor(repository string) routingdomain.DigestConfig
}

DigestResolver looks up the effective digest configuration for a repository.

type DigestScheduler

type DigestScheduler interface {
	Run(ctx context.Context) error
}

DigestScheduler runs one cron per distinct schedule spec, calling its job for each tick, and blocks until its context is cancelled.

type MappingLookup

type MappingLookup interface {
	Get(ctx context.Context, repository string) (routingdomain.RepoMapping, error)
}

MappingLookup resolves a repository to its Slack channel and mentions.

type Message

type Message struct {
	Blocks   []Block
	Fallback string
}

Message is a presentation-neutral rendered message that crosses the composer and poster ports. The application treats it as opaque — it only carries a composer's output to the poster; the Slack adapter maps it to and from the platform message type at the boundary.

type MessageRef

type MessageRef struct {
	Channel   string
	MessageID string
}

MessageRef is one posted message for a PR: the channel it lives in and the messenger's id for the post.

type PullRequest

type PullRequest struct {
	Repository string
	PRNumber   int
	UpdatedAt  time.Time
	Messages   []MessageRef
}

PullRequest is the digest's view of one tracked PR: the fields the reporter reads to build a reminder. It is mapped from the store's persistence model at the repository boundary, so no gorm-tagged type crosses a port.

type ReporterParams

type ReporterParams struct {
	Finder   StuckFinder
	Mappings MappingLookup
	Poster   DigestPoster
	Composer DigestComposer
	Digests  DigestResolver
	Logger   *slog.Logger
	TZ       *time.Location
	Now      func() time.Time
}

ReporterParams bundles everything the stuck-PR reporter needs. Now supplies the clock (time.Now in production, a fixed clock in tests); TZ is the timezone the "start of day" cutoff is computed in (nil defaults to UTC) and must match the scheduler's timezone so a digest fires and cuts off in the same zone.

type ScheduleJob

type ScheduleJob interface {
	ReportSchedule(ctx context.Context, spec string) error
}

ScheduleJob is the unit the scheduler fires on each cron tick; the reporter satisfies it. spec is the cron expression that fired, so the job can include only the repos scheduled at that spec.

type SchedulerParams

type SchedulerParams struct {
	Specs  []string
	Job    ScheduleJob
	Logger *slog.Logger
	TZ     *time.Location
}

SchedulerParams bundles everything the digest scheduler needs. Specs is a list of standard 5-field cron expressions; TZ is the timezone every spec is interpreted in (nil defaults to UTC).

type StuckFinder

type StuckFinder interface {
	FindStuck(ctx context.Context, cutoff time.Time) ([]PullRequest, error)
}

StuckFinder returns open PRs (with their messages) idle since before cutoff.

type StuckPR

type StuckPR struct {
	Repository string
	Number     int
	URL        string
	IdleDays   int
}

StuckPR is one line of a channel's digest list: the PR, its web URL, and how many whole days it has sat idle.

type TextObject

type TextObject struct {
	Type string
	Text string
}

TextObject is a block's text payload.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL