Skip to content

feat(infra): migrate Postgres to Neon and object storage to Cloudflare R2 - #22

Merged
AlaskanTuna merged 1 commit into
mainfrom
feat/neon-r2-migration
Jul 30, 2026
Merged

feat(infra): migrate Postgres to Neon and object storage to Cloudflare R2#22
AlaskanTuna merged 1 commit into
mainfrom
feat/neon-r2-migration

Conversation

@AlaskanTuna

@AlaskanTuna AlaskanTuna commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • Points Prisma at Neon Postgres (pooled DATABASE_URL for the app, unpooled DIRECT_URL for Prisma Migrate), replacing the paused Supabase project.
  • Reimplements storageService.ts's three exported functions against Cloudflare R2, preserving signatures and object keys byte-for-byte so no caller (overlayService, fluxRecomputeService, geoTiffService, locationService, projectService, locationPipeline/store) needed changes.
  • Bucket is private (confirmed: no public dev URL, no custom domain); reads stay behind signed URLs with the existing 3600s default.

Test plan

  • pnpm typecheck — exit 0 across shared/backend/frontend/pdf-service
  • pnpm test — 211 frontend + 124 backend passing (7 new storage contract tests)
  • eslint . --max-warnings 68 / prettier --check . — both clean
  • prisma migrate status against Neon — up to date, 6/6 migrations
  • Live boot: GET /api/health ok, a real Location row + Project count read through Prisma
  • Live R2: downloaded a real GeoTIFF (224,671 bytes), fetched a real signed rgbImageUrl (200, image/png), full upload→download round trip, cleaned up after
  • Core cost constraint: real panel recompute against Neon+R2 returned 12 monthly kWh values with a fetch interceptor confirming zero calls to solar.googleapis.com
  • Neon scale-to-zero: after 11 idle minutes, first request returned HTTP_200 in 2.17s with no user-visible error

Closes #4, closes #5

Summary by CodeRabbit

  • Infrastructure

    • Migrated database connectivity to Neon PostgreSQL.
    • Migrated private asset storage to Cloudflare R2.
    • Added support for secure, time-limited asset download links.
  • Documentation

    • Updated setup and deployment instructions with the new database and storage configuration requirements.
    • Clarified that Supabase is used for authentication and API access only.
  • Tests

    • Added coverage for file uploads, downloads, signed links, and storage error handling.

…e R2

Supabase's paused free-tier project can no longer serve as database or
storage backend. Points Prisma at Neon (pooled + direct connection
strings) and reimplements storageService.ts against R2, preserving
object keys and function signatures so no caller changes. Both verified
live: real DB reads, a real GeoTIFF round-trip, and a panel recompute
with zero calls to solar.googleapis.com.

Closes #4, #5
@AlaskanTuna
AlaskanTuna merged commit 4205cd7 into main Jul 30, 2026
1 of 2 checks passed
@AlaskanTuna
AlaskanTuna deleted the feat/neon-r2-migration branch July 30, 2026 06:22
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1d1e9895-1dc7-43be-94e8-85ac5d2518ba

📥 Commits

Reviewing files that changed from the base of the PR and between cc79ab9 and 10aa251.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • .env.example
  • RUNBOOK.md
  • backend/package.json
  • backend/src/config/env.ts
  • backend/src/config/r2.ts
  • backend/src/services/__tests__/storageService.test.ts
  • backend/src/services/storageService.ts
  • prisma/schema.prisma

📝 Walkthrough

Walkthrough

The backend now uses Neon for PostgreSQL and Cloudflare R2 for object storage. Environment validation, Prisma configuration, deployment documentation, R2 client setup, storage operations, signed URLs, and storage tests were updated accordingly.

Changes

Neon and Cloudflare R2 migration

Layer / File(s) Summary
Neon database and environment contracts
.env.example, backend/src/config/env.ts, prisma/schema.prisma, RUNBOOK.md
Replaces SUPABASE_DATABASE_URL with pooled and direct Neon URLs, adds required R2 variables, and updates deployment and environment documentation.
R2 client setup
backend/package.json, backend/src/config/r2.ts
Adds AWS S3 SDK packages and exports an R2-configured S3Client.
Storage operations and validation
backend/src/services/storageService.ts, backend/src/services/__tests__/storageService.test.ts
Migrates uploads, downloads, and signed URLs to R2 commands and adds coverage for request parameters, default expiration, and error handling.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant storageService
  participant r2
  participant CloudflareR2
  storageService->>r2: Send PutObjectCommand, GetObjectCommand, or presign GetObjectCommand
  r2->>CloudflareR2: Execute object operation
  CloudflareR2-->>r2: Return operation result or object body
  r2-->>storageService: Return result, ArrayBuffer, or signed URL
Loading
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/neon-r2-migration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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.

Migrate cached GeoTIFF and imagery storage to Cloudflare R2 Migrate Postgres from Supabase to Neon

1 participant