Concepts
The Userz product model in one page. Every entity is org-scoped, there is no shared global state across organizations.
Organization
The top-level container. One billing relationship, one set of members, one set of encryption keys, one set of AI provider keys.
Members have a role: owner (everything), admin (everything except billing), or member (read-only on most resources; can submit manual actions on Feedback).
App
A product you ship feedback for. Each App has a unique publicKey (starts with pub_) the widget authenticates with, a per-App private-mode signing secret used to verify customer-issued JWTs, and a per-App processing mode:
processingMode
auto_pr: every benign submission triggers an immediate agent run.manual: submissions sit inawaiting_manualuntil a dashboard user (or chat-ops button) asks for a PR.no_pr: collect feedback only; never run the agent.
batchEnabled (windowed duplicate detection)
When true, manual-mode submissions land in batch_pending and Userz periodically clusters similar reports. The oldest member of each cluster is promoted to the lead; the rest are attached as duplicates. One PR per theme instead of one PR per report.
incrementalMergeEnabled (real-time duplicate detection)
When true, each new submission is immediately compared (Jaccard pre-filter → cosine on embeddings) against recent feedback. A match attaches it as a duplicate of the original and bumps the lead's consolidated description; no match routes it normally.
Repo
A connected source-control repository linked to one App. PRs land on a configurable branch prefix (default userz/). Two providers are supported today:
- GitHub: install the Userz GitHub App; we mint short-lived installation tokens scoped to a single repo per agent run.
- GitLab: supply a project access token (or per-project OAuth token); stored encrypted at rest, decrypted only in memory at run time. Self-hosted GitLab is supported via a per-Repo
baseUrloverride.
Feedback
One submission from the widget. Carries the report text, optional severity, viewport, user-agent, last 200 console log entries, uploaded attachments, and an optional component target.
Drives a 14-state lifecycle: received → sanitizing → sanitized → ({queued | awaiting_manual | batch_pending | archived}) → processing → ({pr_opened | pr_failed | timed_out | agent_error}), or → flagged if sanitization rejects it.
Session
A multi-item feedback capture. End-users press Ctrl+Shift+S in the widget to enter session mode, then right-click components to attach individual reports — up to 25 items, each with its own text, severity, screenshot, and target metadata. Sessions ship as a single submission and group naturally into one PR theme.
Duplicates
When Userz detects that a new submission describes the same thing as an existing one, it attaches the new report as a duplicate of the original. The original becomes the lead: it carries an LLM-consolidated description that covers every member, a short theme, the agent run, and the eventual PR. Duplicates remain queryable as full Feedback rows (screenshots, console logs, submitter info all preserved) but are hidden from the dashboard queue — opening the lead surfaces them in a "Duplicates of this report" section.
AgentRun
One execution of the AI agent. Append-only audit row recording which provider + model ran, tokens consumed, estimated cost, the resulting PR URL or rejection reason, and per-step timings. The full run log is retained for replay from the dashboard.
ReviewConversation + DiffComment
After the agent opens a PR, you can request revisions inline. Each PR has a Review conversation that the agent reads on the next iteration; per-line diff comments become part of the next run's context. The agent re-runs and commits on top of the same branch. Each plan caps the number of round-trips per PR.
ApiKey
Per-Org credential for the REST API (sk_…). The plaintext is shown exactly once at creation, we store only a salted, slow-hashed digest. Use it from your backend to query feedback, manage apps, etc.
Integration
One row per (Org, kind, external-team) where kind is slack or discord. Stores the connection's credentials, encrypted at rest. App-level routing (which channel each App's events post to) lives on the App.
Subscription
Mirror of the Org's Stripe subscription. We read this row in hot paths during agent runs and feedback intake, so a Stripe outage doesn't block customer traffic. Billing webhooks keep it in sync.
AI provider keys
Userz is bring-your-own-key across four providers — Anthropic, OpenAI, Moonshot (Kimi), and z.ai (GLM). Each Organization picks an agent model (the one that writes PRs) and a helper model (the one that sanitizes, summarizes, and builds context) independently, so you can pair an inexpensive helper with a powerful agent. Token-quota customers fall back to their own keys once the included quota is exhausted; pure-BYOK customers never touch the quota.