facade4datatug

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 5, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package facade4datatug holds the DataTug extension's application commands.

It is storage-agnostic by construction: the only persistence API it uses is dal-go, so it never learns whether the host backs it with Firestore, an in-memory database (tests), or anything else. Platform needs arrive through ports declared in ports.go.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrOrgRequired is returned when a GitHub project is registered without
	// its repository owner.
	ErrOrgRequired = errors.New("github org is required")

	// ErrRepoRequired is returned when a GitHub project is registered without
	// its repository name.
	ErrRepoRequired = errors.New("github repo is required")
)
View Source
var (
	ErrPersonalAccountUnavailable = errors.New("personal account unavailable")
	ErrForeignAccount             = errors.New("account is not the caller's personal account")
	ErrPlanUnavailable            = errors.New("plan response unavailable")
)
View Source
var (
	// ErrUserIDRequired is returned when a command is called without a user.
	ErrUserIDRequired = errors.New("user id is required")

	// ErrTitleRequired is returned when a project is created without a title.
	ErrTitleRequired = errors.New("project title is required")

	// ErrUnsupportedStore is returned for a store this API does not serve. A
	// project in a GitHub repo is created by the client holding the user's
	// GitHub credential, and a local filesystem project by the datatug CLI
	// agent — only the DataTug cloud store is created here.
	ErrUnsupportedStore = errors.New("store is not served by the DataTug cloud API")
)

Functions

This section is empty.

Types

type AdmissionReader added in v0.4.0

type AdmissionReader interface {
	ReadAdmission(context.Context, string, time.Time) (AdmissionState, error)
}

type AdmissionState added in v0.4.0

type AdmissionState struct {
	TodayUsed int64
	Blocked   string
}

AdmissionState supplies guards that are authoritative outside this module. Blocked is empty, daily, free_budget, or unverified.

type Facade

type Facade struct {
	// contains filtered or unexported fields
}

Facade carries the injected database and ports for the DataTug extension's application commands. The host constructs one Facade at composition time (sneat-go/pkg/modules/datatug), wiring a real adapter per port; tests construct it over an in-memory database with fakes.

func NewFacade

func NewFacade(db dal.DB, ids IDGenerator) Facade

NewFacade returns a Facade over the given database and ports.

func (Facade) CreateProject

func (f Facade) CreateProject(
	ctx context.Context, userID, storeID, title string,
) (projectID string, err error)

CreateProject creates a DataTug project in the cloud store and registers its brief in the user's DataTug index, both in one transaction. It returns the id of the created project.

func (Facade) RegisterGithubProject added in v0.2.0

func (f Facade) RegisterGithubProject(
	ctx context.Context, userID string, request RegisterGithubProjectRequest,
) (projectID string, err error)

RegisterGithubProject records a project that lives in a GitHub repository in the user's DataTug index, so it shows up among the user's projects.

The project files themselves are created by the client that holds the user's GitHub credential — this command only keeps the index; the cloud never talks to GitHub. It returns the project id the web client addresses the project by (`repo@org@folder`).

type FirstAdmittedMonthReader added in v0.4.0

type FirstAdmittedMonthReader interface {
	ReadFirstAdmittedMonth(context.Context, string, string, string) (string, error)
}

FirstAdmittedMonthReader reads the same immutable, server-only first-admission marker used by the AI meter. Empty means no question has been admitted yet. It is keyed by product and caller, with the proved personal account included so the host can reject a mismatched binding.

type IDGenerator

type IDGenerator interface {
	// NewID returns the id of a new record.
	NewID(ctx context.Context) (string, error)
}

IDGenerator is a PORT: the module must not import sneat-go-core, sneat-core-modules or another extension's backend, so anything it needs from outside crosses a small interface defined here and is satisfied by an adapter in the host composition root (sneat-go/pkg/modules/datatug/adapters.go). Domain tests fake the port — see facade_test.go's fakeIDGenerator.

type PersonalAccount added in v0.4.0

type PersonalAccount struct{ ID, Title string }

PersonalAccount is an ownership assertion made by the host directory.

func ResolvePersonalPayer added in v0.4.0

func ResolvePersonalPayer(ctx context.Context, callerID, accountHint string, directory PersonalAccountDirectory) (PersonalAccount, error)

PersonalPayer is shared by plan reads and the later AI adapter. A foreign account hint is refused before any plan or usage read for that hint.

type PersonalAccountDirectory added in v0.4.0

type PersonalAccountDirectory interface {
	PersonalAccount(context.Context, string) (PersonalAccount, error)
}

PersonalAccountDirectory must prove ownership and provision the personal account through the host. This domain never infers an account from a user ID.

type PersonalPlanService added in v0.4.0

type PersonalPlanService struct {
	Directory  PersonalAccountDirectory
	Plans      PlanReader
	Usage      UsageReader
	Admission  AdmissionReader
	Config     PlanConfigReader
	Clock      PlanClock
	FirstMonth FirstAdmittedMonthReader
}

PersonalPlanService composes ports without depending on transport or store.

func (PersonalPlanService) Read added in v0.4.0

func (s PersonalPlanService) Read(ctx context.Context, callerID, accountHint, _ string) (PlanResponse, error)

type PlanAI added in v0.4.0

type PlanAI struct {
	Unit     string      `json:"unit"`
	Enforced bool        `json:"enforced"`
	PeriodID string      `json:"periodId"`
	Used     int64       `json:"used"`
	Limit    int64       `json:"limit"`
	Left     int64       `json:"left"`
	ResetsAt time.Time   `json:"resetsAt"`
	Today    PlanToday   `json:"today"`
	Blocked  *string     `json:"blocked"`
	Models   []PlanModel `json:"models"`
}

