Files
clawmates/crates/cm-api/Cargo.toml
T
Omar SobhandClaude Fable 5 f3f08a8edd R4 backend: team org-chart + leaderboard, Stripe credits, workspace apps
- GET /api/team/orgchart — each member grouped with the claws they manage
  (agents.managed_by); GET /api/team/leaderboard — every claw ranked by
  its real usage_events rollup (credits/tokens/runs, zeros included).
  Both tested against real Postgres.
- Stripe Buy-credits (the Slack/Clerk integration pattern): [billing]
  config (stripe keys + price + webhook secret + credits_per_pack);
  POST /api/credits/checkout opens a real Checkout Session; POST
  /api/billing/stripe verifies Stripe's t=,v1= HMAC (constant-time) and
  grants one credit lot, idempotent on the session id; GET
  /api/billing/config gates the button (honest degradation when unset).
  Offline tests: signed grant + replay no-double-grant + forged-sig 400 +
  config flag. Live checkout creation deferred to a CM_LIVE_STRIPE test.
- /apps global page support: clawId now optional on connect + directory;
  absent => workspace-wide connection (app_connections.agent_id NULL) via
  new connections::list_for_workspace.
- ApiError gains a From<sqlx::Error> so inline queries use ? cleanly.

cm-api 10 test files incl. team_tabs (2) + stripe_billing (3); clippy clean.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 19:58:09 -05:00

55 lines
1.4 KiB
TOML

[package]
name = "cm-api"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
license.workspace = true
publish.workspace = true
[dependencies]
hex = "0.4"
hmac = "0.12"
sha2 = "0.10"
async-stream = "0.3"
axum = "0.8"
futures = "0.3"
serde = { workspace = true }
serde_json = { workspace = true }
sqlx = { workspace = true }
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
cm-auth = { path = "../cm-auth" }
cm-billing = { path = "../cm-billing" }
cm-config = { path = "../cm-config" }
cm-db = { path = "../cm-db" }
cm-domain = { path = "../cm-domain" }
cm-runtime = { path = "../cm-runtime" }
cm-safety = { path = "../cm-safety" }
cm-scheduler = { path = "../cm-scheduler" }
cm-secrets = { path = "../cm-secrets" }
thiserror = { workspace = true }
tower-http = { version = "0.6", features = ["trace"] }
time = { workspace = true }
tokio = { workspace = true }
urlencoding = "2"
uuid = { workspace = true }
[dev-dependencies]
jsonwebtoken = "9"
eventsource-stream = "0.2"
reqwest = { version = "0.12", default-features = false, features = [
"json",
"rustls-tls",
"stream",
] }
cm-llm = { path = "../cm-llm" }
cm-testkit = { path = "../cm-testkit" }
hex = "0.4"
hmac = "0.12"
base64 = "0.22"
rand_core = { version = "0.6", features = ["getrandom"] }
rsa = { version = "0.9", features = ["pem"] }
sha2 = "0.10"
[lints]
workspace = true