Documentation
¶
Overview ¶
Package team is the library-first service layer for the multi-user ("team/family") system of record: users, roles, the allowlist, and — in later phases — chats and authentication.
Authorization is enforced twice by design: the service checks the acting user before issuing queries (clear errors), and row-level security in PostgreSQL backstops every query regardless (defense in depth). Never infer authorization from ent errors alone: an RLS-filtered UPDATE can surface as a not-found rather than a denial.
Index ¶
- Variables
- type Actor
- type Config
- type Service
- func (s *Service) AgentHandle() string
- func (s *Service) AllowlistAdd(ctx context.Context, actor Actor, email, note string) (*ent.AllowlistEntry, error)
- func (s *Service) AllowlistList(ctx context.Context, actor Actor) ([]*ent.AllowlistEntry, error)
- func (s *Service) AllowlistRemove(ctx context.Context, actor Actor, email string) error
- func (s *Service) EnsureUser(ctx context.Context, email string) (u *ent.User, created bool, err error)
- func (s *Service) GetSelf(ctx context.Context, actor Actor) (*ent.User, error)
- func (s *Service) IsEmailAllowed(ctx context.Context, email string) (bool, error)
- func (s *Service) ListIdentities(ctx context.Context, actor Actor, userIDs []uuid.UUID) (map[uuid.UUID][]string, error)
- func (s *Service) ListUsers(ctx context.Context, actor Actor) ([]*ent.User, error)
- func (s *Service) RenameUser(ctx context.Context, actor Actor, userID uuid.UUID, username string) error
- func (s *Service) SetDisplayName(ctx context.Context, actor Actor, userID uuid.UUID, name string) error
- func (s *Service) SetUserStatus(ctx context.Context, actor Actor, userID uuid.UUID, status entuser.Status) error
Constants ¶
This section is empty.
Variables ¶
var ( // ErrForbidden is returned when the actor lacks permission. ErrForbidden = errors.New("forbidden") // ErrInvalidUsername is returned for usernames outside the allowed form. ErrInvalidUsername = errors.New("invalid username: use 3-32 characters of a-z, 0-9, '-' or '_', starting with a letter or digit") // ErrInvalidEmail is returned for unparseable email addresses. ErrInvalidEmail = errors.New("invalid email address") // ErrNotFound is returned when the referenced entity does not exist // (or is invisible to the actor — indistinguishable by design). ErrNotFound = errors.New("not found") )
Sentinel errors returned by the service layer.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// SuperadminEmail bootstraps the superadmin: the first login by this
// email creates (or, if no superadmin exists yet, promotes) the
// superadmin user. Later config changes never demote an existing one.
SuperadminEmail string
// AgentHandle is the @-mention handle of the agent (default "omniagent").
AgentHandle string
// Logger defaults to slog.Default().
Logger *slog.Logger
}
Config configures the team service.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service exposes team operations over the RLS-scoped store.
func NewService ¶
NewService creates the team service.
func (*Service) AgentHandle ¶
AgentHandle returns the agent's @-mention handle.
func (*Service) AllowlistAdd ¶
func (s *Service) AllowlistAdd(ctx context.Context, actor Actor, email, note string) (*ent.AllowlistEntry, error)
AllowlistAdd approves an email for login. Superadmin only.
func (*Service) AllowlistList ¶
AllowlistList returns all allowlisted emails. Superadmin only.
func (*Service) AllowlistRemove ¶
AllowlistRemove revokes an email's approval. Superadmin only. Removing an email does not delete an existing user; disable the user for that.
func (*Service) EnsureUser ¶
func (s *Service) EnsureUser(ctx context.Context, email string) (u *ent.User, created bool, err error)
EnsureUser returns the user for a verified email, creating it on first login. Superadmin bootstrap happens here:
- A newly created user whose email matches the configured superadmin email gets the superadmin role.
- An existing member with that email is promoted only when no superadmin exists yet (config set after their first login).
- Changing the configured email later never demotes an existing superadmin — demotion is an explicit administrative act, not a config side effect.
The caller (auth layer) must have verified both the email and its allowlist status; EnsureUser does not re-check the allowlist.
func (*Service) IsEmailAllowed ¶
IsEmailAllowed reports whether an email may log in: it is allowlisted or is the configured superadmin email. Runs in the system context — it is consulted by the auth layer before any user exists.
func (*Service) ListIdentities ¶ added in v0.17.0
func (s *Service) ListIdentities(ctx context.Context, actor Actor, userIDs []uuid.UUID) (map[uuid.UUID][]string, error)
ListIdentities returns each given user's linked sign-in provider names ("magic_link", "google", "github"), keyed by user ID. Superadmin only; used by the admin members view (RMI-OMNIAGENT-122).
func (*Service) RenameUser ¶
func (s *Service) RenameUser(ctx context.Context, actor Actor, userID uuid.UUID, username string) error
RenameUser changes a user's username. Members may rename themselves; the superadmin may rename anyone (US-3 covers renaming themselves).
Directories
¶
| Path | Synopsis |
|---|---|
|
Package agentruntime provides per-agent runtime instances for team mode (RMI-OMNIAGENT-309).
|
Package agentruntime provides per-agent runtime instances for team mode (RMI-OMNIAGENT-309). |
|
Package agents is the virtual-agents service layer (INIT-OMNIAGENT-005): a persisted agent = a persona/model bound to an enabled subset of the deployment's skills, its per-agent owner/maintainer roles, an authorization matrix (Can), and a private/listed + featured registry.
|
Package agents is the virtual-agents service layer (INIT-OMNIAGENT-005): a persisted agent = a persona/model bound to an enabled subset of the deployment's skills, its per-agent owner/maintainer roles, an authorization matrix (Can), and a private/listed + featured registry. |
|
Package auth implements passwordless, allowlist-closed authentication for team mode: magic-link issuance/verification and server-side cookie sessions.
|
Package auth implements passwordless, allowlist-closed authentication for team mode: magic-link issuance/verification and server-side cookie sessions. |
|
Package chats is the chat/membership/message service layer: private (DM) and group chats, membership, message persistence, and the agent turn.
|
Package chats is the chat/membership/message service layer: private (DM) and group chats, membership, message persistence, and the agent turn. |
|
Package ent holds the generated Ent client for the team system of record.
|
Package ent holds the generated Ent client for the team system of record. |
|
schema
Package schema defines the Ent schemas for the team (multi-user) system of record.
|
Package schema defines the Ent schemas for the team (multi-user) system of record. |
|
Package mail delivers team emails (magic-link logins).
|
Package mail delivers team emails (magic-link logins). |
|
Package secrets provides the team-mode secret store: an OmniVault-backed, multi-tenant vault whose per-agent namespaces let a runtime instance (RMI-OMNIAGENT-310) load only its own agent's secrets.
|
Package secrets provides the team-mode secret store: an OmniVault-backed, multi-tenant vault whose per-agent namespaces let a runtime instance (RMI-OMNIAGENT-310) load only its own agent's secrets. |
|
Package store opens the team database and scopes every query to the authenticated user.
|
Package store opens the team database and scopes every query to the authenticated user. |