Documentation
¶
Index ¶
- Constants
- Variables
- func HashRefreshToken(token string) []byte
- func HashSessionToken(token string) []byte
- type ActivityBucket
- type AuditLogEntry
- type AuditLogFilter
- type AuthCode
- type AuthorizationConfirmation
- type AuthorizationConfirmationResult
- type CountBucket
- type DeleteInsightParams
- type Encryptor
- type GetInsightParams
- type GitHubProfile
- type Grant
- type Insight
- type InsightBacklink
- type InsightDetail
- type InsightHistoryCursor
- type InsightHistoryPage
- type InsightLinkReference
- type InsightLinkWarning
- type InsightListCursor
- type InsightPage
- type InsightRevision
- type InsightSearchCursor
- type InsightSearchHit
- type InsightSearchPage
- type InsightSearchProjection
- type ListInsightHistoryParams
- type ListInsightsParams
- type OAuthClient
- type OAuthClientKind
- type Org
- type PendingAuth
- type Project
- type ProjectDashboard
- type RestoreInsightParams
- type RetiredRefreshToken
- type RevisionConflictError
- type SearchInsightsParams
- type SearchQueryMode
- type SearchTagMode
- type Store
- type TagCount
- type UpdateInsightParams
- type User
- type WebSession
- type WriteInsightParams
Constants ¶
const ( MaxInsightRevision = 1<<31 - 1 MaxInsightSearchExcludeIDs = 100 MaxInsightSearchSnippetBytes = 512 MaxInsightSearchBriefSnippetBytes = 256 )
const ( InsightLinkWarningUnresolved = "unresolved_insight_link" InsightLinkWarningSelf = "self_insight_link" )
const ( RetiredRefreshTokenReasonRotated = "rotated" RetiredRefreshTokenReasonGitHubExpired = "github_expired" RetiredRefreshTokenReasonGitHubInvalid = "github_invalid" RetiredRefreshTokenReasonGitHubMissingRefresh = "github_missing_refresh" //nolint:gosec // reason label, not a credential RetiredRefreshTokenReasonGrantDeleted = "grant_deleted" RetiredRefreshTokenReasonClientBindingMissing = "client_binding_missing" )
Variables ¶
var ( ErrInvalidTargetRevision = errors.New("invalid target revision") ErrInsightRevisionNotFound = errors.New("insight revision not found") ErrInsightKeyConflict = errors.New("insight key conflict") )
var ErrInvalidExpectedRevision = errors.New("invalid expected revision")
ErrInvalidExpectedRevision is returned for a precondition that cannot apply to the mutation.
var ErrNotFound = errors.New("not found")
ErrNotFound is returned when a queried row does not exist.
Functions ¶
func HashRefreshToken ¶ added in v0.4.0
func HashSessionToken ¶ added in v0.6.0
Types ¶
type ActivityBucket ¶ added in v0.6.0
ActivityBucket holds a single day's insight update count.
type AuditLogEntry ¶ added in v0.3.0
type AuditLogEntry struct {
ID int64
TableName string
Operation string // INSERT, UPDATE, DELETE
OldData []byte // raw JSONB; nil for INSERT
NewData []byte // raw JSONB; nil for DELETE
ChangedAt time.Time
}
AuditLogEntry is a single row from the audit_log table.
type AuditLogFilter ¶ added in v0.3.0
type AuditLogFilter struct {
TableName string // optional
Operation string // optional: INSERT, UPDATE, DELETE
Since time.Time // optional: only entries after this time
Limit int // 0 → default 100; capped at 500
}
AuditLogFilter controls which audit_log rows are returned by ListAuditLog. Zero values for string fields and a zero Since mean "no filter on that field".
type AuthCode ¶ added in v0.2.0
type AuthCode struct {
Sub string // internal user UUID (JWT sub)
GitHubID int64 // GitHub numeric ID (for logging)
Email string
Scope string
CodeChallenge string
RedirectURI string
ClientID string
RefreshAllowed bool
AccessToken string
RefreshToken string
AccessTokenExpiry time.Time
RefreshTokenExpiry time.Time
}
AuthCode holds identity and GitHub tokens between the GitHub callback and token exchange. Tokens are stored encrypted at rest; this struct carries plaintext values.
type AuthorizationConfirmation ¶ added in v0.7.0
AuthorizationConfirmation binds an authenticated identity to the client request awaiting consent. GitHub tokens are stored encrypted at rest; this struct carries plaintext values.
type AuthorizationConfirmationResult ¶ added in v0.7.0
type CountBucket ¶ added in v0.6.0
CountBucket holds a named aggregate count.
type DeleteInsightParams ¶ added in v0.6.0
type Encryptor ¶ added in v0.2.0
type Encryptor struct {
// contains filtered or unexported fields
}
Encryptor encrypts and decrypts token strings using NaCl secretbox.
func NewEncryptor ¶ added in v0.2.0
NewEncryptor returns an Encryptor keyed with key.
type GetInsightParams ¶ added in v0.6.0
type GitHubProfile ¶ added in v0.6.0
type Grant ¶ added in v0.2.0
type Grant struct {
JTI string
UserID uuid.UUID
OurRefreshToken string
ClientID string
Scope string
AccessToken string
RefreshToken string
AccessTokenExpiry time.Time
RefreshTokenExpiry time.Time
JWTExpiry time.Time
UpdatedAt time.Time
}
Grant holds a single authorization grant with the associated GitHub App tokens. Tokens are stored encrypted at rest; this struct carries plaintext values.
type Insight ¶ added in v0.4.0
type Insight struct {
ID uuid.UUID
ProjectID uuid.UUID
Key string // empty string when no key
Content string
Tags []string
Category string
Source string
CreatedBy uuid.UUID
CreatedAt time.Time
UpdatedAt time.Time
Revision int
ContentChanged bool
LinkWarnings []InsightLinkWarning
}
Insight is a text assertion stored against a project.
type InsightBacklink ¶ added in v0.6.0
type InsightDetail ¶ added in v0.6.0
type InsightDetail struct {
Insight *Insight
Links []InsightLinkReference
Backlinks []InsightBacklink
LinkCount int
BacklinkCount int
LinksTruncated bool
BacklinksTruncated bool
}
type InsightHistoryCursor ¶ added in v0.6.0
type InsightHistoryCursor struct {
Revision int
}
type InsightHistoryPage ¶ added in v0.6.0
type InsightHistoryPage struct {
InsightID uuid.UUID
Key string
CurrentRevision int
DeletedAt *time.Time
Revisions []*InsightRevision
NextCursor *InsightHistoryCursor
}
type InsightLinkReference ¶ added in v0.6.0
type InsightLinkWarning ¶ added in v0.6.0
type InsightListCursor ¶ added in v0.6.0
type InsightPage ¶ added in v0.6.0
type InsightPage struct {
Insights []*Insight
NextCursor *InsightListCursor
}
type InsightRevision ¶ added in v0.6.0
type InsightSearchCursor ¶ added in v0.6.0
type InsightSearchHit ¶ added in v0.6.0
type InsightSearchPage ¶ added in v0.6.0
type InsightSearchPage struct {
Hits []*InsightSearchHit
NextCursor *InsightSearchCursor
}
type InsightSearchProjection ¶ added in v0.7.0
type InsightSearchProjection uint8
const ( InsightSearchProjectionFull InsightSearchProjection = iota InsightSearchProjectionStandard InsightSearchProjectionBrief )
type ListInsightHistoryParams ¶ added in v0.6.0
type ListInsightsParams ¶ added in v0.6.0
type ListInsightsParams struct {
ProjectID uuid.UUID
Tag string
Limit int
After *InsightListCursor
}
type OAuthClient ¶
type OAuthClient struct {
ClientID string
ClientName string
RedirectURIs []string
GrantTypes []string
ResponseTypes []string
TokenEndpointAuthMethod string
Scope string
IssuedAt time.Time
LastUsedAt time.Time
ExpiresAt *time.Time
}
OAuthClient is a registered OAuth2 client stored in the database.
type OAuthClientKind ¶ added in v0.7.0
type OAuthClientKind string
const ( OAuthClientKindRegistered OAuthClientKind = "registered" OAuthClientKindCIMD OAuthClientKind = "cimd" )
type Org ¶ added in v0.2.0
type Org struct {
ID uuid.UUID
Slug string
Name string
Kind string // "personal" or "shared"
CreatedAt time.Time
}
Org is a tenant boundary; every project belongs to exactly one org.
type PendingAuth ¶ added in v0.2.0
type PendingAuth struct {
ClientID string
ClientName string
ClientKind OAuthClientKind
ClientLogoPNG []byte
RedirectURI string
Scope string
CodeChallenge string
ClientState string
RefreshAllowed bool
ConfirmationRequired bool
}
PendingAuth holds client PKCE and redirect params across the GitHub OAuth2 redirect leg.
type Project ¶
type Project struct {
ID uuid.UUID
OrgID uuid.UUID
CreatedBy uuid.UUID
Slug string
Name string
CreatedAt time.Time
}
Project is a named container for facts owned by an org.
type ProjectDashboard ¶ added in v0.6.0
type ProjectDashboard struct {
TotalInsights int
CategoryCounts []CountBucket
SourceCounts []CountBucket
TopTags []CountBucket
RecentActivity []ActivityBucket
RecentInsights []*Insight
}
ProjectDashboard holds read-optimized aggregate data for the project dashboard.
type RestoreInsightParams ¶ added in v0.6.0
type RetiredRefreshToken ¶ added in v0.4.0
type RetiredRefreshToken struct {
TokenHash []byte
Reason string
UserID uuid.UUID
ClientID string
OldJTI string
ReplacementJTI string
GraceExpiresAt time.Time
RetainedUntil time.Time
CreatedAt time.Time
}
RetiredRefreshToken records hashed refresh tokens after rotation or teardown.
type RevisionConflictError ¶ added in v0.6.0
func (*RevisionConflictError) Error ¶ added in v0.6.0
func (e *RevisionConflictError) Error() string
type SearchInsightsParams ¶ added in v0.6.0
type SearchInsightsParams struct {
ProjectID uuid.UUID
Query string
QueryMode SearchQueryMode
Tags []string
TagMode SearchTagMode
Limit int
After *InsightSearchCursor
ExcludeIDs []uuid.UUID
Projection InsightSearchProjection
}
type SearchQueryMode ¶ added in v0.6.0
type SearchQueryMode string
const ( SearchQueryModeAll SearchQueryMode = "all" SearchQueryModeWeb SearchQueryMode = "web" )
type SearchTagMode ¶ added in v0.6.0
type SearchTagMode string
const ( SearchTagModeAll SearchTagMode = "all" SearchTagModeAny SearchTagMode = "any" )
type Store ¶
type Store interface {
Ping(ctx context.Context) error
Migrate(ctx context.Context, logger *slog.Logger) error
Close()
UpsertUser(ctx context.Context, profile GitHubProfile) (*User, error)
GetUserByGitHubID(ctx context.Context, githubID int64) (*User, error)
GetUserByID(ctx context.Context, id uuid.UUID) (*User, error)
CreateWebSession(ctx context.Context, session WebSession) (*WebSession, error)
GetWebSessionByTokenHash(ctx context.Context, tokenHash []byte) (*WebSession, error)
TouchWebSession(ctx context.Context, id uuid.UUID, lastSeenAt, idleExpiresAt time.Time) error
RevokeWebSessionByTokenHash(ctx context.Context, tokenHash []byte) error
GetPersonalOrgByUserID(ctx context.Context, userID uuid.UUID) (*Org, error)
ListOrgs(ctx context.Context) ([]*Org, error)
EnsureProject(ctx context.Context, orgID, createdBy uuid.UUID, slug, name string) (*Project, error)
ListProjects(ctx context.Context, orgID uuid.UUID) ([]*Project, error)
GetProjectBySlug(ctx context.Context, orgID uuid.UUID, slug string) (*Project, error)
UpsertGrant(ctx context.Context, g Grant) error
GetGrant(ctx context.Context, jti string) (*Grant, error)
GetGrantByRefreshToken(ctx context.Context, token string) (*Grant, error)
GetRetiredRefreshToken(ctx context.Context, tokenHash []byte) (*RetiredRefreshToken, error)
RotateGrant(ctx context.Context, oldToken, oldJTI string, oldJWTExpiry time.Time, g Grant, retired *RetiredRefreshToken) (*Grant, error)
DeleteGrant(ctx context.Context, jti string, retired *RetiredRefreshToken) error
StorePendingAuth(ctx context.Context, state string, p PendingAuth) error
ConsumePendingAuth(ctx context.Context, state string) (*PendingAuth, error)
StoreAuthorizationConfirmation(ctx context.Context, tokenHash []byte, c AuthorizationConfirmation) error
CompleteAuthorizationConfirmation(ctx context.Context, tokenHash []byte, approve bool, code string) (*AuthorizationConfirmationResult, error)
StoreAuthCode(ctx context.Context, code string, c AuthCode) error
ConsumeAuthCode(ctx context.Context, code string) (*AuthCode, error)
RevokeToken(ctx context.Context, jti string, expiresAt time.Time) error
IsTokenRevoked(ctx context.Context, jti string) (bool, error)
WriteInsight(ctx context.Context, p WriteInsightParams) (*Insight, error)
GetInsight(ctx context.Context, p GetInsightParams) (*InsightDetail, error)
UpdateInsight(ctx context.Context, p UpdateInsightParams) (*Insight, error)
DeleteInsight(ctx context.Context, p DeleteInsightParams) (int, error)
RestoreInsight(ctx context.Context, p RestoreInsightParams) (*Insight, error)
ListInsightHistory(ctx context.Context, p ListInsightHistoryParams) (*InsightHistoryPage, error)
SearchInsights(ctx context.Context, p SearchInsightsParams) (*InsightSearchPage, error)
ListInsights(ctx context.Context, p ListInsightsParams) (*InsightPage, error)
ListTags(ctx context.Context, projectID uuid.UUID, limit int) ([]TagCount, error)
GetProjectDashboard(ctx context.Context, projectID uuid.UUID) (*ProjectDashboard, error)
SaveClient(ctx context.Context, c OAuthClient) error
UpsertClient(ctx context.Context, c OAuthClient) error
GetClient(ctx context.Context, clientID string) (*OAuthClient, error)
TouchClient(ctx context.Context, clientID string) error
ListAuditLog(ctx context.Context, filter AuditLogFilter) ([]*AuditLogEntry, error)
}
Store is the interface satisfied by the postgres.Store implementation.
type UpdateInsightParams ¶ added in v0.4.0
type UpdateInsightParams struct {
OrgID uuid.UUID
InsightID uuid.UUID
Content string
Tags []string
ChangedBy uuid.UUID
ExpectedRevision *int
}
UpdateInsightParams holds the inputs for Store.UpdateInsight. Empty Content means no change. Nil Tags means no change; non-nil (including empty) replaces tags.
type User ¶
type User struct {
ID uuid.UUID
GitHubID int64
Email string
Login string
DisplayName string
AvatarURL string
ProfileURL string
Bio string
ProfileUpdatedAt time.Time
CreatedAt time.Time
UpdatedAt time.Time
}
User is a GitHub-authenticated user stored in the database.
type WebSession ¶ added in v0.6.0
type WriteInsightParams ¶ added in v0.4.0
type WriteInsightParams struct {
ProjectID uuid.UUID
Key string // empty = no stable key
Content string
Tags []string
Category string
Source string
CreatedBy uuid.UUID
// ExpectedRevision distinguishes an omitted last-write-wins mutation from an explicit precondition.
ExpectedRevision *int
}
WriteInsightParams holds the inputs for Store.WriteInsight.