tenant

package
v0.51.5 Latest Latest
Warning

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

Go to latest
Published: Apr 18, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	StatusActive    = "active"
	StatusSuspended = "suspended"
)

Tenant status values.

Variables

View Source
var ErrAccountSuspended = errors.New("account suspended")

ErrAccountSuspended is returned when a tenant's status is not active.

View Source
var ErrRepoLimitExceeded = errors.New("repo limit exceeded for plan")

ErrRepoLimitExceeded is returned when adding repos would exceed the tenant's plan limit.

View Source
var ErrSessionInvalid = errors.New("session expired or not found")

ErrSessionInvalid is returned when a session is expired or not found.

Functions

func AcceptToS

func AcceptToS(ctx context.Context, db *sql.DB, tenantID string) error

AcceptToS records that a tenant has accepted the Terms of Service.

func AddTenantRepos

func AddTenantRepos(ctx context.Context, db *sql.DB, tenantID string, repos []OrgRepo) error

AddTenantRepos adds repos to a tenant's tracking list, enforcing the plan limit. Upserts run first (ON CONFLICT re-activates deactivated repos without inflating the count), then the resulting active count is checked against the plan limit and rolled back if exceeded. This prevents the previous bug where re-adding a deactivated repo at capacity was incorrectly rejected.

func CleanExpiredSessions

func CleanExpiredSessions(ctx context.Context, db *sql.DB) (int64, error)

CleanExpiredSessions removes all expired sessions. Uses a transaction with cleared app.tenant_id so the RLS bypass policy allows the DELETE across all tenants.

func ClearUpgradeRequest added in v0.26.2

func ClearUpgradeRequest(ctx context.Context, db *sql.DB, tenantID string) error

ClearUpgradeRequest removes a pending upgrade request for a tenant.

func CountTenantRepos added in v0.41.0

func CountTenantRepos(ctx context.Context, db *sql.DB, tenantID string) (int, error)

CountTenantRepos returns the number of active repos for a tenant.

func CreateAppJWT

func CreateAppJWT(cfg *GitHubAppConfig) (string, error)

CreateAppJWT creates a short-lived JWT signed with the GitHub App's private key.

func CreateSession

func CreateSession(ctx context.Context, db *sql.DB, tenantID string, ttl time.Duration) (string, error)

CreateSession generates a session token for an existing tenant. Uses a dedicated connection with cleared app.tenant_id so the RLS bypass policy allows the INSERT regardless of stale connection state.

func DeactivateTenantRepo

func DeactivateTenantRepo(ctx context.Context, db *sql.DB, tenantID, org, repo string) error

DeactivateTenantRepo marks a repo as inactive.

func DestroySession

func DestroySession(ctx context.Context, db *sql.DB, rawToken string) error

DestroySession removes a session by its raw token. Uses a transaction with cleared app.tenant_id so the RLS bypass policy allows the DELETE regardless of stale connection state.

func GetLastSignIn added in v0.41.0

func GetLastSignIn(ctx context.Context, db *sql.DB, tenantID string) *time.Time

GetLastSignIn returns the most recent session creation time for a tenant. Uses a dedicated connection with cleared app.tenant_id so RLS bypass allows the query regardless of stale connection state.

func GetTenantIDByUsername added in v0.26.2

func GetTenantIDByUsername(ctx context.Context, db *sql.DB, username string) (string, error)

GetTenantIDByUsername returns the tenant ID for a given GitHub username.

func GetWeeklyEventCount

func GetWeeklyEventCount(ctx context.Context, db *sql.DB, tenantID string) (int, error)

GetWeeklyEventCount returns the total events this week for a tenant's repos.

func HardResetRepo added in v0.45.6

func HardResetRepo(ctx context.Context, db *sql.DB, org, repo string) (int64, error)

HardResetRepo clears error counter, import state, and repo metadata for a specific org/repo. Forces a full reimport on the next scheduled run.

func HashToken

func HashToken(raw string) string

HashToken returns the hex-encoded SHA-256 hash of a raw token.

func IncrementImportErrors added in v0.22.0

func IncrementImportErrors(ctx context.Context, db *sql.DB, id, errMsg string) error

IncrementImportErrors increments the consecutive error counter and stores the last error.

func IncrementImportErrorsByRepo added in v0.33.0

