feat: add snipe tier gates with LOCAL_VISION_UNLOCKABLE
This commit is contained in:
parent
ee3c85bfb0
commit
95ccd8f1b3
2 changed files with 57 additions and 0 deletions
34
app/tiers.py
Normal file
34
app/tiers.py
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
"""Snipe feature gates. Delegates to circuitforge_core.tiers."""
|
||||||
|
from __future__ import annotations
|
||||||
|
from circuitforge_core.tiers import can_use as _core_can_use, TIERS # noqa: F401
|
||||||
|
|
||||||
|
# Feature key → minimum tier required.
|
||||||
|
FEATURES: dict[str, str] = {
|
||||||
|
# Free tier
|
||||||
|
"metadata_trust_scoring": "free",
|
||||||
|
"hash_dedup": "free",
|
||||||
|
# Paid tier
|
||||||
|
"photo_analysis": "paid",
|
||||||
|
"serial_number_check": "paid",
|
||||||
|
"ai_image_detection": "paid",
|
||||||
|
"reverse_image_search": "paid",
|
||||||
|
"saved_searches": "paid",
|
||||||
|
"background_monitoring": "paid",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Photo analysis features unlock if user has local vision model (moondream2 (MD2) or similar).
|
||||||
|
LOCAL_VISION_UNLOCKABLE: frozenset[str] = frozenset({
|
||||||
|
"photo_analysis",
|
||||||
|
"serial_number_check",
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def can_use(
|
||||||
|
feature: str,
|
||||||
|
tier: str = "free",
|
||||||
|
has_byok: bool = False,
|
||||||
|
has_local_vision: bool = False,
|
||||||
|
) -> bool:
|
||||||
|
if has_local_vision and feature in LOCAL_VISION_UNLOCKABLE:
|
||||||
|
return True
|
||||||
|
return _core_can_use(feature, tier, has_byok=has_byok, _features=FEATURES)
|
||||||
23
tests/test_tiers.py
Normal file
23
tests/test_tiers.py
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
from app.tiers import can_use, FEATURES, LOCAL_VISION_UNLOCKABLE
|
||||||
|
|
||||||
|
|
||||||
|
def test_metadata_scoring_is_free():
|
||||||
|
assert can_use("metadata_trust_scoring", tier="free") is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_photo_analysis_is_paid():
|
||||||
|
assert can_use("photo_analysis", tier="free") is False
|
||||||
|
assert can_use("photo_analysis", tier="paid") is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_local_vision_unlocks_photo_analysis():
|
||||||
|
assert can_use("photo_analysis", tier="free", has_local_vision=True) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_byok_does_not_unlock_photo_analysis():
|
||||||
|
assert can_use("photo_analysis", tier="free", has_byok=True) is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_saved_searches_require_paid():
|
||||||
|
assert can_use("saved_searches", tier="free") is False
|
||||||
|
assert can_use("saved_searches", tier="paid") is True
|
||||||
Loading…
Reference in a new issue