Client-facing surface: self-serve funding and work submission #41
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Outcome
A client can fund an account and submit work without the operator running
curl for them. Today every route is operator/admin behind a shared
SAAS_API_KEY-- verified onmain. There is no signup, no per-clientcredential, no checkout initiation, and no client-visible status. That means the
service cannot have a second user.
Dependency
Dependency satisfied: app assembly #38 merged via PR #43. Verified current main contains
gitea_saas/app.py:create_app.Scope
SAAS_API_KEYis a single shared operatorsecret. Add per-client keys: hashed at rest (never stored plaintext), scoped so
a client can only read and act on its own client_id. Issued on provision,
revocable.
POST /api/checkoutreturns a Stripe Checkout URL for a top-up.The existing webhook already credits idempotently (#3) -- reuse it, do not
write a second credit path.
GET /api/me-- balance, queued items, in-flight items,delivered count. Scoped to the caller's client_id.
Security notes -- this is the first genuinely externally-reachable surface
client key gets 403 on
/api/clientsand on another client's/api/factory/*./api/checkoutper client.Files this issue owns
gitea_saas/client_api.py(new),gitea_saas/auth.py(extend -- do not fork),gitea_saas/schema.sql,tests/test_client_api.py(new).Acceptance
Stripe seam, and a replayed webhook credits exactly once.
Integration clarification (Vale)
Also allow
gitea_saas/app.pyandtests/test_app_assembly.pysolely to mount the client routes and verify they are reachable through the real assembled app. Existing operator before-request guards must not make scoped client endpoints unreachable. Add a real assembled-app test for the authenticated client path and the operator/cross-tenant denial cases. Never expose operator secrets to clients. All other files remain forbidden. Required verification:python -m pytest -q; use mock Stripe/Gitea, no real charges.[owner-decision] Euro requested execution of the income methods. Dependency verified on current main: PR #43 is merged and app.py/create_app plus wsgi.py exist. Removing stale dependency block; implement the scoped ticket, test, and open one PR. No public launch, real payments, or production ledger changes under this ticket without separate approval.