feat: Implement user tier-based feature gating system #8
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implement a system to gate features and functions behind user tiers (Free, Pro, Enterprise). This provides the foundation for monetization and premium feature differentiation.
User Tiers
freeproenterpriseRequirements
Database
tiercolumn touserstable if not present (enum:free,pro,enterprise, default:free)Backend - Feature Registry
backend/src/config/feature-tiers.ts- hardcoded feature-to-tier mappingdocument.scanMaintenanceSchedule)Example structure:
Backend - Tier Enforcement
canAccessFeature(userTier: Tier, featureKey: string): booleangetRequiredTier(featureKey: string): TiergetTierLevel(tier: Tier): number(for comparison: free=0, pro=1, enterprise=2)Frontend - Tier Context
/api/auth/me)useTierAccesshook:hasAccess(featureKey: string): booleancheckAccess(featureKey: string): { allowed: boolean; requiredTier?: Tier }Frontend - Upgrade Dialog
UpgradeRequiredDialogcomponentfeatureKey,open,onCloseAdmin UI Integration
Initial Feature Gate
Technical Notes
feature-tiers.tsuseTierAccesshookenterprise>pro>free(higher tiers inherit all lower tier features)Acceptance Criteria
Out of Scope (Future Issues)
Implementation Plan - User Tier-Based Feature Gating
Analysis Summary
Codebase Analysis Complete. Key findings:
subscription_tiercolumnuser_profilestable (migration 002)SubscriptionTiertypeAdminUsersPage.tsxdropdown worksscanForMaintenancecolumndocumentstable (migration 002)Files to Create (4):
backend/src/config/feature-tiers.tsbackend/src/core/plugins/tier-guard.plugin.tsfrontend/src/core/hooks/useTierAccess.tsfrontend/src/shared-minimal/components/UpgradeRequiredDialog.tsxFiles to Modify (4):
backend/src/core/plugins/auth.plugin.ts(add tier to userContext)backend/src/features/documents/domain/documents.service.ts(validate tier)frontend/src/features/documents/components/DocumentForm.tsx(gate checkbox)Milestone 1: Backend Feature Registry and Tier Service
Goal: Create centralized feature-to-tier configuration and utility functions.
Files:
backend/src/config/feature-tiers.tsImplementation:
Tests:
feature-tiers.spec.ts- Unit tests for tier comparison logicAcceptance:
Milestone 2: Backend Auth Context Extension
Goal: Add
subscriptionTierto request.userContext for route-level checks.Files:
backend/src/core/plugins/auth.plugin.tsChanges at line ~208:
Type augmentation update:
Acceptance:
Milestone 3: Backend Tier Enforcement Middleware
Goal: Create reusable middleware for route-level tier checks.
Files:
backend/src/core/plugins/tier-guard.plugin.tsbackend/src/app.tsImplementation Pattern (following admin-guard.plugin.ts):
Acceptance:
Milestone 4: Backend Documents Tier Validation
Goal: Gate
scanForMaintenancefeature at API level.Files:
backend/src/features/documents/domain/documents.service.tsbackend/src/features/documents/api/documents.controller.tsService validation:
Tests:
Acceptance:
Milestone 5: Frontend Tier Access Hook
Goal: Create React hook for checking feature access.
Files:
frontend/src/core/hooks/useTierAccess.tsfrontend/src/core/hooks/index.tsImplementation (following useAdminAccess pattern):
Acceptance:
Milestone 6: Frontend Upgrade Dialog Component
Goal: Create reusable upgrade prompt dialog.
Files:
frontend/src/shared-minimal/components/UpgradeRequiredDialog.tsxfrontend/src/shared-minimal/components/index.tsProps:
Implementation (mobile + desktop responsive):
Acceptance:
Milestone 7: Frontend Document Form Gating
Goal: Gate scanForMaintenance checkbox in document upload.
Files:
frontend/src/features/documents/components/DocumentForm.tsxImplementation:
Acceptance:
Milestone 8: Testing and Documentation
Goal: Comprehensive test coverage and documentation.
Tests:
feature-tiers.spec.tstier-guard.plugin.spec.tsdocuments.service.spec.tsuseTierAccess.spec.tsxUpgradeRequiredDialog.spec.tsxDocumentation Updates:
backend/src/config/README.md- Document feature-tiers configdocs/FEATURES.md- Document tier system architectureAcceptance:
Dependencies Between Milestones
Recommended Order: M1 -> M2 -> M3 -> M4 -> M5 -> M6 -> M7 -> M8
Risk Assessment
Out of Scope (per issue requirements)
Ready for review. Please provide feedback on this plan before implementation begins.
Plan Review Cycle Complete
Review Summary
Blocking Issues (Must Fix Before Implementation)
1. Incorrect File Paths (TW)
backend/src/config/feature-tiers.tsbackend/src/core/config/feature-tiers.tsbackend/src/config/README.mdbackend/src/core/config/README.md2. Missing Index Files (TW)
frontend/src/core/hooks/index.ts- does not existfrontend/src/shared-minimal/components/index.ts- does not existDecision needed: Create these index files or use direct imports?
3. TypeScript Interface Update Required (QR Code)
The
FastifyRequest.userContextinterface atauth.plugin.ts:49-60must be extended:4. ForbiddenError Class Does Not Exist (QR Code)
Plan references
throw new ForbiddenError({...})but no such class exists.Decision needed:
core/errors/ForbiddenError.tsShould Fix (Before Milestone Completion)
5. Guard Pattern Inconsistency (QR Code)
requireAdminuses direct decoration; plan showsrequireTieras factory function. Should be consistent.Recommendation: Follow
requireAdminpattern (direct decoration with parameter object).6. Config Drift Strategy (QR Completeness)
Plan mentions risk but mitigation is vague.
Decision needed:
/api/config/feature-tiersendpoint7. Data Migration Decision (QR Completeness)
Existing free users may have
scanForMaintenance=true.Decision needed: Grandfather existing data OR reset to false?
8. Missing Decision Log (QR Completeness)
Add section documenting:
Suggestions (Nice to Have)
__tests__/or alongside source)Action Items
Before Implementation Begins:
Ready to start M1 after decisions are made.
Decision Log
Decisions made on blocking issues:
backend/src/core/config/frontend/src/core/hooks/index.tsandfrontend/src/shared-minimal/components/index.tsrequireAdminandrequireTierare distinct/api/config/feature-tiersendpointscanForMaintenance=truetofalsefor free usersUpdated Plan Amendments
M1 Update - Add API endpoint:
backend/src/core/config/feature-tiers.tsGET /api/config/feature-tiersendpoint returning feature configM4 Update - Controller pattern:
M5 Update - Fetch from API:
New: Data Migration (add to M4):
All blocking issues resolved. Ready to begin implementation.
Milestone 1 Complete: Backend Feature Registry and Tier Service
Files Created
backend/src/core/config/feature-tiers.tsbackend/src/core/config/config.routes.tsbackend/src/core/config/tests/feature-tiers.test.tsFiles Modified
backend/src/app.tsAPI Endpoint
Exported Utilities
getTierLevel(tier)- Get numeric level (0/1/2)canAccessFeature(userTier, featureKey)- Check access permissiongetRequiredTier(featureKey)- Get minimum tier for featuregetFeatureConfig(featureKey)- Get full feature configgetAllFeatureConfigs()- Get all configs (for API)Test Results
Acceptance Criteria
Proceeding to M2: Backend Auth Context Extension
Milestone 2 Complete: Backend Auth Context Extension
Files Modified
backend/src/core/plugins/auth.plugin.tsChanges Made
Type Check
Acceptance Criteria
Proceeding to M3: Backend Tier Enforcement Middleware
Milestone 3 Complete: Backend Tier Enforcement Middleware
Files Created
backend/src/core/plugins/tier-guard.plugin.tsbackend/src/core/plugins/tests/tier-guard.plugin.test.tsFiles Modified
backend/src/app.tsUsage
403 Error Response
Test Results
Acceptance Criteria
Proceeding to M4: Backend Documents Tier Validation
Milestone 4 Complete: Backend Documents Tier Validation
Files Created
backend/src/features/documents/migrations/003_reset_scan_for_maintenance_free_users.sqlbackend/src/features/documents/tests/unit/documents.controller.tier.test.tsFiles Modified
backend/src/features/documents/api/documents.controller.tsImplementation Summary
Controller Tier Validation (lines 88-106, 134-153):
Data Migration:
Test Results
Combined Test Summary (All Tier Tests)
Acceptance Criteria
Proceeding to M5: Frontend Tier Access Hook
Milestone 5 Complete: Frontend Tier Access Hook
Files Created
frontend/src/core/hooks/useTierAccess.tsfrontend/src/core/hooks/index.tsFiles Modified
frontend/src/features/settings/types/profile.types.tsSubscriptionTiertype andsubscriptionTierfield toUserProfileHook API
Implementation Details
user-profilequery key with 5-minute stale time/api/config/feature-tierswith 30-minute stale timeallowed: truefor safetyType Check
Acceptance Criteria
Proceeding to M6: Frontend Upgrade Dialog Component
Milestone 6 Complete: Frontend Upgrade Dialog Component
Files Created
frontend/src/shared-minimal/components/UpgradeRequiredDialog.tsxfrontend/src/shared-minimal/components/index.tsComponent API
Features
Responsive Design:
< 600px)Tier Visualization:
Dynamic Content:
Actions:
Type Check
Acceptance Criteria
Proceeding to M7: Frontend Document Form Gating
Milestone 7 Complete: Frontend Document Form Gating
Files Modified
frontend/src/features/documents/components/DocumentForm.tsxImplementation Details
Imports added:
Hook usage:
UI Behavior:
Visual Comparison
Free User:
Pro/Enterprise User:
Type Check
Acceptance Criteria
Implementation Summary
All milestones for Issue #8 (User Tier-Based Feature Gating) have been completed:
Files Created (9)
backend/src/core/config/feature-tiers.tsbackend/src/core/config/config.routes.tsbackend/src/core/config/tests/feature-tiers.test.tsbackend/src/core/plugins/tier-guard.plugin.tsbackend/src/core/plugins/tests/tier-guard.plugin.test.tsbackend/src/features/documents/migrations/003_reset_scan_for_maintenance_free_users.sqlbackend/src/features/documents/tests/unit/documents.controller.tier.test.tsfrontend/src/core/hooks/useTierAccess.tsfrontend/src/core/hooks/index.tsfrontend/src/shared-minimal/components/UpgradeRequiredDialog.tsxfrontend/src/shared-minimal/components/index.tsFiles Modified (4)
backend/src/app.tsbackend/src/core/plugins/auth.plugin.tsbackend/src/features/documents/api/documents.controller.tsfrontend/src/features/documents/components/DocumentForm.tsxfrontend/src/features/settings/types/profile.types.tsTest Summary
Remaining for M8 (Testing and Documentation)
Ready for review and merge.
Milestone 8 Complete: Documentation
Files Created
docs/TIER-GATING.mdDocumentation Contents
Pull Request Created
PR #18: feat: Implement user tier-based feature gating system
Implementation Complete
All 8 milestones have been completed:
Ready for review and merge.