Skip to content

feat: Stripe invoice PDF delivery, Vercel build cache invalidation, multi-provider OAuth#701

Merged
temma02 merged 2 commits into
StellerCraft:mainfrom
topsonDev:feat/stripe-invoice-pdf-vercel-cache-multi-provider-oauth
May 30, 2026
Merged

feat: Stripe invoice PDF delivery, Vercel build cache invalidation, multi-provider OAuth#701
temma02 merged 2 commits into
StellerCraft:mainfrom
topsonDev:feat/stripe-invoice-pdf-vercel-cache-multi-provider-oauth

Conversation

@topsonDev
Copy link
Copy Markdown
Contributor

Summary

Implements three features in a single PR.


#659 — Stripe invoice PDF generation and email delivery

New file: apps/backend/src/services/invoice-delivery.service.ts
Modified: apps/backend/src/services/payment.service.ts

  • InvoiceDeliveryService retrieves the Stripe-hosted invoice PDF URL and emails it to the customer on every successful subscription renewal.
  • Hooked into the invoice.payment_succeeded webhook event in PaymentService.handleWebhook. Delivery failures are caught and logged — they do not fail the webhook so Stripe does not retry unnecessarily.
  • Email sending is provider-agnostic: configure EMAIL_API_URL, EMAIL_API_KEY, and EMAIL_FROM. Falls back to console.log when EMAIL_API_URL is unset (dev/test mode).
  • Transient email failures are retried with exponential back-off via the existing retryWithBackoff utility.

#660 — Vercel build cache invalidation strategy

New file: apps/backend/src/services/build-cache.service.ts
Modified: apps/backend/src/services/deployment-pipeline.service.ts

  • BuildCacheService.computeContentHash produces a deterministic SHA-256 hash over all generated files (sorted by path, order-independent).
  • checkCache compares the new hash against the value stored in deployments.customization_config._buildCacheHash and returns hit or miss.
  • Integrated into DeploymentPipelineService after syntax validation: cache status (hit/miss + hash prefix) is written to deployment logs.
  • storeHash persists the hash after a successful build so future runs can detect unchanged code without triggering a redundant Vercel deployment.

#661 — Multi-provider OAuth token exchange

New file: apps/backend/src/services/multi-provider-auth.service.ts
New migration: supabase/migrations/012_multi_provider_oauth.sql
Modified: apps/backend/src/lib/supabase/database.types.ts

  • MultiProviderAuthService coordinates GitHub and Stellar wallet auth under a single platform identity (Supabase user ID).
  • Token isolation: GitHub tokens are encrypted with AES-256-GCM (existing encryptToken/decryptToken) before storage in the existing github_token_encrypted column. Stellar stores only the wallet public key in the new provider_connections JSONB column — no private key is ever held by the platform.
  • Handles partial connection states (GitHub only, Stellar only, both, neither).
  • Migration 012 adds provider_connections JSONB to profiles; database.types.ts updated accordingly.

Tests

27 tests added across 3 new test files — all passing:

File Tests
invoice-delivery.service.test.ts 6
build-cache.service.test.ts 8
multi-provider-auth.service.test.ts 13

Closes #659
Closes #660
Closes #661

…ulti-provider OAuth

StellerCraft#659 — Stripe invoice PDF generation and email delivery
- Add InvoiceDeliveryService that retrieves the hosted invoice PDF URL from
  Stripe and emails it to the customer on subscription renewal
- Hook into the invoice.payment_succeeded webhook event in PaymentService;
  delivery failures are logged but do not fail the webhook (best-effort)
- Email sending uses a configurable provider (EMAIL_API_URL/EMAIL_API_KEY/
  EMAIL_FROM env vars); falls back to console logging in dev/test
- Retry transient email failures with exponential back-off via retryWithBackoff
- Tests: invoice PDF retrieval, email delivery, email-from-expanded-customer,
  missing PDF URL, missing email, retry wrapper invoked, dev-mode logging

StellerCraft#660 — Vercel build cache invalidation strategy for template code generation
- Add BuildCacheService that computes a deterministic SHA-256 content hash
  over all generated files (sorted by path for order-independence)
- Integrate cache check into DeploymentPipelineService after syntax validation:
  logs cache hit/miss with the content hash prefix
- Store the hash in deployments.customization_config._buildCacheHash after a
  successful build so future runs can detect unchanged code (cache hit)
- Tests: deterministic hash, order-independence, content-change detection,
  file-addition detection, cache hit/miss logic, hash persistence

StellerCraft#661 — Multi-provider OAuth token exchange for GitHub and Stellar wallet
- Add MultiProviderAuthService coordinating GitHub and Stellar wallet auth
  under a single platform identity (Supabase user ID)
- GitHub tokens are encrypted with AES-256-GCM (existing token-encryption lib)
  before storage; Stellar stores only the wallet public key — no private key
  is ever held by the platform
- Provider tokens are isolated: GitHub uses existing profile columns;
  Stellar uses a new provider_connections JSONB column
- Handles partial connection (one provider connected, not the other)
- Add migration 012_multi_provider_oauth.sql adding provider_connections JSONB
  column to profiles; update database.types.ts accordingly
- Tests: GitHub token encryption on connect, expiry storage, Stellar public-key-
  only storage, existing connections preserved, disconnect clears correct fields,
  partial connection status, token decryption, public key retrieval

Closes StellerCraft#659
Closes StellerCraft#660
Closes StellerCraft#661
@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented May 30, 2026

@topsonDev Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@temma02 temma02 merged commit 7681d83 into StellerCraft:main May 30, 2026
0 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants