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]>
This commit is contained in:
co-authored by
Claude Fable 5
parent
67b80da695
commit
f3f08a8edd
@@ -159,6 +159,25 @@ impl Default for SandboxConfig {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Deserialize)]
|
||||
pub struct BillingConfig {
|
||||
/// Stripe secret key (sk_*); enables Buy-credits when set.
|
||||
pub stripe_secret_key: Option<String>,
|
||||
/// Price id (price_*) of the credit pack sold at checkout.
|
||||
pub stripe_price_id: Option<String>,
|
||||
/// Webhook signing secret (whsec_*) for verifying Stripe callbacks.
|
||||
pub stripe_webhook_secret: Option<String>,
|
||||
/// Credits granted per completed checkout (one pack).
|
||||
#[serde(default = "default_pack_credits")]
|
||||
pub credits_per_pack: i64,
|
||||
/// Public base URL for the checkout success/cancel return.
|
||||
pub return_base: Option<String>,
|
||||
}
|
||||
|
||||
fn default_pack_credits() -> i64 {
|
||||
1000
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Deserialize)]
|
||||
pub struct TelemetryConfig {
|
||||
/// OTLP/HTTP collector base (e.g. http://otel-collector:4318).
|
||||
@@ -195,6 +214,8 @@ pub struct AppConfig {
|
||||
pub sandbox: SandboxConfig,
|
||||
#[serde(default)]
|
||||
pub telemetry: TelemetryConfig,
|
||||
#[serde(default)]
|
||||
pub billing: BillingConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
|
||||
Reference in New Issue
Block a user