Description
Log is the shared parent for the dated, event-level records in the ERD: Appointment, Therapy, Vital Signs, Transportation Expense, Symptom. Each of those is its own model with its own fields. Log carries what they all have in common — the date — and gives us one dated timeline across all of them.
Implemented with Rails [delegated types](https://api.rubyonrails.org/classes/ActiveRecord/DelegatedType.html), not single-table inheritance.
Log
- Date (Date, required)
- Belongs to a Person (optional)
delegated_type :loggable, required
Relationships: Person, and each delegated type. Appointment is the first one.
UI
Standard Rails scaffolding, with the usual modifications we make for selecting relationships.
- Index — table of all log entries: Date, Type (the loggable type, in human-readable form), Person. Date order.
- Show — the log's own fields, plus the details of its loggable.
- New — step one is a type selector. Choosing a type routes to that type's own new form, which carries the log's date and person fields alongside the type's own. There is no form that saves a Log on its own — a Log requires a loggable, so the loggable is what gets created and it builds its Log.
- Edit — edits the loggable and its log fields together, same as the new form.
The type selector reads from the registered delegated_type list rather than a hard-coded list of types, so adding a type later is a one-line change.
Acceptance Criteria
logs table and Log model exist with date, person_id, loggable_type, loggable_id
delegated_type :loggable is declared
- A Log cannot be saved without a date
- A Log cannot be saved without a loggable
- A Log can be saved without a person
- Index lists logs in date order and shows each entry's type
- Show displays the log's date and person
- The new flow offers a type selector driven by the registered delegated types — it must not hard-code a list
- Index and show render sensibly for a log whose type has no view of its own yet (fall back to the type name)
- Model tests cover create, the date and loggable validations, the person-optional case, and the date-ordered listing
Notes
- Person is optional on purpose. Some log types won't logically need one. Some may end up requiring it — we'll deal with that per type later, not here.
- Chicken-and-egg with the Appointment ticket: a Log requires a loggable, so this ticket can't demonstrate a saved Log through the UI until at least one type exists. Model tests here use a test-only loggable defined in the suite; the first real end-to-end pass through the Log UI lands with the Appointment ticket. Don't block on Appointment, and don't stub a fake type into
app/.
- ERD note on this model: "Individual logs are presented as their own UI. Easy to allow contextual adds or general add (add a log and choose its type vs I'm looking at vitals and I add a vital log entry)." The type selector is the "general add" half. Contextual adds come with the individual type tickets.
- This blocks the Appointment ticket — land it first.
Description
Logis the shared parent for the dated, event-level records in the ERD: Appointment, Therapy, Vital Signs, Transportation Expense, Symptom. Each of those is its own model with its own fields.Logcarries what they all have in common — the date — and gives us one dated timeline across all of them.Implemented with Rails [delegated types](https://api.rubyonrails.org/classes/ActiveRecord/DelegatedType.html), not single-table inheritance.
Log
delegated_type :loggable, requiredRelationships: Person, and each delegated type. Appointment is the first one.
UI
Standard Rails scaffolding, with the usual modifications we make for selecting relationships.
The type selector reads from the registered
delegated_typelist rather than a hard-coded list of types, so adding a type later is a one-line change.Acceptance Criteria
logstable andLogmodel exist withdate,person_id,loggable_type,loggable_iddelegated_type :loggableis declaredNotes
app/.