feat(r2): add Cloudflare R2 upload tooling and env configuration #103

Merged
yuris merged 4 commits from feat/r2-upload-tooling into main 2026-10-15 01:21:37 +00:00
Owner

Summary

Implements S3-compatible Cloudflare R2 upload tooling for PMTiles and raster terrain archives, and documents environment variables.

Closes #101

Principles applied

  • principle-boundary-discipline: Isolated cloud storage upload mechanics to standalone build scripts (scripts/upload-tiles-r2.mjs) without polluting application runtime code.
  • principle-test-behavior-not-implementation: Unit tests assert credential validation, MIME type resolution, and header generation.
  • ponytail-review: Utilizes standard S3-compatible PutObjectCommand via @aws-sdk/client-s3 without custom wrapper bloat.

Impact

  • For the consumer: Vector tiles and terrain rasters can be deployed directly to Cloudflare Anycast edge storage with zero egress fees and fast byte-range delivery.
  • For the maintainer: Clear .env.example reference and automated tile upload command (pnpm run tiles:upload).

Anti-Overengineering Audit (ponytail-review)

  • No bespoke tools or in-house crates added when standard upstream libraries exist.
  • No cosmetic compliance (e.g. importing a library just to call an unused helper or info command).
  • Code subtraction evaluated: unnecessary wrappers or files were deleted rather than preserved.

Verification proof

  • pnpm exec vp check: Passed cleanly with zero formatting or lint errors.
  • pnpm test: All unit tests passed including upload-tiles-r2.test.ts.
  • pnpm build: Next.js Turbopack production build succeeded cleanly.
## Summary Implements S3-compatible Cloudflare R2 upload tooling for PMTiles and raster terrain archives, and documents environment variables. Closes #101 ### Principles applied - `principle-boundary-discipline`: Isolated cloud storage upload mechanics to standalone build scripts (`scripts/upload-tiles-r2.mjs`) without polluting application runtime code. - `principle-test-behavior-not-implementation`: Unit tests assert credential validation, MIME type resolution, and header generation. - `ponytail-review`: Utilizes standard S3-compatible PutObjectCommand via `@aws-sdk/client-s3` without custom wrapper bloat. ### Impact - **For the consumer:** Vector tiles and terrain rasters can be deployed directly to Cloudflare Anycast edge storage with zero egress fees and fast byte-range delivery. - **For the maintainer:** Clear `.env.example` reference and automated tile upload command (`pnpm run tiles:upload`). ### Anti-Overengineering Audit (ponytail-review) - [x] No bespoke tools or in-house crates added when standard upstream libraries exist. - [x] No cosmetic compliance (e.g. importing a library just to call an unused helper or info command). - [x] Code subtraction evaluated: unnecessary wrappers or files were deleted rather than preserved. ### Verification proof - `pnpm exec vp check`: Passed cleanly with zero formatting or lint errors. - `pnpm test`: All unit tests passed including `upload-tiles-r2.test.ts`. - `pnpm build`: Next.js Turbopack production build succeeded cleanly.
feat(tiles): add Cloudflare R2 upload tooling and env configuration (#101)
All checks were successful
CI / Verify Quality & Build (pull_request) Successful in 1m55s
a534de972c
- Add .env.example documenting all required Cloudflare R2 variables (R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET_NAME, NEXT_PUBLIC_CDN_URL)
- Add scripts/upload-tiles-r2.mjs with S3 PutObjectCommand to upload files from public/tiles/ to Cloudflare R2
- Configure Content-Type mapping (application/x-protobuf for PMTiles/PBF, image/png for raster tiles) and Cache-Control (public, max-age=31536000, immutable)
- Implement environment variable validation with diagnostic error reporting
- Add scripts/__tests__/upload-tiles-r2.test.ts for parameter parsing, header resolution, and env validation
- Update vitest.config.ts and package.json with scripts test inclusion and upload:tiles script
- Update .gitignore to permit .env.example tracking

Closes #101
feat(r2): replace .env.example with SecretSpec and OpenBao declarative secrets
All checks were successful
CI / Verify Quality & Build (pull_request) Successful in 1m49s
3c951fe0db
- Remove .env.example file
- Add secretspec.yaml mapping R2 and CDN credentials to OpenBao (https://bao.nokopia.com at secret/data/titik-gambut/storage)
- Update scripts/upload-tiles-r2.mjs and unit tests to guide users toward SecretSpec injection
feat(r2): add optional R2_ENDPOINT mapping in secretspec.yaml
All checks were successful
CI / Verify Quality & Build (pull_request) Successful in 1m50s
c10c814de5
feat(r2): update secretspec.yaml with uppercase fields to match OpenBao exactly
All checks were successful
CI / Verify Quality & Build (pull_request) Successful in 1m7s
55793c9110
yuris merged commit 4091328b2c into main 2026-10-15 01:21:37 +00:00
yuris deleted branch feat/r2-upload-tooling 2026-10-15 01:21:37 +00:00
Sign in to join this conversation.
No reviewers
No labels
backend
frontend
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
yuris/titik-gambut-next!103
No description provided.