- **The message profile's readers.** A message between a world's members is a Narrative with supertype `Message`, from its `narrator` to its `characters`. `is_message(element)` reads the pair (`MESSAGE_PAIR`), trimmed and folded as `is_room_element` folds the room's pairs; a parlor's line and a world's own message are both messages. `recipients_of(message)` lists the `characters`, and `is_addressed_to(message, character_id)` is true when the id is among them or the list is empty, absent or `None`, which addresses everyone; a list that names no valid id, or a value that is not a list, addresses nobody, never everyone; nothing else addresses a message, not the `narrator`, not a name in the `story`, not `protagonist`. `is_sent_by(message, character_id)` reads the `narrator`, the claimed sender. `sender_status(message, members)` checks the claim against who wrote the element: its `created_by` on the world's members list (`None` is the owner), and answers a `SenderRead` with `status` `verified`, `mismatch` (with `written_by`, the author's Character) or `unverifiable` (no `narrator`, no `created_by` at all, no members list, the author not on it or playing no Character), and `claimed`, the `narrator`. `read_mark_of(relations, character_id, members)` finds a reader's read mark, a Relation with supertype `Read` (`READ_MARK_PAIR`) whose `actor` is the reader: only a mark written by the reader's own hand counts (a relation with no `created_by` at all, from a folder or an export, has no hand to check and counts), the newest `updated_at` when several do. `unread_for(messages, character_id, read_mark)` is the messages addressed to the reader, not sent by it and not on its mark. `thread_of(messages, root_id)`, which the profile's page does not list, is every message whose chain of `parent_narrative` reaches the root, the root included, a loop of parents ending. Every list comes back in `created_at` order, two equal times keeping the order given, never by id. The profile's fixture (43 cases) runs as a test.
0 commit comments