Exploration spike following expert-panel synthesis. Codifies the 3-tier
gating model (instance / per-user / per-family) without adding a
framework. Investments is the first family-scoped module.
- Family#disabled_modules: string[] column, opt-out semantics. No
per-module DB column. Existing families default to [] = enabled.
- Family::AVAILABLE_MODULES = %w[investments] (the registry).
- ModuleGateable concern (auto-included in ApplicationController):
require_module! class macro + module_enabled? helper.
- Api::V1::BaseController#require_module!: 403 feature_disabled JSON,
mirrors require_ai_enabled.
- NavigationHelper extracts mobile/desktop nav into a single source
with module: key support; mobile shrinks via justify-around, never
auto-fills empty slots.
- Settings → Preferences gains a family-scoped module toggle card.
- 4 HTML controllers (Investments, Holdings, Trades, Securities) +
3 API controllers gated. Investment/Crypto account types hidden in
the new-account modal when off.
- docs/feature-gating.md codifies the rule for future modules.
Background-job layer not wired (no Investments-specific scheduled job
to gate; flagged as TODO in docs). Run db:migrate before bin/rails
test. No PR yet — awaiting decisions in open-questions list.
* Enhance security handling logic:
- Prioritize user's country in sorting securities and country codes.
- Add comprehensive mapping for MIC codes to user-friendly exchange names.
- Revamp combobox to consistently pull from a provider when available.
- Improve handling of custom ticker and exchange input fields.
* Localize securities combobox display and exchange labels.
---------
Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>