Documentation
¶
Overview ¶
Package team is your org's shared workspace: documents edited together, files, seats, and agents as teammates.
It is Hanzo Team: IAM sign-in and workspace selection, the transactor WebSocket a workspace's documents ride, collaborative editing on /collaborator, per-workspace files, the wallet page with its plan + seats, and the org's agents projected in as bot members.
The published surface is the typed ops themselves (plugin/team/openapi.json) — there is no second route table here to drift out of date.
TENANT ISOLATION. The org (tenant key) is NEVER a client-supplied header on any data path:
- transactor: org = the `extra.org` claim of the HS256 workspace token in the :token path segment, minted by selectWorkspace and VERIFIED (token.Decode verify=true) against SERVER_SECRET before the WebSocket upgrade. Every docs SQLite file lives at {DataDir}/team/workspaces/orgs/<org>/projects/<ws>/docs.db.
- account RPC: org = the `extra.org` claim of the HS256 session token in the bearer/cookie, likewise VERIFIED. Every account-store query filters by org; selectWorkspace resolves the workspace scoped to (org, slug) so a foreign tenant's slug is unresolvable.
- bots read routes: org = principal.Org(c) — the value the identity middleware minted from the VALIDATED IAM owner claim (HIP-0026) — and never a client X-Org-Id.
The session-token org is itself minted from the VERIFIED IAM `owner` claim at the OAuth callback, so the chain IAM owner → session token → workspace token → docs path is signed end-to-end and a client can forge none of it.
Order 138: binds /v1/team/* before the AI subsystem's /v1/* catch-all (150).
Index ¶
- Variables
- func Apply(org, workspace, account string, txes ...map[string]any)
- func Encode(e Envelope) []byte
- func MemberTxes(m Member, exists bool) []map[string]any
- func Mount(app cloud.Router, deps cloud.Deps) error
- func PersonRef(userID string) string
- func Shutdown() error
- type AgentRunner
- type Bot
- type BotLister
- type Envelope
- type Kind
- type LoginInfo
- type Member
- type ProviderInfo
- type RegionInfo
- type Role
- type SocialID
- type Status
- type WorkspaceInfo
- type WorkspaceLoginInfo
Constants ¶
This section is empty.
Variables ¶
var ErrInvalid = errors.New("zap: invalid frame")
ErrInvalid is returned for a malformed ZAP frame.
Functions ¶
func Apply ¶
Apply ingests platform CUD txes into a workspace's store exactly as a live client would (same applyTx path, same triggers) and broadcasts the applied txes to every open session of that workspace (realtime). account is the attribution used for triggers/PersonSpace ownership. No-op until Mount runs.
func MemberTxes ¶
MemberTxes builds the txes to project a member. When the Person already EXISTS it only UPDATES the mirror-owned name + refreshes the Employee mixin (which merges, never replaces) — so avatar/city/birthday/profile and any SPA-set mixin survive. On first projection it creates the Person + the hanzo social identity. The Employee mixin (active) is what puts the member in the Team list and fires the PersonSpace trigger.
func Mount ¶
Mount wires the /v1/team/* surface onto app per HIP-0106. It opens the two SQLite stores under {DataDir}/team, wires the account API, the transactor WebSocket and the bots read routes, and publishes the transactor singleton so the in-process projection path can write into the workspace store.
The uniform /v1/team/health liveness route is provided by the compose root (serve.go registers GET /v1/<name>/health for every enabled subsystem BEFORE MountAll, HIP-0106) — the SAME contract clients/tracker, clients/crm and clients/agents rely on. Mount does NOT re-register it (a second identical route is dead — Fiber matches the first-registered — and violates one-way).
Types ¶
type AgentRunner ¶
AgentRunner runs agent `agentID` for `org` on behalf of `userSub` with `input` and returns the model's text output. It is injected in Mount (only when the feature is enabled) as an adapter over agents.RunOnBehalf — the ONE in-process run path (billed, metered, recorded) — so clients/team never speaks clients/agents' concrete run types and the responder is testable with a fake.
type Bot ¶
Bot is the minimal projection of an org agent the roster reconcile needs. It is the seam that keeps clients/team decoupled from clients/agents' concrete Agent type — team names only what it projects (id, name, active).
type BotLister ¶
BotLister sources an org's bots (the canonical in-process agents). It is injected in Mount as an adapter over agents.ListForOrg — the ONE in-process seam, replacing the removed IAM-SA HTTP enumeration. org is always a VERIFIED tenant (the transactor token's extra.org), never a client header.
type LoginInfo ¶
type LoginInfo struct {
Account string `json:"account"`
Name string `json:"name,omitempty"`
SocialID string `json:"socialId,omitempty"`
Token string `json:"token,omitempty"`
}
LoginInfo is the base login response. token overrides any prior token.
type Member ¶
type Member struct {
UserID string // account uuid (also the Person.personUuid + social key)
Name string // display name
Role string // owner/admin/member — surfaced on the Employee mixin
IsBot bool
Active bool // Employee.active — drives Team/Employee-list membership
}
Member is the projection of a team member (human or bot) rendered as a Person + Employee in the SPA directory.
type ProviderInfo ¶
type ProviderInfo struct {
// Name is the provider id, and it is the value that goes back in the URL to
// start a login: GET /v1/team/account/auth/{provider}. This deployment
// surfaces exactly one, "openid" — the hanzo.id door.
Name string `json:"name"`
// DisplayName is the human label for the sign-in button; this deployment
// sends "Hanzo". Omitted from the body when empty.
DisplayName string `json:"displayName,omitempty"`
}
ProviderInfo is one entry of GET /providers.
type RegionInfo ¶
RegionInfo is one entry of getRegionInfo.
type Role ¶
type Role = string
Role is the platform AccountRole. Stored on members.role (lowercased) and surfaced uppercased in WorkspaceLoginInfo.role.
type SocialID ¶
type SocialID struct {
ID string `json:"_id"`
Type string `json:"type"`
Value string `json:"value"`
Key string `json:"key"`
DisplayValue string `json:"displayValue,omitempty"`
VerifiedOn int64 `json:"verifiedOn,omitempty"`
IsDeleted bool `json:"isDeleted,omitempty"`
}
SocialID is one entry of getSocialIds. The workbench connect flow runs pickPrimarySocialId over these: it needs at least one non-deleted id and prefers type "hanzo".
type Status ¶
type Status struct {
Severity string `json:"severity"`
Code string `json:"code"`
Params map[string]any `json:"params"`
}
Status is the platform PlatformError payload sent as {"error": Status}. Severity is the platform's STRING enum ("OK"/"INFO"/"WARNING"/"ERROR") — the SPA compares it against those literals, so a numeric severity matches nothing.
type WorkspaceInfo ¶
type WorkspaceInfo struct {
UUID string `json:"uuid"`
Name string `json:"name"`
URL string `json:"url"`
DataID string `json:"dataId,omitempty"`
// Org is the workspace's owning IAM tenant. getUserWorkspaces unions a user's
// workspaces across every org they belong to, so the client switcher groups by
// this field (a user in two orgs sees both orgs' workspaces, each tagged).
Org string `json:"org,omitempty"`
Region string `json:"region"`
Mode string `json:"mode"`
VersionMajor int `json:"versionMajor"`
VersionMinor int `json:"versionMinor"`
VersionPatch int `json:"versionPatch"`
LastVisit int64 `json:"lastVisit,omitempty"`
IsDisabled bool `json:"isDisabled"`
CreatedOn int64 `json:"createdOn,omitempty"`
}
WorkspaceInfo is one entry of getUserWorkspaces. The version triple is the Team MODEL version (the SAME source the transactor reports as serverVersion).
type WorkspaceLoginInfo ¶
type WorkspaceLoginInfo struct {
LoginInfo
Workspace string `json:"workspace"`
WorkspaceDataID string `json:"workspaceDataId,omitempty"`
WorkspaceURL string `json:"workspaceUrl"`
Endpoint string `json:"endpoint"`
Role Role `json:"role"`
AllowGuestSignUp bool `json:"allowGuestSignUp,omitempty"`
}
WorkspaceLoginInfo extends LoginInfo — returned by selectWorkspace. token is the per-workspace JWT; endpoint is the transactor wss:// base the client connects to.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package token mints and verifies the HS256 JWTs that the team SPA, the /v1/team/account API and the /v1/team/transactor data plane all share.
|
Package token mints and verifies the HS256 JWTs that the team SPA, the /v1/team/account API and the /v1/team/transactor data plane all share. |
|
Package wallet embeds the built hanzo.team usage/wallet page — a SMALL @hanzo/ui@8 React static export (app/, Vite) — into the cloud binary, the same one-binary/one-origin precedent as the console (webui.go) and the tasks SPA (clients/tasks/ui).
|
Package wallet embeds the built hanzo.team usage/wallet page — a SMALL @hanzo/ui@8 React static export (app/, Vite) — into the cloud binary, the same one-binary/one-origin precedent as the console (webui.go) and the tasks SPA (clients/tasks/ui). |