Skip to content

Plan open source vs paid hosted split#6

Open
adboio wants to merge 5 commits intomainfrom
claude/plan-hosted-split-011CV3KjHMSqNRUvDiMbojdX
Open

Plan open source vs paid hosted split#6
adboio wants to merge 5 commits intomainfrom
claude/plan-hosted-split-011CV3KjHMSqNRUvDiMbojdX

Conversation

@adboio
Copy link
Copy Markdown
Contributor

@adboio adboio commented Nov 12, 2025

No description provided.

Implements flexible provider pattern for dual deployment modes:
- Provider interfaces for context, billing, analytics, storage
- No-op providers for OSS (unlimited, no tracking)
- Database migrations for projects and project_members
- RLS policies supporting both user-owned and project-owned collections
- Feature flags and comprehensive documentation

Note: Supabase types will be regenerated after migrations are applied
Separates hosted-only migrations into /migrations-hosted/ to prevent
OSS users from accidentally running them. Supabase CLI only reads from
/migrations/ by default, so this ensures clean separation.

Changes:
- Move projects/project_members migrations to migrations-hosted/
- Add warning comments to hosted migration files
- Add README explaining hosted-only migrations
Adds content caching for fast queries without database hits.
Unlike other providers, cache is opt-in for BOTH OSS and hosted.

Features:
- DisabledCacheProvider (default for OSS)
- MemoryCacheProvider (in-process, dev/single-instance)
- FileSystemCacheProvider (persistent, no external deps)
- RedisCacheProvider stub (Redis/Upstash for production)

OSS users can enable caching with CACHE_PROVIDER env var.
Supports memory, filesystem, redis, and upstash options.

Use case: Cache published items for public API without DB queries
Example: Publish item -> cache.set(slug, data) -> fast retrieval
Replace Redis/memory caching with object storage approach:
User → Next.js API → Object Storage Cache → DB (if miss)

Benefits:
- App is the gateway (control URLs, auth, metrics)
- Cache is transparent to users
- CDN accelerates storage reads
- Cheaper than Redis for static content

Providers:
- Supabase Storage (FREE for OSS, uses existing instance)
- Cloudflare R2 ($0.015/GB, FREE egress, production)
- Vercel Blob (simple, Vercel-integrated)
- File System (dev/single-instance)

Removed:
- Redis/Upstash providers (wrong pattern for CMS caching)
- Memory provider (not persistent)

This architecture is better for a CMS:
- Published content cached once, read many times
- No need for in-memory cache or Redis
- Object storage + CDN is cheaper and simpler
- App maintains full control over access
Creates provider pattern for media and video storage.
Not yet integrated with existing code - just the architecture.

Media Storage (images/files):
- Supabase Storage provider (OSS default)
- R2 provider (hosted option, stub)
- Interface: uploadImage(), uploadFile(), delete()

Video Storage (separate - different needs):
- Disabled provider (default)
- Cloudflare Stream provider (transcoding, HLS, thumbnails)
- Bunny.net Stream provider (cheapest option)
- Interface: uploadVideo(), getVideoInfo(), playback URLs

Design decisions:
- Separate media vs video (different requirements)
- OSS default: Supabase Storage (already have it, free)
- Hosted options: R2 for media, CF Stream/Bunny for video
- Video is opt-in (most CMSes don't need it)

Not yet implemented:
- Provider registry initialization
- Integration with existing upload code
- Video upload UI
- Usage tracking/limits
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.

2 participants