oneie
Version:
Build apps, websites, and AI agents in English. Zero-interaction setup for AI agents (Claude Code, Cursor, Windsurf). Download to your computer, run in the cloud, deploy to the edge. Open source and free forever.
895 lines (638 loc) • 17.8 kB
Markdown
title: Feature Based Sites
dimension: things
category: plans
tags: architecture, ontology, things
related_dimensions: events, people
scope: global
created: 2025-11-03
updated: 2025-11-03
version: 1.0.0
ai_context: |
This document is part of the things dimension in the plans category.
Location: one/things/plans/feature-based-sites.md
Purpose: Documents feature-based multi-site architecture
Related dimensions: events, people
For AI agents: Read this to understand feature based sites.
# Feature-Based Multi-Site Architecture
**Status:** 🎯 Active Plan
**Created:** 2025-10-19
**Ontology:** Things (Infrastructure Planning)
## Vision
Build websites by **enabling features**, not selecting templates. Users mix and match features to create exactly what they need.
### The Shift: From Templates to Features
**❌ Template-Based (Rigid):**
```bash
PUBLIC_SITE_TEMPLATE=creator # Gets: portfolio, blog, courses
PUBLIC_SITE_TEMPLATE=ecommerce # Gets: shop, cart, checkout
# Problem: What if you want portfolio + shop + courses?
```
**✅ Feature-Based (Flexible):**
```bash
# Enable exactly what you need
PUBLIC_FEATURES=blog,portfolio,shop,courses,community,tokens
# Or start blank and add features one at a time
PUBLIC_FEATURES=blank # Minimal starter, add features later
```
## Core Concept: Feature Flags
### Environment Variables Control Features
```bash
# .env.local or Cloudflare environment
PUBLIC_SITE_NAME="Jane Doe"
PUBLIC_FEATURES=portfolio,blog,courses,shop,community,tokens
# Each feature adds:
# - Routes (/courses, /shop, etc.)
# - Components (CourseCard, ProductGrid, etc.)
# - Navigation items
# - Database tables/functions
```
### How Features Work
```typescript
// src/config/features.ts
export type Feature =
| "blank" // Minimal starter (homepage, about, contact)
| "blog" // Content hub
| "portfolio" // Project showcase
| "courses" // Course platform
| "shop" // Ecommerce
| "community" // Forums/chat
| "tokens" // Creator tokens
| "library" // Resource library
| "events" // Event management
| "booking" // Appointment scheduling
| "membership" // Subscription tiers
| "analytics"; // Dashboard & insights
export const FEATURES = (import.meta.env.PUBLIC_FEATURES || "blank")
.split(",")
.map((f) => f.trim()) as Feature[];
export const hasFeature = (feature: Feature) =>
FEATURES.includes(feature) || FEATURES.includes("all");
```
## Feature Catalog
### 1. Blank (Starter)
**Perfect for:** Starting from scratch, custom builds
**Includes:**
- Homepage (hero + CTA)
- About page
- Contact page
- Basic navigation
**Routes:**
- `/`
- `/about`
- `/contact`
**No backend needed** - Pure static pages
### 2. Blog
**Perfect for:** Content creators, writers, marketers
**Includes:**
- Blog listing (grid/list views)
- Individual blog posts
- Categories & tags
- Search & filtering
- RSS feed
**Routes:**
- `/blog`
- `/blog/[slug]`
- `/blog/category/[category]`
**Backend needs:** `things` table (type: `blog_post`)
### 3. Portfolio
**Perfect for:** Artists, designers, developers
**Includes:**
- Project showcase
- Case studies
- Image galleries
- Client testimonials
**Routes:**
- `/portfolio`
- `/portfolio/[project-slug]`
**Backend needs:** `things` table (type: `project`)
### 4. Courses
**Perfect for:** Educators, coaches, trainers
**Includes:**
- Course catalog
- Lesson pages
- Progress tracking
- Quizzes & assessments
- Certificates
**Routes:**
- `/courses`
- `/courses/[slug]`
- `/courses/[slug]/lessons/[lesson]`
- `/dashboard` (student progress)
**Backend needs:**
- `things` table (type: `course`, `lesson`)
- `connections` table (relationshipType: `enrolled_in`)
- `events` table (type: `lesson_completed`)
### 5. Shop
**Perfect for:** Product sellers, brands, merchants
**Includes:**
- Product catalog
- Product pages
- Shopping cart
- Checkout flow
- Order management
**Routes:**
- `/shop`
- `/shop/[product-slug]`
- `/cart`
- `/checkout`
- `/orders`
**Backend needs:**
- `things` table (type: `product`)
- `connections` table (relationshipType: `purchased`)
- `events` table (type: `order_placed`)
- Stripe integration
### 6. Community
**Perfect for:** Building engaged audiences
**Includes:**
- Discussion forums
- Chat rooms
- Member directory
- Direct messaging
**Routes:**
- `/community`
- `/community/topics/[topic]`
- `/community/members`
- `/community/messages`
**Backend needs:**
- `things` table (type: `forum_topic`, `message`)
- `connections` table (relationshipType: `follows`, `member_of`)
- Real-time subscriptions
### 7. Tokens
**Perfect for:** Creator economy, fan engagement
**Includes:**
- Token overview
- Buy/sell interface
- Holder benefits
- Token-gated content
**Routes:**
- `/tokens`
- `/tokens/buy`
- `/tokens/holders`
**Backend needs:**
- `things` table (type: `token`)
- `connections` table (relationshipType: `holds_tokens`)
- `events` table (type: `tokens_purchased`)
- Blockchain integration
### 8. Library
**Perfect for:** Resource hubs, knowledge bases
**Includes:**
- Document library
- File uploads
- Search & categories
- Download tracking
**Routes:**
- `/library`
- `/library/[category]`
- `/library/[slug]`
**Backend needs:**
- `things` table (type: `document`)
- `events` table (type: `document_downloaded`)
### 9. Events
**Perfect for:** Event organizers, conferences
**Includes:**
- Event calendar
- Event pages
- RSVP/ticketing
- Attendee list
**Routes:**
- `/events`
- `/events/[slug]`
- `/events/[slug]/register`
**Backend needs:**
- `things` table (type: `event`)
- `connections` table (relationshipType: `registered_for`)
- `events` table (type: `event_registered`)
### 10. Booking
**Perfect for:** Consultants, coaches, service providers
**Includes:**
- Calendar availability
- Appointment booking
- Payment integration
- Reminders
**Routes:**
- `/book`
- `/book/confirm`
- `/appointments`
**Backend needs:**
- `things` table (type: `appointment`)
- `events` table (type: `appointment_booked`)
- Calendar integration
### 11. Membership
**Perfect for:** Subscription businesses
**Includes:**
- Membership tiers
- Subscription management
- Member-only content
- Recurring billing
**Routes:**
- `/membership`
- `/membership/[tier]`
- `/members/dashboard`
**Backend needs:**
- `things` table (type: `membership_tier`)
- `connections` table (relationshipType: `subscribed_to`)
- `events` table (type: `subscription_created`)
- Stripe subscriptions
### 12. Analytics
**Perfect for:** Data-driven creators
**Includes:**
- Traffic dashboard
- Revenue analytics
- User insights
- Export reports
**Routes:**
- `/analytics`
- `/analytics/revenue`
- `/analytics/audience`
**Backend needs:**
- `events` table (all event types)
- Aggregation queries
## Feature Combinations
### Starter Pack (Blank)
```bash
PUBLIC_FEATURES=blank
```
**Use case:** Simple landing page, portfolio
### Content Creator
```bash
PUBLIC_FEATURES=blog,portfolio,community,tokens
```
**Use case:** Influencer, artist, writer with engaged fans
**Routes unlocked:**
- `/` - Homepage
- `/blog` - Content hub
- `/portfolio` - Work showcase
- `/community` - Fan forum
- `/tokens` - Creator economy
### Online Educator
```bash
PUBLIC_FEATURES=courses,library,community,membership
```
**Use case:** Teacher, coach, trainer with paid content
**Routes unlocked:**
- `/` - Homepage
- `/courses` - Course catalog
- `/library` - Resources
- `/community` - Student forum
- `/membership` - Subscription tiers
### Ecommerce + Content
```bash
PUBLIC_FEATURES=shop,blog,membership
```
**Use case:** Brand with products + content marketing
**Routes unlocked:**
- `/` - Homepage
- `/shop` - Product catalog
- `/blog` - Content marketing
- `/membership` - Loyalty program
### Full Stack Creator
```bash
PUBLIC_FEATURES=blog,portfolio,courses,shop,community,tokens,events,library
```
**Use case:** Power creator with multiple revenue streams
**Routes unlocked:** Everything!
## File Structure
```
/web/
├── src/
│ ├── features/
│ │ ├── blank/
│ │ │ ├── pages/
│ │ │ │ ├── index.astro
│ │ │ │ ├── about.astro
│ │ │ │ └── contact.astro
│ │ │ └── components/
│ │ │ └── Hero.astro
│ │ │
│ │ ├── blog/
│ │ │ ├── pages/
│ │ │ │ ├── index.astro
│ │ │ │ └── [...slug].astro
│ │ │ └── components/
│ │ │ ├── BlogList.astro
│ │ │ └── BlogPost.astro
│ │ │
│ │ ├── portfolio/
│ │ │ ├── pages/
│ │ │ │ ├── index.astro
│ │ │ │ └── [...slug].astro
│ │ │ └── components/
│ │ │ └── ProjectGrid.astro
│ │ │
│ │ ├── courses/
│ │ │ ├── pages/
│ │ │ │ ├── index.astro
│ │ │ │ ├── [slug]/index.astro
│ │ │ │ └── [slug]/lessons/[lesson].astro
│ │ │ └── components/
│ │ │ ├── CourseCard.astro
│ │ │ └── LessonList.astro
│ │ │
│ │ ├── shop/
│ │ │ ├── pages/
│ │ │ │ ├── index.astro
│ │ │ │ ├── [slug].astro
│ │ │ │ ├── cart.astro
│ │ │ │ └── checkout.astro
│ │ │ └── components/
│ │ │ ├── ProductGrid.astro
│ │ │ └── ShoppingCart.tsx
│ │ │
│ │ ├── community/
│ │ ├── tokens/
│ │ ├── library/
│ │ ├── events/
│ │ ├── booking/
│ │ ├── membership/
│ │ └── analytics/
│ │
│ ├── config/
│ │ ├── features.ts # Feature detection
│ │ ├── navigation.ts # Dynamic nav based on features
│ │ └── site.ts # Site metadata
│ │
│ ├── components/ui/ # Shared shadcn/ui
│ │
│ └── pages/
│ └── [...feature].astro # Dynamic router
│
├── astro.config.mjs
└── .env
```
## Dynamic Routing
### Feature-Based Page Resolution
```astro
// src/pages/[...route].astro
import { FEATURES, hasFeature } from '@/config/features';
const route = Astro.params.route || '';
// Resolve feature from route
const featureMap = {
'': 'blank', // Homepage
'blog': 'blog',
'portfolio': 'portfolio',
'courses': 'courses',
'shop': 'shop',
'community': 'community',
'tokens': 'tokens',
'library': 'library',
'events': 'events',
'book': 'booking',
'membership': 'membership',
'analytics': 'analytics',
};
const feature = featureMap[route.split('/')[0]];
// Check if feature is enabled
if (!hasFeature(feature)) {
return Astro.redirect('/404');
}
// Import feature page dynamically
const Page = await import(`@/features/${feature}/pages/${route}.astro`);
<Page.default {...Astro.props} />
```
## Navigation Generation
### Dynamic Nav Based on Enabled Features
```typescript
// src/config/navigation.ts
import { hasFeature } from "./features";
export const generateNavigation = () => {
const nav = [];
// Always include home
nav.push({ label: "Home", href: "/" });
// Add feature-specific nav items
if (hasFeature("blog")) {
nav.push({ label: "Blog", href: "/blog" });
}
if (hasFeature("portfolio")) {
nav.push({ label: "Portfolio", href: "/portfolio" });
}
if (hasFeature("courses")) {
nav.push({ label: "Courses", href: "/courses" });
}
if (hasFeature("shop")) {
nav.push({ label: "Shop", href: "/shop" });
}
if (hasFeature("community")) {
nav.push({ label: "Community", href: "/community" });
}
if (hasFeature("events")) {
nav.push({ label: "Events", href: "/events" });
}
// Always include about & contact
nav.push({ label: "About", href: "/about" });
nav.push({ label: "Contact", href: "/contact" });
return nav;
};
```
## NPX OneIE Integration
### Feature Selection UI
```bash
npx oneie init
# Interactive prompts:
✓ What's your name? Jane Doe
✓ Site tagline? Artist, Educator, Creator
? Select features (space to select, enter to continue):
◯ Blank (minimal starter)
◉ Blog (content hub)
◉ Portfolio (project showcase)
◉ Courses (course platform)
◉ Shop (ecommerce)
◯ Community (forums/chat)
◉ Tokens (creator economy)
◯ Library (resources)
◯ Events (event management)
◯ Booking (appointments)
◯ Membership (subscriptions)
◯ Analytics (dashboard)
✓ Deploy now? y
```
### Generated .env.local
```bash
# Site Configuration
PUBLIC_SITE_NAME="Jane Doe"
PUBLIC_SITE_TAGLINE="Artist, Educator, Creator"
# Features (comma-separated)
PUBLIC_FEATURES=blog,portfolio,courses,shop,tokens
# Backend Connection
PUBLIC_CONVEX_URL=https://shocking-falcon-870.convex.cloud
CONVEX_DEPLOYMENT=prod:shocking-falcon-870
# Authentication
BETTER_AUTH_SECRET=generated-secret-key
BETTER_AUTH_URL=https://janedoe.pages.dev
```
## Development Workflow
### Local Development
```bash
# Start with blank template
PUBLIC_FEATURES=blank bun run dev
# Add blog feature
PUBLIC_FEATURES=blank,blog bun run dev
# Add multiple features
PUBLIC_FEATURES=blog,portfolio,courses,shop bun run dev
# Enable everything
PUBLIC_FEATURES=all bun run dev
```
### Build for Production
```bash
# Build with specific features
PUBLIC_FEATURES=blog,courses,shop bun run build
# Deploy to Cloudflare
wrangler pages deploy dist --project-name=janedoe-creator
```
## Benefits
### Maximum Flexibility
- ✅ **Mix & match** any features
- ✅ **Start minimal** (blank template)
- ✅ **Add features** as you grow
- ✅ **Remove features** you don't need
### No Rigid Templates
- ❌ No "creator" vs "ecommerce" choice
- ✅ Enable exactly what you need
- ✅ Creator + ecommerce + courses? Yes!
- ✅ Portfolio + shop + events? Yes!
### Easy Customization
```bash
# Start blank
PUBLIC_FEATURES=blank
# Add blog
PUBLIC_FEATURES=blank,blog
# Add shop later
PUBLIC_FEATURES=blank,blog,shop
# Add courses when ready
PUBLIC_FEATURES=blank,blog,shop,courses
```
### Backend Efficiency
Only loads/generates code for enabled features:
```typescript
// Conditionally load feature services
if (hasFeature("shop")) {
const { ProductService } = await import(
"@/features/shop/services/ProductService"
);
}
if (hasFeature("courses")) {
const { CourseService } = await import(
"@/features/courses/services/CourseService"
);
}
```
## Feature Dependencies
Some features depend on others:
```typescript
// src/config/features.ts
export const FEATURE_DEPENDENCIES: Record<Feature, Feature[]> = {
membership: ["shop"], // Memberships need payment
tokens: ["community"], // Tokens need community
analytics: [], // No dependencies
booking: ["shop"], // Booking needs payment
library: [], // No dependencies
events: ["shop"], // Events may need ticketing
// etc.
};
// Auto-enable dependencies
export const resolveFeatures = (requested: Feature[]): Feature[] => {
const enabled = new Set(requested);
for (const feature of requested) {
const deps = FEATURE_DEPENDENCIES[feature] || [];
deps.forEach((dep) => enabled.add(dep));
}
return Array.from(enabled);
};
```
## Pre-Built Feature Combinations
For convenience, offer pre-built combos:
```typescript
// src/config/presets.ts
export const PRESETS = {
blank: ["blank"],
blogger: ["blog", "portfolio"],
creator: ["blog", "portfolio", "community", "tokens"],
educator: ["courses", "library", "community", "membership"],
ecommerce: ["shop", "blog"],
powerhouse: [
"blog",
"portfolio",
"courses",
"shop",
"community",
"tokens",
"events",
],
};
// Usage
PUBLIC_FEATURES_PRESET = creator;
// Expands to: blog,portfolio,community,tokens
```
## Implementation Timeline
### Week 1: Core Infrastructure
- Create feature system
- Build blank template
- Add feature detection logic
### Week 2: Core Features
- Build blog feature
- Build portfolio feature
- Test feature combinations
### Week 3-4: Additional Features
- Build courses feature
- Build shop feature
- Build community feature
### Week 5-6: Advanced Features
- Build tokens feature
- Build events feature
- Build membership feature
### Week 7: CLI Integration
- Update `npx oneie` to support features
- Add feature selection UI
- Test end-to-end
## Success Metrics
- [ ] Blank template works (homepage, about, contact)
- [ ] Feature flags control routes correctly
- [ ] Navigation updates based on enabled features
- [ ] Can combine any features without conflicts
- [ ] Bundle only includes enabled feature code
- [ ] `npx oneie` allows feature selection
- [ ] Users can start blank and add features later
## Next Steps
1. **Create blank template** (Day 1)
2. **Build feature system** (Day 2)
3. **Add blog feature** (Day 3)
4. **Add portfolio feature** (Day 4)
5. **Test feature combinations** (Day 5)
6. **Add shop & courses features** (Week 2)
7. **Integrate with npx oneie** (Week 3)
**This is way more flexible than templates!** 🚀
Users start blank, then enable exactly what they need. Want blog + shop? Done. Want courses + community + tokens? Done. Want everything? Enable `all`!
No more rigid templates - just features you can mix and match infinitely.