Deploy on DigitalOcean App Platform (GitHub-source build) + consolidate audit-fixes

Deploy config:
- .do/app.yaml: build the Dockerfile directly from GitHub (deploy_on_push) instead
  of a pre-built DOCR image; NEXT_PUBLIC_* set RUN_AND_BUILD_TIME with the
  propertymanagement.network domain so they bake into the client bundle; add
  custom domains block (apex + www); wire Sentry DSN (server + browser).

Included pending work from the audit-fixes branch:
- AI provider abstraction (OpenAI/Anthropic, admin-selectable; Anthropic default)
- Per-landlord e-signature (DocuSign OAuth + Dropbox Sign) + migration 0010
- Outbound webhooks / Zapier integration
- PayPal removal (Stripe-only billing)
- Storage hardening (fail-loud when Spaces unconfigured), security fixes

Verified: full production Docker build (same build-args as DO) passes clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Leon Serfaty
2026-07-03 04:45:24 -04:00
co-authored by Claude Opus 4.8
parent 917a06ee85
commit 5495b94924
86 changed files with 7647 additions and 1182 deletions
+26
View File
@@ -631,6 +631,32 @@ export const signature_requests = pgTable("signature_requests", {
updated_at: updatedAt(),
})
// ============================================================
// E-SIGN CONNECTIONS (per-landlord DocuSign OAuth / Dropbox Sign API key)
// ============================================================
// One row per (owner, provider). Each landlord connects THEIR OWN e-signature
// account, so leases are sent from their brand with their audit trail. DocuSign
// uses OAuth (access + refresh tokens); Dropbox Sign uses an API key stored in
// `access_token`. All secrets are AES-256-GCM encrypted (see lib/crypto.ts).
export const esign_connections = pgTable("esign_connections", {
id: uuid("id").primaryKey().defaultRandom(),
user_id: text("user_id")
.notNull()
.references(() => profiles.id, { onDelete: "cascade" }),
provider: text("provider").$type<"docusign" | "dropbox_sign">().notNull(),
access_token: text("access_token").notNull(), // encrypted (DocuSign access token / Dropbox Sign API key)
refresh_token: text("refresh_token"), // encrypted (DocuSign only)
expires_at: tstz("expires_at"),
// DocuSign account id + base uri from /oauth/userinfo (null for Dropbox Sign).
account_id: text("account_id"),
base_uri: text("base_uri"),
account_name: text("account_name"),
status: text("status").$type<"active" | "error" | "revoked">().notNull().default("active"),
last_error: text("last_error"),
created_at: createdAt(),
updated_at: updatedAt(),
})
// ============================================================
// WEBHOOK ENDPOINTS (outbound webhooks / Zapier integration)
// ============================================================