npm package: @rivtor/features
Description: Production-ready feature gating and entitlement engine for B2B SaaS
Author: Rivtor
Latest version: 1.0.1

# @rivtor/features

[![npm version](https://badge.fury.io/js/%40rivtor%2Ffeatures.svg)](https://www.npmjs.com/package/@rivtor/features)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Production-ready feature gating and entitlement engine for B2B SaaS.

## Overview

`@rivtor/features` is the "Entitlement Engine" that connects Stripe Plans to Code. It eliminates spaghetti feature-flag logic by providing a simple, declarative way to gate features based on subscription plans.

**Key Features:**
- 🚪 **Feature Gates** - Simple React wrapper to show/hide features
- 💳 **Stripe Integration** - Automatic plan detection and caching
- ⚡ **Zero API Calls** - Instant feature checks via Stripe cache
- 📊 **Upgrade Prompts** - Built-in upgrade banners
- 🎯 **Type-Safe** - Full TypeScript support

## Installation

```bash
npm install @rivtor/features
```

## Quick Start

### Configuration

```typescript
// rivtor.config.ts
export const config = {
  features: {
    analytics: { tiers: ['pro', 'enterprise'] },
    'api-access': { tiers: ['pro', 'enterprise'] },
    'custom-domain': { tiers: ['enterprise'] },
    'priority-support': { tiers: ['enterprise'] },
  },
};
```

### Client-Side (React)

```tsx
import { RivtorGate } from '@rivtor/features/react';

export default function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      
      <RivtorGate 
        feature="analytics" 
        fallback={<UpgradeBanner feature="Analytics Dashboard" />}
      >
        <AnalyticsDashboard />
      </RivtorGate>
      
      <RivtorGate feature="api-access">
        <APIKeysSection />
      </RivtorGate>
    </div>
  );
}
```

### Server-Side

```typescript
import { features } from '@rivtor/features';

export async function GET(request: Request) {
  const user = await auth.requireUser(request);
  
  // Check feature access
  const hasAnalytics = await features.hasFeature(user.id, 'analytics');
  
  if (!hasAnalytics) {
    return Response.json(
      { error: 'Upgrade to Pro to access analytics' },
      { status: 402 }
    );
  }
  
  // Feature available, proceed
  const data = await getAnalyticsData(user.id);
  return Response.json(data);
}

// Or use requireFeature (throws error if not available)
export async function POST(request: Request) {
  const user = await auth.requireUser(request);
  await features.requireFeature(user.id, 'api-access');
  
  // Proceed with API key generation
}
```

## API Reference

### Server Methods

- `hasFeature(userId, feature)` - Check if user has feature access
- `getAvailableFeatures(userId)` - Get all features for user's plan
- `requireFeature(userId, feature)` - Throw error if feature not available

### React Components

- `<RivtorGate feature="name" fallback={<Component />}>` - Feature gate wrapper

## Environment Variables

```bash
# Stripe (Required)
STRIPE_SECRET_KEY=sk_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_...

# Supabase (Required)
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
```

## How It Works

1. User subscribes to a plan in Stripe
2. Plan metadata is synced to your database via webhooks
3. `@rivtor/features` checks the cached subscription data
4. Feature gates show/hide content based on plan tier

**No API calls during feature checks = instant performance**

## License

MIT © Rivtor

## Support

- Email: legal@rivtor.com
- Documentation: [GitHub Wiki](https://github.com/rivtor/rivtor-features/wiki)

---

**Built with care by [Rivtor](https://rivtor.com)**