type PlanAccount added in v0.4.0

type PlanAccount struct {
	AccountID string `json:"accountId"`
	Kind      string `json:"kind"`
	Title     string `json:"title"`
	Plan      string `json:"plan"`
	Role      string `json:"role"`
	Pays      bool   `json:"pays"`
}

type PlanClock added in v0.4.0

type PlanClock interface{ Now() time.Time }

type PlanConfig added in v0.4.0

type PlanConfig struct {
	FreeFirstMonthLimits models4datatug.PlanLimits
	FreeLaterMonthLimits models4datatug.PlanLimits
	ProLimits            models4datatug.PlanLimits
	FreeModels           []PlanModel
	ProModels            []PlanModel
	DailyLimit           int64
	ActiveGrace          time.Duration
	PastDueGrace         time.Duration
	Enforced             bool
	UpgradeURL           string
	ManageURL            string
	SupportEmail         string
}

PlanConfig is supplied by the host, rather than encoded in plan policy. The two Free grants differ by the month of the first admitted question, which is independently read from the meter's server-only marker.

type PlanConfigReader added in v0.4.0

type PlanConfigReader interface {
	ReadPlanConfig(context.Context, string, time.Time) (PlanConfig, error)
}

PlanConfigReader receives the proved account and the one UTC instant sampled for this response; settings can change at runtime without implicit context.

type PlanFacts added in v0.4.0

type PlanFacts struct {
	AccountKind               string                     `json:"accountKind"`
	Tier                      string                     `json:"tier"`
	Period                    string                     `json:"period"`
	ProviderStatus            string                     `json:"providerStatus"`
	PaidUntil                 *time.Time                 `json:"paidUntil,omitempty"`
	EndsAt                    *time.Time                 `json:"endsAt,omitempty"`
	LastInvoiceRefundedInFull bool                       `json:"lastInvoiceRefundedInFull"`
	RefundedAt                *time.Time                 `json:"refundedAt,omitempty"`
	FirstPaidAt               *time.Time                 `json:"firstPaidAt,omitempty"`
	Founding                  bool                       `json:"founding"`
	Grants                    *models4datatug.PlanLimits `json:"grants,omitempty"`
}

PlanFacts are plain, provider-independent inputs to the plan-state mapping.

type PlanModel added in v0.4.0

type PlanModel struct {
	ID      string `json:"id"`
	Class   string `json:"class"`
	Weight  int64  `json:"weight"`
	Default bool   `json:"default"`
}

type PlanReader added in v0.4.0

type PlanReader interface {
	ReadCurrentPlan(context.Context, string) (*models4datatug.PlanRecord, error)
}

PlanReader reads only plan/current; an unreadable record falls toward Free.

type PlanResponse added in v0.4.0

type PlanResponse struct {
	V             int                       `json:"v"`
	Payer         string                    `json:"payer"`
	AccountID     string                    `json:"accountId"`
	AccountTitle  string                    `json:"accountTitle"`
	Role          string                    `json:"role"`
	Plan          string                    `json:"plan"`
	EffectivePlan string                    `json:"effectivePlan"`
	Status        string                    `json:"status"`
	Period        string                    `json:"period"`
	PaidUntil     *time.Time                `json:"paidUntil,omitempty"`
	Founding      bool                      `json:"founding"`
	Limits        models4datatug.PlanLimits `json:"limits"`
	AI            PlanAI                    `json:"ai"`
	OwnKeyWorks   bool                      `json:"ownKeyWorks"`
	CanUpgrade    bool                      `json:"canUpgrade"`
	UpgradeURL    string                    `json:"upgradeUrl"`
	ManageURL     string                    `json:"manageUrl,omitempty"`
	SupportEmail  string                    `json:"supportEmail,omitempty"`
	Accounts      []PlanAccount             `json:"accounts"`
}

type PlanStateResult added in v0.4.0

type PlanStateResult struct {
	Outcome string                     `json:"outcome"`
	Reason  string                     `json:"reason,omitempty"`
	Record  *models4datatug.PlanRecord `json:"record,omitempty"`
}

PlanStateResult names a write, leave, or refusal. The writer retains the previous aiExtraQuestions and stamps updatedAt outside this pure function.

func PlanStateFor added in v0.4.0

func PlanStateFor(f PlanFacts) PlanStateResult

PlanStateFor follows the ordered precedence of the version-1 state table. This slice grants paid access only to personal Pro; ended states remain mappable even when a provider reports a now-unsupported tier.

type PlanToday added in v0.4.0

type PlanToday struct {
	Used  int64 `json:"used"`
	Limit int64 `json:"limit"`
}

type RegisterGithubProjectRequest added in v0.2.0

type RegisterGithubProjectRequest struct {
	Org    string `json:"org"`
	Repo   string `json:"repo"`
	Folder string `json:"folder"`
	Title  string `json:"title"`
}

RegisterGithubProjectRequest describes a project that already exists in a GitHub repository.

func (RegisterGithubProjectRequest) Validate added in v0.2.0

func (v RegisterGithubProjectRequest) Validate() error

Validate validates the request.

type UsageReader added in v0.4.0

type UsageReader interface {
	ReadUsage(context.Context, string, string) (*models4datatug.AIUsageRecord, error)
}

UsageReader reads the requested UTC month; nil means no count document.

Jump to

Keyboard shortcuts

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