func IncrementImportErrorsByRepo(ctx context.Context, db *sql.DB, org, repo, errMsg string) error

IncrementImportErrorsByRepo increments error counter for all active tenant_repo rows of a given org/repo.

func InsertMinimalTenant added in v0.26.2

func InsertMinimalTenant(ctx context.Context, db *sql.DB, githubID int64, username string) (string, error)

InsertMinimalTenant creates a tenant with only GitHub ID and username (for admin invites).

func PurgeOldTokenQuotaSamples added in v0.51.2

func PurgeOldTokenQuotaSamples(ctx context.Context, db *sql.DB, before time.Time) (int64, error)

PurgeOldTokenQuotaSamples deletes samples older than the given time.

func RecordTokenQuotaSample added in v0.51.2

func RecordTokenQuotaSample(ctx context.Context, db *sql.DB, installationID int64, login string, limit, used int) error

RecordTokenQuotaSample writes a single quota snapshot to the time-series table.

func ResetImportErrors added in v0.22.0

func ResetImportErrors(ctx context.Context, db *sql.DB, id string) error

ResetImportErrors clears the error counter and last error after a successful import.

func ResetImportErrorsByRepo added in v0.28.10

func ResetImportErrorsByRepo(ctx context.Context, db *sql.DB, org, repo string) (int64, error)

ResetImportErrorsByRepo clears the error counter for a specific org/repo across all tenants.

func SaveInstallation

func SaveInstallation(ctx context.Context, db *sql.DB, tenantID string, installationID int64, targetType, targetLogin string, permissions []byte, appID int64) error

SaveInstallation stores or updates a GitHub App installation for a tenant. appID is the GitHub App ID from the webhook payload (installation.app_id).

func StartOfWeek added in v0.12.0

func StartOfWeek() time.Time

StartOfWeek returns the Monday 00:00 UTC of the current week.

func SuspendInstallation

func SuspendInstallation(ctx context.Context, db *sql.DB, installationID int64) error

SuspendInstallation marks an installation as suspended.

func UpdatePlan

func UpdatePlan(ctx context.Context, db *sql.DB, tenantID, plan string, maxRepos, maxEventsPerWeek int) error

UpdatePlan sets a tenant's plan, repo limit, and event limit.

func UpdateStatus added in v0.50.3

func UpdateStatus(ctx context.Context, db *sql.DB, tenantID, status string) error

UpdateStatus sets the tenant status (e.g. "active", "suspended").

Types

type ActiveInstallation

type ActiveInstallation struct {
	ID    int64
	Login string
}

ActiveInstallation holds the GitHub installation ID and target org login.

func GetActiveInstallations

func GetActiveInstallations(ctx context.Context, db *sql.DB, tenantID string, appID int64) ([]ActiveInstallation, error)

GetActiveInstallations returns non-suspended installations for a tenant. appID filters to installations belonging to this GitHub App (0 means no filter).

func GetInstallationForOrg added in v0.3.1

func GetInstallationForOrg(ctx context.Context, db *sql.DB, tenantID, org string, appID int64) (*ActiveInstallation, error)

GetInstallationForOrg returns the active installation for a tenant's org, if any. appID filters to installations belonging to this GitHub App (0 means no filter).

type ActiveRepo

type ActiveRepo struct {
	Org  string
	Repo string
}

ActiveRepo is a repo eligible for import.

func GetActiveReposForInstall

func GetActiveReposForInstall(ctx context.Context, db *sql.DB, tenantID string, installationID int64) ([]ActiveRepo, error)

GetActiveReposForInstall returns active repos for a tenant's installation.

type ActiveTenant

type ActiveTenant struct {
	ID       string
	Username string
}

ActiveTenant represents a tenant with at least one active repo.

func GetActiveTenants

func GetActiveTenants(ctx context.Context, db *sql.DB) ([]ActiveTenant, error)

GetActiveTenants returns all tenants that have accepted ToS and have active repos.

type GitHubAppConfig

type GitHubAppConfig struct {
	AppID      int64
	PrivateKey *rsa.PrivateKey
	BaseURL    string // override for testing, default: https://api.github.com
}

GitHubAppConfig holds the GitHub App credentials for minting installation tokens.

func LoadGitHubAppConfig added in v0.3.1

func LoadGitHubAppConfig() (*GitHubAppConfig, error)

