models4datatug

package
v0.13.0 Latest Latest
Warning

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

Go to latest
Published: Oct 7, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package models4datatug holds this extension's database objects and the DALgo keys they are stored under. Shared linkage reuses published contract DTOs; no database client or peer extension implementation is imported.

Copyright 2026 Sneat.co

Index

Constants

View Source
const (
	FreeMoneySettingsCollection = "datatugFreeMoneySettings"
	FreeMoneyMonthCollection    = "datatugFreeMoneyMonths"
)
View Source
const (
	GithubAppCredentialsCollection = "datatug_github_app_credentials"
	GithubOAuthStatesCollection    = "datatug_github_oauth_states"
)
View Source
const (
	SpacesCollection  = "spaces"
	PlanCollection    = "plan"
	AIUsageCollection = "aiUsage"
)
View Source
const (
	PlanApplicationCollection = "datatugPlanApplications"
	PaidMoneyMonthCollection  = "datatugPaidMoneyMonths"
)
View Source
const (
	// ProjectsCollection stores DataTug projects.
	ProjectsCollection = "datatug_projects"

	// UsersCollection is the platform's users collection.
	UsersCollection = "users"

	// UserExtCollection is the platform's collection of per-extension user
	// documents: users/{userID}/ext/{extID}. The DataTug extension's user data
	// (which stores and projects the user can see) lives there, never inline in
	// the core users/{userID} document. This mirrors the key that
	// sneat-core-modules' dal4userus.NewUserExtKey builds; the module builds it
	// itself so that it depends on dal-go only.
	UserExtCollection = "ext"

	// FirestoreStoreID is the store id of the DataTug cloud store. It is what
	// the web client sends as `?store=` and the key of the store brief in the
	// user's index.
	FirestoreStoreID = "firestore"

	// FirestoreStoreTitle is the human-readable title of the cloud store.
	FirestoreStoreTitle = "DataTug cloud"

	// GithubStoreID is the store id of a project hosted in a GitHub repository —
	// the id the web client's GitHub reader and navigation use.
	GithubStoreID = "github.com"

	// GithubStoreType is the store type reported for GitHub-hosted projects.
	GithubStoreType = "github"

	// GithubStoreTitle is the human-readable title of the GitHub store.
	GithubStoreTitle = "GitHub"

	// DefaultGithubProjectFolder is the repo folder a project lives in when the
	// user does not name one — the same default the web client's
	// parseGithubProjectId() applies.
	DefaultGithubProjectFolder = "datatug"

	// AccessPrivate means only the userIDs listed on the project can read it.
	AccessPrivate = "private"
)
View Source
const AccessProtected = "protected"
View Source
const ProjectAdmissionCollection = "projectAdmissions"
View Source
const ProtectedProjectQuotaCollection = "protectedProjectQuota"

These server-only roots require Firebase read/list exclusions at every depth before activation: spaces/{payer}/ext/datatug/protectedProjectQuota/{scope} and spaces/{projectSpace}/ext/datatug/projectAdmissions/{projectID}.

Variables

View Source
var ErrInvalidFreeMoneyKey = errors.New("invalid Free money key scope")

Functions

func NewAIUsageKey added in v0.4.0

func NewAIUsageKey(accountID, periodID string) *record.Key

func NewCurrentPlanKey added in v0.4.0

func NewCurrentPlanKey(accountID string) *record.Key

NewCurrentPlanKey names only the live entitlement document. Test-mode reconciliation deliberately uses a different key and never feeds readers.

func NewFreeMoneyGlobalMonthKey added in v0.8.0

func NewFreeMoneyGlobalMonthKey(mode, product, periodID string) (*record.Key, error)

NewFreeMoneyGlobalMonthKey selects the shared private UTC-month counter.

func NewFreeMoneyPersonMonthKey added in v0.8.0

func NewFreeMoneyPersonMonthKey(mode, product, verifiedUserID, periodID string) (*record.Key, error)

NewFreeMoneyPersonMonthKey selects a verified person's private UTC-month counter. The caller must supply a server-verified user ID.

func NewFreeMoneySettingsKey added in v0.8.0

func NewFreeMoneySettingsKey(mode, product string) (*record.Key, error)

NewFreeMoneySettingsKey selects one private configuration per mode and product. The caller must supply a server-resolved mode; no settings record is created here.

