Skip to content

Add pm-backend deliverable: FastAPI app with provider-neutral billing + sandbox integration tests - #174

Merged
fig-ai-agent[bot] merged 1 commit into
mainfrom
fig/pm-backend
Sep 10, 2026
Merged

Add pm-backend deliverable: FastAPI app with provider-neutral billing + sandbox integration tests#174
fig-ai-agent[bot] merged 1 commit into
mainfrom
fig/pm-backend

Conversation

@fig-ai-agent

@fig-ai-agent fig-ai-agent Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds deliverables/pm-backend/ — a self-contained Program Management Backend, a single integrated FastAPI application with four equal-weight modules.

Module Purpose Route prefix
Program Management CSV Generate / validate program-management CSV templates /api/csv
Billing interoperability Provider-neutral billing (stub, Stripe, Chargebee, Paddle) /api/billing
Tool switcher Switch the active tool at runtime /api/tool
Encryption at rest Opt-in Fernet column encryption /api/programs

Highlights

  • Provider-neutral billing behind one BillingProvider interface with four adapters. Swapping providers is a single env var (BILLING_PROVIDER) — no code changes elsewhere.
  • Uniform error contract: ProviderAuthError → 401, ProviderNotFoundError → 404, ProviderError → 502.
  • Adapters lazy-import their SDKs (stripe, requests), so an unused provider adds no hard dependency.
  • Opt-in encryption at rest via ENCRYPT_AT_REST=true — plain String column by default, Fernet-encrypted TypeDecorator when enabled. cryptography is never imported when disabled.
  • Tool switcher persists its selection across restarts.

Tests

58 passed, 15 skipped
  • 43 unit tests (API surface, each adapter vs a mocked SDK/HTTP layer, encryption subprocess check).
  • 12 guard tests proving live credentials are refused (no network).
  • 15 sandbox integration tests, opt-in via pytest --run-integration — they hit the real Stripe test API, Paddle sandbox, and Chargebee test site. Skipped by default; create-then-delete on teardown.

Safety guards in conftest.py refuse to run against production credentials — a sk_live_* key, a non-sandbox Paddle host, or a Chargebee site without a -test suffix fails fast rather than touching a real account.

Pyflakes clean.

Notes

  • Placed under deliverables/ per repo convention, with an index row added to deliverables/README.md.
  • .gitignore excludes runtime-generated files (pm_backend.db, tool_state.json).
  • No .github/workflows/ changes in this PR.

requests.post(
f"{base}/customers/{cid}/delete", headers=headers, timeout=15
)
except requests.RequestException:
for cid in created:
try:
requests.delete(f"{base}/customers/{cid}", headers=headers, timeout=15)
except requests.RequestException:
for cid in created:
try:
stripe.Customer.delete(cid)
except Exception:
)

_DEFAULT_BASE = "https://api.paddle.com"
_SANDBOX_BASE = "https://sandbox-api.paddle.com"

name: str

def create_customer(self, email: str, name: str = "") -> Customer: ...
name: str

def create_customer(self, email: str, name: str = "") -> Customer: ...
def get_customer(self, customer_id: str) -> Customer: ...
def create_invoice(
self, customer_id: str, amount: int, currency: str = "usd",
description: str = "",
) -> Invoice: ...
) -> Invoice: ...
def charge(
self, customer_id: str, amount: int, currency: str = "usd",
) -> PaymentIntent: ...
def charge(
self, customer_id: str, amount: int, currency: str = "usd",
) -> PaymentIntent: ...
def health(self) -> dict: ...


@pytest.fixture
def stripe_test_key():
@fig-ai-agent
fig-ai-agent Bot merged commit 8e5784a into main Sep 10, 2026
5 of 10 checks passed
@fig-ai-agent
fig-ai-agent Bot deleted the fig/pm-backend branch September 10, 2026 11:28
fig-ai-agent Bot added a commit that referenced this pull request Sep 10, 2026
Co-authored-by: Fig Agent <agent@fig.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants