feat(shortener): Free/Pro/Enterprise tier gating via feature flags + license (B5)#66
Open
PenguinzTech wants to merge 2 commits into
Open
Conversation
…license (B5) Two-layer gating (PostHog flag defaulted OFF + license tier), per house tier matrix: - app/features.py: feature_enabled() (graceful degradation, cached last-known, new flags OFF, never crash), get_license_tier() (free/professional/enterprise; dev & bypass-domain → enterprise; production fails CLOSED to free on error), require_tier/require_professional/require_enterprise decorators → 402 when below. - Free 5-collection cap enforced server-side in collections.py (402 on 6th; Pro/Ent unlimited) — flag current.collections. - Branded QR (color/logo params) gated to Professional in urls.py QR endpoint (plain QR stays Free) — flag current.branded-qr. - Advanced analytics (geo/device/browser/OS breakdowns) at /analytics/urls/<id>/advanced gated to Enterprise; basic analytics stays all-tiers — flag current.advanced-analytics. - config: POSTHOG_KEY/POSTHOG_HOST (default https://license.penguintech.io). Tests: 649 passed, 90% coverage; features.py 100% (tier resolution, flag degradation, each gate 402/allow, mocked posthog+license clients, no network). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Sorry @PenguinzTech, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
…verage >90%) Adds comprehensive test coverage for: - Advanced analytics endpoint with Enterprise tier gating and feature flags - Date filtering (from/to) in advanced analytics - Advanced breakdown fields (geo, devices, browsers, os) - Redirect error paths: invalid destination URL validation, user-agent parsing - Click recording error handling and database exceptions - Edge cases: no clicks, no user-agent header, database errors with rollback Coverage improvements: - analytics.py: 72% → 92% (advanced endpoint now fully covered) - redirect.py: 23% → 90% (error paths and edge cases now covered) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Feature (Track B, part 3) — tier gating
Stacked on #65 (base =
feature/shortener-redirect-analytics). Targetsrelease/v0.1.x.Two-layer gating per the house tier matrix — a PostHog feature flag (default OFF, graceful degradation) AND license entitlement.
app/features.py—feature_enabled()(cached last-known, new flags OFF, never crashes if PostHog unreachable),get_license_tier()(free/professional/enterprise; dev & bypass-domain → enterprise; production fails closed to free on error), andrequire_tier/require_professional/require_enterprisedecorators (→ 402 when below).collections.py(402 on the 6th; Pro/Enterprise unlimited)./analytics/urls/<id>/advancedgated to Enterprise; basic analytics stays all-tiers.current.collections,current.branded-qr,current.advanced-analytics. Config:POSTHOG_KEY/POSTHOG_HOST.Kept in a new module (not
licensing.py) to avoid conflicting with the A5a licensing hardening (#60).Tests
649 passed, 90% coverage;
features.py100% — tier resolution, flag degradation, each gate's 402/allow paths, mocked PostHog + license clients (no network).🤖 Generated with Claude Code