func NewGithubAppCredentialKey added in v0.13.0

func NewGithubAppCredentialKey(userID string) *record.Key

NewGithubAppCredentialKey addresses a private root-collection record for one Firebase user. It deliberately lives outside users/{uid}, whose recursive client-read rule would otherwise expose even encrypted credential metadata.

func NewGithubOAuthStateKey added in v0.13.0

func NewGithubOAuthStateKey(userID, stateDigest string) *record.Key

NewGithubOAuthStateKey addresses a single-use state in the private root collection. The id contains hashes of both the Firebase UID and OAuth state.

func NewGithubProjectID added in v0.2.0

func NewGithubProjectID(org, repo, folder string) string

NewGithubProjectID builds the id a GitHub-hosted project is addressed by: `repo@org@folder` — the format the web client's parseGithubProjectId() expects.

func NewPaidMoneyMonthKey added in v0.5.0

func NewPaidMoneyMonthKey(mode, family, accountID, periodID string) *record.Key

func NewPlanApplicationKey added in v0.5.0

func NewPlanApplicationKey(mode, family, accountID string) *record.Key

func NewProjectContactLinkageRecord added in v0.12.0

NewProjectContactLinkageRecord projects only the existing Contactus linkage fields. Mutation callers update those fields only, never contact identity or status. Contact authorization is supplied by the current-contact port.

func NewProjectKey

func NewProjectKey(projectID string) *record.Key

NewProjectKey builds the dalgo key of a project record.

func NewTestPlanKey added in v0.4.0

func NewTestPlanKey(accountID string) *record.Key

func NewUserExtKey

func NewUserExtKey(userID, extID string) *record.Key

NewUserExtKey builds the dalgo key of a user's DataTug index record: users/{userID}/ext/{extID}.

func PaidSharedProjectCreateDigest added in v0.11.0

func PaidSharedProjectCreateDigest(actorID, spaceID, commandID, title, payer, mode, product string) string

func SharedProjectCreateDigest added in v0.10.0

func SharedProjectCreateDigest(actorID, spaceID, commandID, title string) string

SharedProjectCreateDigest freezes every command payload field; JSON provides unambiguous boundaries even if a caller tries separator-shaped values.

func ValidateProjectContactRef added in v0.12.0

func ValidateProjectContactRef(ref contract4linkage.RelationshipEntityRef) error

func ValidateSharedProjectIdentifier added in v0.10.0

func ValidateSharedProjectIdentifier(id string) error

ValidateSharedProjectIdentifier accepts one bounded path segment. Core Space authority separately validates that a Space exists and is eligible.

func ValidateSharedProjectTitle added in v0.10.0

func ValidateSharedProjectTitle(title string) error

Types

type AIUsageRecord added in v0.4.0

type AIUsageRecord struct {
	V         int              `json:"v" firestore:"v"`
	PeriodID  string           `json:"periodId" firestore:"periodId"`
	Used      int64            `json:"used" firestore:"used"`
	Questions int64            `json:"questions" firestore:"questions"`
	ByMember  map[string]int64 `json:"byMember,omitempty" firestore:"byMember,omitempty"`
	Capped    bool             `json:"capped,omitempty" firestore:"capped,omitempty"`
	ResetsAt  *time.Time       `json:"resetsAt,omitempty" firestore:"resetsAt,omitempty"`
	UpdatedAt *time.Time       `json:"updatedAt,omitempty" firestore:"updatedAt,omitempty"`
}

AIUsageRecord is the version-1 UTC-month usage document.

type Created

type Created struct {
	At time.Time `json:"at" firestore:"at"`
}

Created holds the creation timestamp of a DataTug record.

type PaidMoneyMonth added in v0.5.0

type PaidMoneyMonth struct {
	V                   int    `json:"v" firestore:"v"`
	Mode                string `json:"mode" firestore:"mode"`
	AccountID           string `json:"accountId" firestore:"accountId"`
	PeriodID            string `json:"periodId" firestore:"periodId"`
	BasisRevision       int64  `json:"basisRevision" firestore:"basisRevision"`
	BasisMicroEUR       int64  `json:"basisMicroEUR" firestore:"basisMicroEUR"`
	SettledMicroEUR     int64  `json:"settledMicroEUR" firestore:"settledMicroEUR"`
	OutstandingMicroEUR int64  `json:"outstandingMicroEUR" firestore:"outstandingMicroEUR"`
	Frozen              bool   `json:"frozen" firestore:"frozen"`
}

