mirror of
https://github.com/we-promise/sure.git
synced 2026-06-01 00:39:01 +00:00
Functional data-entry surface on the (still preview) /retirement page. The polished combined-page UI is PR4; this ships plain forms + lists so a preview user can populate a plan end to end. - RetirementScoped concern: tier-1 preview gate + tier-2 family killswitch + per-owner plan bootstrap (Goal::Retirement.for_owner find-or-creates, so children always have a parent). RetirementController now uses it. - Nested controllers under Retirement::: PensionSources (full CRUD), Statements (new/create + soft-delete destroy — append-only audit), Adjustments (full CRUD), Buckets (replace-all account selection, same-family filtered). All scoped to the current user's own plan, so cross-user access is impossible by construction. - Routes nested under `resource :retirement` via `scope module:`. - Views: show page rewritten into management sections (sources, adjustments, bucket checkboxes, statement journal) + plain styled_form_with forms. Money carries privacy-sensitive. - Goal gains a target_amount_required? hook (true); Goal::Retirement overrides it false — the forecast owns the target (PR3), so a plan can exist before any target is set. - EN locale for the new surface. 111 controller+model tests green. Note: delete uses Turbo confirm for now; PR4 swaps in the skinned DS::Dialog per the design.
25 lines
769 B
Ruby
25 lines
769 B
Ruby
# Shared gate + plan loading for the Retirement surface and its nested
|
|
# resource controllers. Tier 1 (preview features) comes from
|
|
# PreviewGateable; tier 2 is the family killswitch. The plan is
|
|
# bootstrapped per owner so nested resources always have a parent.
|
|
module RetirementScoped
|
|
extend ActiveSupport::Concern
|
|
include PreviewGateable
|
|
|
|
included do
|
|
before_action :require_preview_features!
|
|
before_action :ensure_retirement_enabled!
|
|
before_action :load_retirement_plan
|
|
end
|
|
|
|
private
|
|
def ensure_retirement_enabled!
|
|
return if Current.family.retirement_enabled?(Current.user)
|
|
raise ActionController::RoutingError, "Not Found"
|
|
end
|
|
|
|
def load_retirement_plan
|
|
@plan = Goal::Retirement.for_owner(Current.user)
|
|
end
|
|
end
|