LoadGitHubAppConfig reads GitHub App credentials from environment variables.

type ImportWorkRow added in v0.33.0

type ImportWorkRow struct {
	TenantRepoID string
	TenantID     string
	Org          string
	Repo         string
	Plan         string
	EventCount   int
}

ImportWorkRow is a raw row from the import work list query.

func ListImportWork added in v0.33.0

func ListImportWork(ctx context.Context, db *sql.DB) ([]ImportWorkRow, error)

ListImportWork returns all active tenant_repo rows eligible for import, joined with tenant plan. Sorted deterministically for sharding.

func ListImportWorkForRepo added in v0.40.0

func ListImportWorkForRepo(ctx context.Context, db *sql.DB, org, repo string) ([]ImportWorkRow, error)

ListImportWorkForRepo returns import work rows for a single repo across all tenants.

type Installation

type Installation struct {
	ID             string
	TenantID       string
	InstallationID int64
	TargetType     string
	TargetLogin    string
	SuspendedAt    *time.Time
	CreatedAt      time.Time
}

Installation represents a GitHub App installation for a tenant.

func ListInstallations

func ListInstallations(ctx context.Context, db *sql.DB, tenantID string) ([]Installation, error)

ListInstallations returns all installations for a tenant.

type InstallationToken

type InstallationToken struct {
	Token     string    `json:"token"`
	ExpiresAt time.Time `json:"expires_at"`
}

InstallationToken is a short-lived token scoped to a GitHub App installation.

func MintInstallationToken

func MintInstallationToken(ctx context.Context, cfg *GitHubAppConfig, installationID int64) (*InstallationToken, error)

MintInstallationToken exchanges an App JWT for an installation-scoped access token. The returned token is valid for 1 hour and should never be persisted.

type OrgRepo

type OrgRepo struct {
	Org  string
	Repo string
}

OrgRepo is a simple org/repo pair.

type OverviewResponse

type OverviewResponse struct {
	Usage UsageSummary   `json:"usage"`
	Repos []RepoOverview `json:"repos"`
}

OverviewResponse combines repo overview and usage summary.

func GetOverview

func GetOverview(ctx context.Context, db *sql.DB, tenantID string, days int) (*OverviewResponse, error)

GetOverview returns the full overview response with repo data and usage summary.

type RepoDetail added in v0.26.2

type RepoDetail struct {
	Org            string
	Repo           string
	Events         int
	WeeklyEvents   int
	LastImport     string
	PRTotal        int
	PRMissingSize  int
	Contributors   int
	Scored         int
	BackfillDays   int // days of backfill coverage (0 = not started)
	BackfillTarget int // target days (EventAgeDaysDefault)
}

RepoDetail holds per-repo statistics for admin inspection.

func GetTenantRepoDetails added in v0.26.2

func GetTenantRepoDetails(ctx context.Context, db *sql.DB, tenantID, since, weekStart, backfillSince string) ([]RepoDetail, error)

GetTenantRepoDetails returns per-repo statistics for a tenant. backfillSince scopes PR backfill counts to match the worker's BACKFILL_MAX_DAYS window.

type RepoOverview

type RepoOverview struct {
	Org             string  `json:"org"`
	Repo            string  `json:"repo"`
	Stars           int     `json:"stars"`
	Forks           int     `json:"forks"`
	OpenIssues      int     `json:"open_issues"`
	Events          int     `json:"events"`
	WeeklyEvents    int     `json:"weekly_events"`
	WeeklyPct       float64 `json:"weekly_pct"`
	Contributors    int     `json:"contributors"`
	Scored          int     `json:"scored"`
	Language        string  `json:"language"`
	License         string  `json:"license"`
	LastImport      string  `json:"last_import"`
	LimitReached    bool    `json:"limit_reached"`
	ImportErrors    int     `json:"import_errors"`
	ImportLastError string  `json:"import_last_error,omitempty"`
}

RepoOverview holds repo metadata and activity stats for the dashboard table.

type Tenant

type Tenant struct {
	ID                 string
	GitHubID           int64
	Username           string
	Email              string
	AvatarURL          string
	Name               string
	Company            string
	Location           string
	Bio                string
	MaxRepos           int
	MaxEventsPerWeek   int
	Plan               string
	Status             string
	ToSAcceptedAt      *time.Time
	UpgradeRequestedAt *time.Time
	CreatedAt          time.Time
	UpdatedAt          time.Time
}

