Two coupled changes:
1. Lite tier
- New Tier.LITE in src/license/schema.py.
- FEATURES_BY_TIER[Tier.LITE] = {Deduplicator, Text Cleaner,
Format Standardizer}. The three universally-useful tools that
cover the most common bookkeeping / RevOps / Klaviyo prep
workflows. Other six tools require Core.
- i18n: license.tier_lite, license.feature_locked_title,
license.feature_locked_body, license.upgrade_link,
license.status_locked (en + es).
- Per-tool feature gate at every GUI tool page
(require_feature_or_render_upgrade) and every tool CLI
(guard(feature=...)). A locked tool renders an upgrade
prompt + Manage-license button (GUI) or exits with code 2
(CLI).
- Home grid: tool cards the user's tier doesn't unlock get a
red 🔒 Locked badge in place of green Ready.
2. Trial removed
- Activation form's "Start 1-year trial" button removed.
- license_cli's `trial` subcommand removed.
- activation.trial_button / activation.trial_help i18n keys
dropped (pack parity test stays green).
- Tier.TRIAL stays in the enum (back-compat with any field-
tested trial licenses); LicenseManager._mint stays internal
for tests and the seller's key generator.
- Decision logged in DECISIONS §9b: a 1-year all-features
trial undercuts paid Lite; paid-only keeps tier economics
clean.
Tests (+29 net): +17 Lite-tier unit/guard tests + 13 Lite-tier
GUI tests + 1 trial-absent assertion - 2 trial CLI tests - 1
trial GUI button test. Total: 1995 → 2024.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
71 lines
2.7 KiB
Python
71 lines
2.7 KiB
Python
"""Reusable Streamlit widgets for the DataTools GUI.
|
|
|
|
This package replaces the former single ``components.py`` module. Public
|
|
behaviour is identical — every name that used to be importable from
|
|
``src.gui.components`` is still importable from the same path because
|
|
this ``__init__`` re-exports the legacy surface in full.
|
|
|
|
The package layout exists so per-tool builds can ship only the seams
|
|
they need without dragging the entire kitchen-sink module:
|
|
|
|
components/
|
|
__init__.py ← compatibility shim (this file)
|
|
_legacy.py ← original components.py, unchanged
|
|
gate.py ← gate-only seam (require_normalization_gate)
|
|
findings.py ← analyzer-finding rendering seam
|
|
dedup_review.py ← dedup match-group cards + review pipeline
|
|
shared.py ← chrome / file-pickup helpers used by every tool
|
|
|
|
A standalone Deduplicator build, for example, can ship without
|
|
``findings.py`` and ``gate.py`` — those modules import the analyzer /
|
|
gate code that the Lite SKU does not include.
|
|
|
|
Adding new tooling: drop new helpers into the appropriate seam module.
|
|
Add their names to its ``__all__`` and to this file's ``__all__`` if
|
|
they should remain importable from ``src.gui.components`` directly.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
# Re-export the full legacy surface so existing pages continue to
|
|
# import unchanged. Once individual tool packages start consuming
|
|
# the focused seam modules directly, names can migrate out of
|
|
# _legacy.py without breaking those imports — this shim is what
|
|
# absorbs the move.
|
|
from ._legacy import * # noqa: F401,F403
|
|
from . import _legacy as _legacy # noqa: F401 (keep for direct access)
|
|
|
|
# Names exported from _legacy.py that pages currently use. Kept here as
|
|
# the canonical public list so a removal from _legacy is a visible
|
|
# breaking change instead of a silent drop.
|
|
from .activation import ( # noqa: F401 re-exported
|
|
render_activation_form,
|
|
render_license_status_sidebar,
|
|
require_feature_or_render_upgrade,
|
|
require_license_or_render_activation,
|
|
)
|
|
|
|
__all__ = [
|
|
# Shared chrome / pickup / gate
|
|
"hide_streamlit_chrome",
|
|
"quit_button",
|
|
"pickup_or_upload",
|
|
"require_normalization_gate",
|
|
# License gate + activation form
|
|
"render_activation_form",
|
|
"render_license_status_sidebar",
|
|
"require_feature_or_render_upgrade",
|
|
"require_license_or_render_activation",
|
|
# Dedup widgets
|
|
"config_panel",
|
|
"match_group_card",
|
|
"results_summary",
|
|
"apply_review_decisions",
|
|
# Analyzer widgets
|
|
"tool_display_name",
|
|
"render_findings_panel",
|
|
"render_hidden_aware_preview",
|
|
"upload_and_analyze_section",
|
|
"findings_count_for_tool",
|
|
]
|