PaidMoneyMonth matches the core paid-month fields. Core's published allocator/admission release must verify this shape before host binding.

type PlanApplication added in v0.5.0

type PlanApplication struct {
	V                             int      `json:"v" firestore:"v"`
	Mode                          string   `json:"mode" firestore:"mode"`
	Family                        string   `json:"family" firestore:"family"`
	AccountID                     string   `json:"accountId" firestore:"accountId"`
	OwnerSubscriptionID           string   `json:"ownerSubscriptionId" firestore:"ownerSubscriptionId"`
	OwnerGeneration               int64    `json:"ownerGeneration" firestore:"ownerGeneration"`
	SubscriptionRevision          int64    `json:"subscriptionRevision" firestore:"subscriptionRevision"`
	EffectDigest                  string   `json:"effectDigest" firestore:"effectDigest"`
	BasisVersion                  int64    `json:"basisVersion" firestore:"basisVersion"`
	BasisPeriods                  []string `json:"basisPeriods" firestore:"basisPeriods"`
	LimitsVersion                 string   `json:"limitsVersion,omitempty" firestore:"limitsVersion,omitempty"`
	LastFullEffectSubscriptionID  string   `json:"lastFullEffectSubscriptionId,omitempty" firestore:"lastFullEffectSubscriptionId,omitempty"`
	LastFullEffectOwnerGeneration int64    `json:"lastFullEffectOwnerGeneration,omitempty" firestore:"lastFullEffectOwnerGeneration,omitempty"`
	LastFullEffectRevision        int64    `json:"lastFullEffectRevision,omitempty" firestore:"lastFullEffectRevision,omitempty"`
	LastFullEffectQuoteKey        string   `json:"lastFullEffectQuoteKey,omitempty" firestore:"lastFullEffectQuoteKey,omitempty"`
	LastProSubscriptionID         string   `json:"lastProSubscriptionId,omitempty" firestore:"lastProSubscriptionId,omitempty"`
	LastProOwnerGeneration        int64    `json:"lastProOwnerGeneration,omitempty" firestore:"lastProOwnerGeneration,omitempty"`
	LastProQuoteKey               string   `json:"lastProQuoteKey,omitempty" firestore:"lastProQuoteKey,omitempty"`
	LastProPlanID                 string   `json:"lastProPlanId,omitempty" firestore:"lastProPlanId,omitempty"`
	LastProPaidServiceProofID     string   `json:"lastProPaidServiceProofId,omitempty" firestore:"lastProPaidServiceProofId,omitempty"`
	// These values come only from the verified payment effect's explicit grants,
	// never the limits resolver's legacy config fallback. Zero means unproved.
	LastProProtectedProjects     int64 `json:"lastProProtectedProjects,omitempty" firestore:"lastProProtectedProjects,omitempty"`
	LastProProtectedProjectUsers int64 `json:"lastProProtectedProjectUsers,omitempty" firestore:"lastProProtectedProjectUsers,omitempty"`
}

PlanApplication is private replay and last-actual-plan-write provenance. Latest applied revision may be basis-only, unlike the last Pro plan write.

type PlanLimits added in v0.4.0

type PlanLimits struct {
	Contributors          int64    `json:"contributors" firestore:"contributors"`
	ProjectGuests         int64    `json:"projectGuests" firestore:"projectGuests"`
	ProjectContributors   *int64   `json:"projectContributors,omitempty" firestore:"projectContributors,omitempty"`
	ProtectedProjects     *int64   `json:"protectedProjects,omitempty" firestore:"protectedProjects,omitempty"`
	ProtectedProjectUsers *int64   `json:"protectedProjectUsers,omitempty" firestore:"protectedProjectUsers,omitempty"`
	AIQuestions           int64    `json:"aiQuestions" firestore:"aiQuestions"`
	AIModelClasses        []string `json:"aiModelClasses" firestore:"aiModelClasses"`
	AIPaysFor             string   `json:"aiPaysFor" firestore:"aiPaysFor"`
}

PlanLimits is the version-1 allowance carried by a paid plan or a response. A Free allowance comes from host configuration, never from a stored plan.

type PlanRecord added in v0.4.0

