As a user I want the second person field to only show correspondents of the first person so I never see an empty conversation #29

Closed
opened 2026-03-20 12:30:02 +01:00 by marcel · 0 comments
Owner

Background

When a user enters Person A in the sender field, the receiver typeahead currently shows all persons. Most combinations have no documents at all, leading to the empty state "Keine Dokumente gefunden". This is confusing and forces trial and error.

Desired behaviour

  • Once Person A is selected, the Person B typeahead only returns persons who have at least one document in common with Person A (as sender or receiver in either direction)
  • The filter applies in both directions: selecting Person B first should also restrict the Person A typeahead
  • If a person is cleared, the other typeahead returns to showing all persons
  • When the second field is focused and the first already has a person selected, the dropdown opens immediately (without requiring the user to type first), showing the top correspondents sorted by number of shared documents — limited to 10 results
  • When the user starts typing, the list filters normally (still restricted to correspondents, still sorted by document count)

Implementation notes

Backend: GET /api/persons/{id}/correspondents

  • Returns all persons who share at least one document with the given person (either as sender or as receiver in either direction)
  • Accepts an optional q query parameter for name filtering (used when the user types)
  • Results are ordered by number of shared documents descending
  • Results are limited to 10 (the most frequent correspondents cover the vast majority of useful combinations)
  • Query: join through documents and document_receivers, count matches per counterpart, order by count DESC, limit 10

Frontend: PersonTypeahead changes

  • Add an optional restrictToCorrespondentsOf?: string prop (the other person's ID)
  • When this prop is set and the field is focused, fetch correspondents immediately on focus — no typing required — by calling /api/persons/{id}/correspondents (no q param)
  • When the user types, call /api/persons/{id}/correspondents?q=... instead of /api/persons?q=...
  • When the prop is not set, keep the existing behaviour (show dropdown only on input, call /api/persons?q=...)

Coding rules to keep in mind

  • New endpoint belongs in PersonController, logic in PersonService, query in PersonRepository
  • Keep the PersonTypeahead component change minimal — one extra optional prop, no flag arguments
  • Write a PersonServiceTest unit test for the new service method
## Background When a user enters Person A in the sender field, the receiver typeahead currently shows all persons. Most combinations have no documents at all, leading to the empty state "Keine Dokumente gefunden". This is confusing and forces trial and error. ## Desired behaviour - Once Person A is selected, the Person B typeahead only returns persons who have at least one document in common with Person A (as sender or receiver in either direction) - The filter applies in both directions: selecting Person B first should also restrict the Person A typeahead - If a person is cleared, the other typeahead returns to showing all persons - **When the second field is focused and the first already has a person selected, the dropdown opens immediately** (without requiring the user to type first), showing the top correspondents sorted by number of shared documents — limited to 10 results - When the user starts typing, the list filters normally (still restricted to correspondents, still sorted by document count) ## Implementation notes **Backend:** `GET /api/persons/{id}/correspondents` - Returns all persons who share at least one document with the given person (either as sender or as receiver in either direction) - Accepts an optional `q` query parameter for name filtering (used when the user types) - Results are **ordered by number of shared documents descending** - Results are **limited to 10** (the most frequent correspondents cover the vast majority of useful combinations) - Query: join through `documents` and `document_receivers`, count matches per counterpart, order by count DESC, limit 10 **Frontend:** `PersonTypeahead` changes - Add an optional `restrictToCorrespondentsOf?: string` prop (the other person's ID) - When this prop is set **and the field is focused**, fetch correspondents immediately on focus — no typing required — by calling `/api/persons/{id}/correspondents` (no `q` param) - When the user types, call `/api/persons/{id}/correspondents?q=...` instead of `/api/persons?q=...` - When the prop is not set, keep the existing behaviour (show dropdown only on input, call `/api/persons?q=...`) ## Coding rules to keep in mind - New endpoint belongs in `PersonController`, logic in `PersonService`, query in `PersonRepository` - Keep the `PersonTypeahead` component change minimal — one extra optional prop, no flag arguments - Write a `PersonServiceTest` unit test for the new service method
marcel added the feature label 2026-03-20 19:11:19 +01:00
marcel added the conversation label 2026-03-20 19:15:30 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marcel/familienarchiv#29