Problem
The codebase has two parallel abstractions for view-layer logic:
- 15 Draper decorators in
app/decorators/ — the dominant pattern.
- 2 presenters in
app/presenters/ (BasePresenter, CaseContactPresenter).
BasePresenter (app/presenters/base_presenter.rb) just wraps current_user, current_organization, and policy_scope — all things decorators can already access via the h helper or by accepting them as arguments.
Only one usage exists: app/controllers/concerns/loads_case_contacts.rb:24 instantiates CaseContactPresenter.
Maintaining two abstractions for the same job creates choice paralysis for new contributors and a small amount of cognitive overhead reading the codebase.
Proposal
- Move the logic in
CaseContactPresenter (the casa_cases lookup + display_case_number + boolean_select_options) into either:
- A
CaseContactDecorator collection method, or
- A small query object under
app/queries/ if it belongs upstream of the view.
- Update
app/controllers/concerns/loads_case_contacts.rb to consume the new home.
- Delete
app/presenters/ and the corresponding spec/presenters/ directory (the existing base_presenter_spec.rb is a generator stub anyway).
- Remove
spec/presenters from spec/.prosopite_ignore.
Acceptance criteria
Problem
The codebase has two parallel abstractions for view-layer logic:
app/decorators/— the dominant pattern.app/presenters/(BasePresenter,CaseContactPresenter).BasePresenter(app/presenters/base_presenter.rb) just wrapscurrent_user,current_organization, andpolicy_scope— all things decorators can already access via thehhelper or by accepting them as arguments.Only one usage exists:
app/controllers/concerns/loads_case_contacts.rb:24instantiatesCaseContactPresenter.Maintaining two abstractions for the same job creates choice paralysis for new contributors and a small amount of cognitive overhead reading the codebase.
Proposal
CaseContactPresenter(thecasa_caseslookup +display_case_number+boolean_select_options) into either:CaseContactDecoratorcollection method, orapp/queries/if it belongs upstream of the view.app/controllers/concerns/loads_case_contacts.rbto consume the new home.app/presenters/and the correspondingspec/presenters/directory (the existingbase_presenter_spec.rbis a generator stub anyway).spec/presentersfromspec/.prosopite_ignore.Acceptance criteria
app/presenters/deleted.BasePresenterorCaseContactPresenterremain (grep -r Presenter app/).