type PlanRecord struct {
	V                int         `json:"v" firestore:"v"`
	Plan             string      `json:"plan" firestore:"plan"`
	Status           string      `json:"status" firestore:"status"`
	Period           string      `json:"period" firestore:"period"`
	PaidUntil        *time.Time  `json:"paidUntil,omitempty" firestore:"paidUntil,omitempty"`
	EndsAt           *time.Time  `json:"endsAt,omitempty" firestore:"endsAt,omitempty"`
	EndedReason      string      `json:"endedReason,omitempty" firestore:"endedReason,omitempty"`
	Founding         bool        `json:"founding" firestore:"founding"`
	Limits           *PlanLimits `json:"limits,omitempty" firestore:"limits,omitempty"`
	AIExtraQuestions int64       `json:"aiExtraQuestions,omitempty" firestore:"aiExtraQuestions,omitempty"`
	UpdatedAt        *time.Time  `json:"updatedAt,omitempty" firestore:"updatedAt,omitempty"`
}

PlanRecord is the version-1 plan/current document. Test-mode reconciliation writes plan/test instead; readers of live entitlements never use that path.

type Project

type Project struct {
	Title   string   `json:"title" firestore:"title"`
	Access  string   `json:"access,omitempty" firestore:"access,omitempty"`
	UserIDs []string `json:"userIDs,omitempty" firestore:"userIDs,omitempty"`
	Created *Created `json:"created,omitempty" firestore:"created,omitempty"`
}

Project is the data stored in a datatug_projects/{projectID} record.

func NewProjectRecord

func NewProjectRecord(projectID string) (record.Record, *Project)

NewProjectRecord wraps a fresh Project in its dalgo record, returning both the record (for database calls) and the DBO (to populate fields on).

func NewSharedProjectRecord added in v0.10.0

func NewSharedProjectRecord(spaceID, projectID string) (record.Record, *Project)

NewSharedProjectRecord reuses the existing Project DTO without a private userIDs ownership list. The canonical Space path is its ownership binding.

type ProjectAdmission added in v0.11.0

type ProjectAdmission struct {
	OwnerContact                                                                  ProjectOwnerContactProof `json:"ownerContact,omitempty" firestore:"ownerContact,omitempty"`
	Version                                                                       int                      `firestore:"v"`
	Mode, Product, PayerID, ActorID, SpaceID, ProjectID, CommandID, RequestDigest string
	LimitsVersion, SubscriptionID                                                 string
	ProfileVersion, QuotaBasisDigest                                              string
	ProtectedProjectsLimit, ProtectedUsersLimit, QuotaRevision                    int64
	OwnerGeneration                                                               int64
	CreatedAt                                                                     time.Time
}

ProjectAdmission is immutable attribution for future write/AI enforcement. It does not grant membership, included guest AI, or local execution authority.

func NewProjectAdmissionRecord added in v0.11.0

func NewProjectAdmissionRecord(space, project string) (record.Record, *ProjectAdmission)

func (ProjectAdmission) Validate added in v0.11.0

func (a ProjectAdmission) Validate() error

type ProjectBrief

type ProjectBrief struct {
	Title  string `json:"title" firestore:"title"`
	Access string `json:"access,omitempty" firestore:"access,omitempty"`
}

ProjectBrief is a brief of one project in a user's DataTug index.

type ProjectOwnerContactProof added in v0.12.0

type ProjectOwnerContactProof struct {
	Version        int                                    `json:"v,omitempty" firestore:"v,omitempty"`
	Contact        contract4linkage.RelationshipEntityRef `json:"contact" firestore:"contact"`
	Role           string                                 `json:"role,omitempty" firestore:"role,omitempty"`
	CatalogVersion string                                 `json:"catalogVersion,omitempty" firestore:"catalogVersion,omitempty"`
}

ProjectOwnerContactProof is immutable paid-create provenance, not another membership list. The actual assignment lives only in the Related graph. Ownerless historical admissions require a separately reviewed migration.

func (ProjectOwnerContactProof) Present added in v0.12.0

func (p ProjectOwnerContactProof) Present() bool

func (ProjectOwnerContactProof) Validate added in v0.12.0

func (p ProjectOwnerContactProof) Validate() error

type ProjectQuotaLimit added in v0.11.0

type ProjectQuotaLimit struct {
	Unlimited bool
	Count     int64
}

ProjectQuotaLimit distinguishes an explicit unlimited grant from absent data. Current Pro admission derives a finite limit from its frozen paid grants.

