Earlier migrations moved data to new directories without updating JSON
fields. Now consistently derives all IDs from file paths:
- Projects: id from filename
- Sessions: id from filename, projectID from parent directory
- Messages: id from filename, sessionID from parent directory
- Parts: id from filename, messageID from parent directory
This ensures migrated data matches the actual file layout regardless of
stale values in JSON content.
Adds test cases for filtering sessions by directory, root sessions only,
start time, search terms, and result limits to ensure the listing
functionality works correctly for all filter combinations.