feat: add comprehensive tier-based feature management system
Implement database-driven feature gating with contextual upgrade prompts: - Add Feature model with 30 features across 8 categories - Create FeatureService with caching for tier-based feature checking - Add @require_feature decorator and RequireFeature dependency for backend enforcement - Create vendor features API (6 endpoints) and admin features API - Add Alpine.js feature store and upgrade prompts store for frontend - Create Jinja macros: feature_gate, feature_locked, limit_warning, usage_bar - Add usage API for tracking orders/products/team limits with upgrade info - Fix Stripe webhook to create VendorAddOn records on addon purchase - Integrate upgrade prompts into vendor dashboard with tier badge and usage bars 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
10
app/templates/vendor/base.html
vendored
10
app/templates/vendor/base.html
vendored
@@ -62,7 +62,13 @@
|
||||
<!-- 5. FIFTH: API Client (depends on Utils) -->
|
||||
<script src="{{ url_for('static', path='shared/js/api-client.js') }}"></script>
|
||||
|
||||
<!-- 6. SIXTH: Alpine.js v3 with CDN fallback (with defer) -->
|
||||
<!-- 6. SIXTH: Feature Store (depends on API Client, registers with Alpine) -->
|
||||
<script src="{{ url_for('static', path='shared/js/feature-store.js') }}"></script>
|
||||
|
||||
<!-- 7. SEVENTH: Upgrade Prompts (depends on API Client, registers with Alpine) -->
|
||||
<script src="{{ url_for('static', path='shared/js/upgrade-prompts.js') }}"></script>
|
||||
|
||||
<!-- 8. EIGHTH: Alpine.js v3 with CDN fallback (with defer) -->
|
||||
<script>
|
||||
(function() {
|
||||
var script = document.createElement('script');
|
||||
@@ -81,7 +87,7 @@
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- 7. LAST: Page-specific scripts -->
|
||||
<!-- 9. LAST: Page-specific scripts -->
|
||||
{% block extra_scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
30
app/templates/vendor/dashboard.html
vendored
30
app/templates/vendor/dashboard.html
vendored
@@ -1,16 +1,24 @@
|
||||
{# app/templates/vendor/dashboard.html #}
|
||||
{% extends "vendor/base.html" %}
|
||||
{% from "shared/macros/feature_gate.html" import limit_warning, usage_bar, upgrade_card, tier_badge %}
|
||||
|
||||
{% block title %}Dashboard{% endblock %}
|
||||
|
||||
{% block alpine_data %}vendorDashboard(){% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Limit Warnings -->
|
||||
{{ limit_warning("orders") }}
|
||||
{{ limit_warning("products") }}
|
||||
|
||||
<!-- Page Header with Refresh Button -->
|
||||
<div class="flex items-center justify-between my-6">
|
||||
<h2 class="text-2xl font-semibold text-gray-700 dark:text-gray-200">
|
||||
Dashboard
|
||||
</h2>
|
||||
<div class="flex items-center gap-3">
|
||||
<h2 class="text-2xl font-semibold text-gray-700 dark:text-gray-200">
|
||||
Dashboard
|
||||
</h2>
|
||||
{{ tier_badge() }}
|
||||
</div>
|
||||
<button
|
||||
@click="refresh()"
|
||||
:disabled="loading"
|
||||
@@ -40,6 +48,9 @@
|
||||
<!-- Vendor Info Card -->
|
||||
{% include 'vendor/partials/vendor_info.html' %}
|
||||
|
||||
<!-- Upgrade Recommendation Card (shows when approaching/at limits) -->
|
||||
{{ upgrade_card(class='mb-6') }}
|
||||
|
||||
<!-- Stats Cards -->
|
||||
<div x-show="!loading" class="grid gap-6 mb-8 md:grid-cols-2 xl:grid-cols-4">
|
||||
<!-- Card: Total Products -->
|
||||
@@ -103,6 +114,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Usage Overview -->
|
||||
<div x-show="!loading" class="grid gap-6 mb-8 md:grid-cols-3">
|
||||
<div class="p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
|
||||
{{ usage_bar("orders", "Monthly Orders") }}
|
||||
</div>
|
||||
<div class="p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
|
||||
{{ usage_bar("products", "Products") }}
|
||||
</div>
|
||||
<div class="p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
|
||||
{{ usage_bar("team_members", "Team Members") }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Recent Orders Table -->
|
||||
<div x-show="!loading && recentOrders.length > 0" class="w-full mb-8 overflow-hidden rounded-lg shadow-xs">
|
||||
<div class="w-full overflow-x-auto">
|
||||
|
||||
Reference in New Issue
Block a user