Description
A symptom entry is a kind of log entry. It is a Log delegated type, and the Log carries the date. One row per dated observation, so the same symptom logged over a week is seven entries.
Fields come from the journal's Symptom Log table (Section 3): Date, Severity (1 to 10), Duration, Time of Day, Possible Triggers or Trends Over Time, Treatments and Results, Notes/Impact on Daily Life.
Symptom
- Is a
Log delegated type (required) — the date lives on the Log
- Belongs to a SymptomType (required)
- Name (String, optional) — free-form symptom name, for when the type is "Other" or the user wants to be more specific
- Severity (Integer, optional) — 1 to 10
- Duration (String)
- Time of day (String)
- Possible triggers or trends (Text)
- Treatments and results (Text)
- Notes / impact on daily life (Text)
Relationships: Log, SymptomType
SymptomType
Lookup table. SymptomType has many symptoms.
-
Name (String)
-
Seeded from the journal's symptom list, plus "Other":
Pain, Fatigue or unusual tiredness, Fever/chills/night sweats, Unexplained weight loss or gain, Sleep changes, Dizziness/fainting/lightheadedness, Headaches or migraines, Confusion/memory problems/difficulty concentrating, Numbness/tingling/weakness/balance problems, Vision changes, Chest pain/pressure/tightness, Shortness of breath, Heart palpitations or irregular heartbeat, Swelling in legs/ankles/feet, Persistent cough or wheezing, Nausea/vomiting/loss of appetite, Diarrhea/constipation/changes in bowel habits, Blood in stool, Abdominal pain/bloating/cramping, Pain or burning with urination, Frequent or urgent urination, Blood in urine, Menstrual irregularities, Rashes/itching/hives, New or changing moles or skin lesions, Unusual hair loss or brittle nails, Persistent sadness/anxiety/irritability/mood swings, Loss of interest in activities, Thoughts of self-harm or hopelessness, Other
UI
Standard scaffolding for Symptom and SymptomType, plus the pieces that make a symptom entry visible from the log:
- Index — follows the same tabular presentation pattern as
app/views/prescriptions/index.html.erb. Copy that structure: the .table-scroll wrapper carrying tabindex="0", role="region" and an aria-label; <th scope="col"> headers; the first cell as <th scope="row"> linking to the show page; or_dash for optional values; table-note spans for secondary detail; and an empty-state paragraph when there are none. Columns: Date, Symptom, Severity, Duration, Time of day. Date order.
- Display — one Symptom value everywhere: the free-form name when set, otherwise the symptom type's name. Put that logic in a helper so the index, the show page and the log partial all agree.
- Register
Symptom in Log's delegated_type list so it appears in the log type selector.
- Add a partial in
app/views/symptoms/ that renders a symptom entry's details in a log context.
- Modify the Log index and show to render that partial, dispatching on the loggable type — the same mechanism the Appointment ticket establishes. Keep the generic fallback intact.
- Add SymptomType to
admin_sections in ApplicationHelper — it's reference data, same as medication types and forms.
Acceptance Criteria
- A user can add, view, edit and delete a symptom entry
- Saving requires a date and a symptom type
- The symptom type is selected from the seeded list
SymptomType is seeded and manageable, and appears on /admin
- Severity accepts 1 through 10 only, and may be left blank
- Symptom displays consistently across the index, the show page and the log partial: free-form name when set, else the type name
- The index matches the prescriptions index pattern: scrollable labelled region, scoped table headers, row header linking to show, dashes for blanks, empty state
- The long-form fields (triggers/trends, treatments and results, notes/impact) are optional and render in full on the show page
Symptom appears in the log type selector
- The log index and show render symptom details via the partial
- Log entries of a type with no partial still render via the fallback
- Model tests cover both models, the severity bounds, and the name-vs-type display
Notes
SymptomDefault is deliberately not modeled. The ERD carries it with Danny's note "Need to check this one. Not needed I think." — the decision is that it isn't needed. SymptomType is seeded directly, the same way MedicationType and AppointmentType are. Remove it from the ERD too.
- The journal groups its symptom list into categories (General; Neurological & Cognitive; Cardiovascular & Respiratory; Digestive; Urinary & Reproductive; Skin, Hair & Nails; Mental Health & Emotional). Those categories are not modeled here —
SymptomType is a flat list. If the picker turns out to be unwieldy at ~30 entries, grouping it is a follow-up, not this ticket.
- Seed names are shortened from the journal's phrasing, which carries guidance in parentheses (e.g. "Pain (location, intensity, frequency, what makes it better/worse)"). That guidance belongs in form hint text if we want it, not in the seeded name.
- The journal marks "Thoughts of self-harm or hopelessness" as urgent to report immediately. This ticket only stores it like any other symptom. Whether the app should do anything else when that entry is logged is a product decision that needs Danny and the client — do not invent a behaviour here.
Description
A symptom entry is a kind of log entry. It is a
Logdelegated type, and the Log carries the date. One row per dated observation, so the same symptom logged over a week is seven entries.Fields come from the journal's Symptom Log table (Section 3): Date, Severity (1 to 10), Duration, Time of Day, Possible Triggers or Trends Over Time, Treatments and Results, Notes/Impact on Daily Life.
Symptom
Logdelegated type (required) — the date lives on the LogRelationships: Log, SymptomType
SymptomType
Lookup table. SymptomType has many symptoms.
Name (String)
Seeded from the journal's symptom list, plus "Other":
Pain, Fatigue or unusual tiredness, Fever/chills/night sweats, Unexplained weight loss or gain, Sleep changes, Dizziness/fainting/lightheadedness, Headaches or migraines, Confusion/memory problems/difficulty concentrating, Numbness/tingling/weakness/balance problems, Vision changes, Chest pain/pressure/tightness, Shortness of breath, Heart palpitations or irregular heartbeat, Swelling in legs/ankles/feet, Persistent cough or wheezing, Nausea/vomiting/loss of appetite, Diarrhea/constipation/changes in bowel habits, Blood in stool, Abdominal pain/bloating/cramping, Pain or burning with urination, Frequent or urgent urination, Blood in urine, Menstrual irregularities, Rashes/itching/hives, New or changing moles or skin lesions, Unusual hair loss or brittle nails, Persistent sadness/anxiety/irritability/mood swings, Loss of interest in activities, Thoughts of self-harm or hopelessness, Other
UI
Standard scaffolding for Symptom and SymptomType, plus the pieces that make a symptom entry visible from the log:
app/views/prescriptions/index.html.erb. Copy that structure: the.table-scrollwrapper carryingtabindex="0",role="region"and anaria-label;<th scope="col">headers; the first cell as<th scope="row">linking to the show page;or_dashfor optional values;table-notespans for secondary detail; and an empty-state paragraph when there are none. Columns: Date, Symptom, Severity, Duration, Time of day. Date order.SymptominLog'sdelegated_typelist so it appears in the log type selector.app/views/symptoms/that renders a symptom entry's details in a log context.admin_sectionsinApplicationHelper— it's reference data, same as medication types and forms.Acceptance Criteria
SymptomTypeis seeded and manageable, and appears on/adminSymptomappears in the log type selectorNotes
SymptomDefaultis deliberately not modeled. The ERD carries it with Danny's note "Need to check this one. Not needed I think." — the decision is that it isn't needed.SymptomTypeis seeded directly, the same wayMedicationTypeandAppointmentTypeare. Remove it from the ERD too.SymptomTypeis a flat list. If the picker turns out to be unwieldy at ~30 entries, grouping it is a follow-up, not this ticket.