Files
datatools-dev/src/gui/components/__init__.py
Michael d32b58e61a feat(license): add Lite SKU; remove user-facing free trial
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>
2026-05-13 17:19:30 +00:00

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",
]