func (ProjectQuotaLimit) Allows added in v0.11.0

func (l ProjectQuotaLimit) Allows(allocated int64) bool

func (ProjectQuotaLimit) Validate added in v0.11.0

func (l ProjectQuotaLimit) Validate() error

type ProtectedProjectQuota added in v0.11.0

type ProtectedProjectQuota struct {
	Version                             int `firestore:"v"`
	Mode, Product, PayerID, BasisDigest string
	Allocated, Revision                 int64
}

ProtectedProjectQuota retains allocation count across renewals and Space boundaries. Missing records never mean zero. BasisDigest identifies a proved complete empty/imported inventory, not an operator assertion or billing term.

func NewProtectedProjectQuotaRecord added in v0.11.0

func NewProtectedProjectQuotaRecord(mode, product, payer string) (record.Record, *ProtectedProjectQuota)

func (ProtectedProjectQuota) Validate added in v0.11.0

func (q ProtectedProjectQuota) Validate() error

type SharedLinkedProject added in v0.12.0

type SharedLinkedProject struct {
	Project
	contract4linkage.WithRelatedAndIDs
}

SharedLinkedProject reuses Linkage's persisted graph at the existing shared project key. Legacy private Project/UserIDs remain unchanged; shared access never derives from that legacy list.

func NewSharedLinkedProjectRecord added in v0.12.0

func NewSharedLinkedProjectRecord(space, project string) (record.Record, *SharedLinkedProject)

type SharedProjectCreateReceipt added in v0.10.0

type SharedProjectCreateReceipt struct {
	OwnerContact  ProjectOwnerContactProof `json:"ownerContact,omitempty" firestore:"ownerContact,omitempty"`
	Version       int                      `json:"v" firestore:"v"`
	ActorID       string                   `json:"actorID" firestore:"actorID"`
	SpaceID       string                   `json:"spaceID" firestore:"spaceID"`
	CommandID     string                   `json:"commandID" firestore:"commandID"`
	Title         string                   `json:"title" firestore:"title"`
	RequestDigest string                   `json:"requestDigest" firestore:"requestDigest"`
	ProjectID     string                   `json:"projectID" firestore:"projectID"`
	CreatedAt     time.Time                `json:"createdAt" firestore:"createdAt"`
	PayerID       string                   `json:"payerID,omitempty" firestore:"payerID,omitempty"`
	Mode          string                   `json:"mode,omitempty" firestore:"mode,omitempty"`
	Product       string                   `json:"product,omitempty" firestore:"product,omitempty"`
}

SharedProjectCreateReceipt is immutable, private command evidence. It is not a project index, a module-enablement record, or a billing entitlement.

func NewSharedProjectCreateReceiptRecord added in v0.10.0

func NewSharedProjectCreateReceiptRecord(spaceID, commandID string) (record.Record, *SharedProjectCreateReceipt)

func (SharedProjectCreateReceipt) Validate added in v0.10.0

func (r SharedProjectCreateReceipt) Validate() error

type SharedProjectRef added in v0.10.0

type SharedProjectRef struct {
	StoreID   string `json:"storeId"`
	SpaceID   string `json:"spaceID"`
	ProjectID string `json:"projectId"`
}

SharedProjectRef preserves the distinction between a Space-owned project and the legacy private cloud root, even when their project IDs are equal.

type StoreBrief

type StoreBrief struct {
	Title    string                   `json:"title" firestore:"title"`
	Type     string                   `json:"type" firestore:"type"`
	URL      string                   `json:"url,omitempty" firestore:"url,omitempty"`
	Projects map[string]*ProjectBrief `json:"projects,omitempty" firestore:"projects,omitempty"`
}

StoreBrief is a brief of one store in a user's DataTug index.

type UserExt

type UserExt struct {
	Stores map[string]*StoreBrief `json:"stores,omitempty" firestore:"stores,omitempty"`
}

UserExt is the DataTug extension data of one user: the index of the DataTug stores the user can see, and the project briefs inside each of them. It is the data of the users/{userID}/ext/datatug record.

func NewUserExtRecord

func NewUserExtRecord(userID, extID string) (record.Record, *UserExt)

NewUserExtRecord wraps a fresh UserExt in its dalgo record, returning both the record and the DBO.

Jump to

Keyboard shortcuts

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