Documentation
¶
Overview ¶
Package captable folds hanzoai/captable into the unified hanzoai/cloud binary as an in-process subsystem (HIP-0106) — the PILOT of epic #96 (fold the Captable,Inc app into cloud, drop Next.js/Prisma/Postgres). Cloud serves the cap-table surface (/v1/captable/*) ITSELF, per tenant, on Base/SQLite.
WRAP, DON'T REWRITE — the read-WRITE variant. Where clients/plan + clients/ pricing host a read-only @hanzo catalog in goja, captable hosts the tRPC business LOGIC (ported to a self-contained goja bundle in github.com/hanzoai/ captable) and gives it PERSISTENCE over per-tenant Base/SQLite. The bundle carries logic; the Go host carries storage. The seam between them is the REUSABLE clients/goja binding (the RW-Base goja host), which esign (#100) and dataroom (#101) reuse unchanged — this leaf is just:
captable bundle (github.com/hanzoai/captable.Bundle) + the per-tenant Schema
│
clients/goja.NewBase(...) ← injects __db/__newId/__now,
│ one SQLite file per tenant,
/v1/captable/* zip routes one transaction per request
No Prisma, no Postgres, no Next.js in this path. Every route resolves the org from the VALIDATED cloud principal (principal.Org), never a client header, and that org selects the tenant's DB file AND scopes every row.
ACTIVATION: captable is NOT staged — it mounts under the mount-all default (empty CLOUD_ENABLE), so the one binary serves /v1/captable/* from first boot. There is no standalone Captable,Inc pod to defer to (the Next.js/Prisma/Postgres app is retired by this fold — no such deployment runs in the fleet), so cloud's fresh per-tenant Base/SQLite is authoritative from the first write, with no data to migrate.
Index ¶
- Variables
- func AddStakeholders(ctx context.Context, org string, holders []StakeholderInput) (int, error)
- func EnsureShareClass(ctx context.Context, org string, in ShareClassInput) (string, error)
- func IssueShares(ctx context.Context, org string, in ShareInput) error
- func Mount(app cloud.Router, deps cloud.Deps) error
- func RecordRound(ctx context.Context, org string, in RoundInput) (string, error)
- func SetIncorporation(ctx context.Context, org, companyName, incType, country, state string) error
- func Shutdown(context.Context) error
- func StakeholderIDsByEmail(ctx context.Context, org string) (map[string]string, error)
- type RoundInput
- type ShareClassInput
- type ShareInput
- type StakeholderInput
Constants ¶
This section is empty.
Variables ¶
var ErrNotMounted = errors.New("captable: subsystem not mounted")
ErrNotMounted is returned when captable has not been mounted. A caller treats it as "cap table unavailable".
Functions ¶
func AddStakeholders ¶ added in v1.800.1
AddStakeholders adds one or more stakeholders (dedup by email in the bundle) and returns how many rows were inserted.
func EnsureShareClass ¶ added in v1.800.1
EnsureShareClass creates a share class and returns its id (resolved via the list route, since shareClasses.create does not echo the id). If a class with the same name already exists it returns that existing id (idempotent seed).
func IssueShares ¶ added in v1.800.1
func IssueShares(ctx context.Context, org string, in ShareInput) error
IssueShares issues a share certificate to a stakeholder.
func Mount ¶
Mount wires the /v1/captable/* surface onto app per HIP-0106. Constructs the value directly (cloud.NewBase) — this subsystem keeps a package global for the Shutdown hook and opens a per-tenant goja host from deps.DataDir.
func RecordRound ¶ added in v1.800.1
RecordRound records a fundraising round and returns its id.
func SetIncorporation ¶ added in v1.800.1
SetIncorporation records the entity kind on the tenant's canonical company row — the cap-table-layer "org is now a company" fact. companyName is required by the bundle's company.update contract.
Types ¶
type RoundInput ¶ added in v1.800.1
type RoundInput struct {
Name string `json:"name"`
RoundType string `json:"roundType"` // PRICED | SAFE | CONVERTIBLE_NOTE
TargetAmount float64 `json:"targetAmount"`
PreMoneyValuation float64 `json:"preMoneyValuation,omitempty"`
}
RoundInput mirrors the rounds.create bundle contract.
type ShareClassInput ¶ added in v1.800.1
type ShareClassInput struct {
}
ShareClassInput mirrors the shareClasses.create bundle contract.
type ShareInput ¶ added in v1.800.1
type ShareInput struct {
}
ShareInput mirrors the shares.add bundle contract.
type StakeholderInput ¶ added in v1.800.1
type StakeholderInput struct {
Name string `json:"name"`
Email string `json:"email"`
StakeholderType string `json:"stakeholderType"` // INDIVIDUAL | INSTITUTION
CurrentRelationship string `json:"currentRelationship"` // FOUNDER | INVESTOR | EMPLOYEE …
InstitutionName string `json:"institutionName,omitempty"`
}
StakeholderInput mirrors the stakeholders.add bundle contract.