Tenant represents a registered SaaS tenant.

func AuthenticateUser added in v0.48.2

func AuthenticateUser(ctx context.Context, db *sql.DB, githubID int64, username, email, avatarURL, name, company, location, bio string, ttl time.Duration) (*Tenant, string, error)

AuthenticateUser upserts the tenant and creates a session on a single dedicated connection with cleared app.tenant_id so the RLS bypass policy allows the session INSERT.

func GetTenantByGitHubID

func GetTenantByGitHubID(ctx context.Context, db *sql.DB, githubID int64) (*Tenant, error)

GetTenantByGitHubID returns a tenant by their GitHub user ID.

func GetTenantByID

func GetTenantByID(ctx context.Context, db *sql.DB, tenantID string) (*Tenant, error)

GetTenantByID returns a tenant by their internal ID.

func UpsertTenant

func UpsertTenant(ctx context.Context, db *sql.DB, githubID int64, username, email, avatarURL, name, company, location, bio string) (*Tenant, error)

UpsertTenant creates or updates a tenant by GitHub ID.

func ValidateSession

func ValidateSession(ctx context.Context, db *sql.DB, rawToken string) (*Tenant, error)

ValidateSession checks the session token and returns the associated tenant. Uses a dedicated connection with cleared app.tenant_id so the RLS bypass policy allows the JOIN across devpulse_session and devpulse_tenant.

type TenantDetail added in v0.26.2

type TenantDetail struct {
	ID               string
	Username         string
	Email            string
	Name             string
	Company          string
	Location         string
	Bio              string
	Plan             string
	Status           string
	MaxRepos         int
	MaxEventsPerWeek int
	CreatedAt        time.Time
	LastSignIn       *time.Time
}

TenantDetail is a full tenant record for admin inspection.

func GetTenantDetailByUsername added in v0.26.2

func GetTenantDetailByUsername(ctx context.Context, db *sql.DB, username string) (*TenantDetail, error)

GetTenantDetailByUsername returns detailed tenant info including email and last sign-in.

type TenantRepo

type TenantRepo struct {
	ID           string  `json:"id"`
	TenantID     string  `json:"tenant_id"`
	Org          string  `json:"org"`
	Repo         string  `json:"repo"`
	Active       bool    `json:"active"`
	LastImportAt *string `json:"last_import_at"`
}

TenantRepo represents a repo tracked by a tenant.

func ListTenantRepos

func ListTenantRepos(ctx context.Context, db *sql.DB, tenantID string) ([]TenantRepo, error)

ListTenantRepos returns all active repos for a tenant.

type TenantSummary added in v0.26.2

type TenantSummary struct {
	Username         string
	Email            string
	Name             string
	Plan             string
	Status           string
	MaxRepos         int
	MaxEventsPerWeek int
	CreatedAt        time.Time
	LastSignIn       *time.Time
}

TenantSummary is a lightweight tenant record for admin listing.

func ListTenantSummaries added in v0.26.2

func ListTenantSummaries(ctx context.Context, db *sql.DB) ([]TenantSummary, error)

ListTenantSummaries returns all tenants with their last sign-in time.

type UpgradeRequest added in v0.6.0

type UpgradeRequest struct {
	Username string
	Email    string
	Plan     string
	MaxRepos int
}

UpgradeRequest holds details returned when an upgrade is first requested.

func RequestUpgrade added in v0.6.0

func RequestUpgrade(ctx context.Context, db *sql.DB, tenantID string) (*UpgradeRequest, error)

RequestUpgrade idempotently records an upgrade request for a tenant. Returns the request details on first call, nil on subsequent calls.

type UsageSummary

type UsageSummary struct {
	Plan             string  `json:"plan"`
	MaxRepos         int     `json:"max_repos"`
	ActiveRepos      int     `json:"active_repos"`
	MaxEventsPerWeek int     `json:"max_events_per_week"`
	WeeklyEvents     int     `json:"weekly_events"`
	WeeklyPct        float64 `json:"weekly_pct"`
	LimitReached     bool    `json:"limit_reached"`
}

UsageSummary holds tenant-level usage stats for the dashboard.

Jump to

Keyboard shortcuts

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