# journalLinesGroupedByEntryId

## Overview

Returns a company's journal lines as flat rows joined to their journal entry and GL account, grouped by `journalEntryId` — each entry's lines come back contiguously so a table UI can render them under their entry. Because the built-in `journalLines` / `journalEntries` collection queries each filter only one entity, this resolver inner-joins `JournalLine` → `JournalEntry` → `Account` and applies filters across the join: entry-level (`status`, `accountingPeriodId`, `entryDate` range, `sourceDocumentType`, `sourceDocumentId`) and line-level (`accountId` — entries that have a line posted to that account; and `descriptionContains` — a case-insensitive substring match on a line's description). The line-level filters return whole entries that have at least one matching line (intersected when combined). Rows are ordered by the entry: the requested field (`entryDate` or `createdAt`, asc/desc), then `createdAt` as a tiebreaker in the same direction (since `entryDate` is date-granular, many entries share a date — within a date the most recently created entry sorts first under `desc`), then `id` for determinism.

Pagination is by **entry**, not by line: a journal entry is a balanced unit (Σdebit = Σcredit), so `limit`/`offset` page over entries and every page returns whole entries' lines, kept contiguous per `journalEntryId`. This avoids splitting an entry across a page boundary (which would show a meaningless, unbalanced half-entry). `hasNextPage` indicates whether more entries follow, `entryCount` is the number of entries on this page, and `total` is the count of all matching entries across every page (so the client can number entries — under the default descending order the newest entry is `#total`).

## Modules Commands Used

- (none) — a read-only join over `JournalLine` / `JournalEntry` / `Account`; issues no module command. The `accountId` filter is resolved as a two-step `id IN (...)` lookup (TailorDB's SQL layer has no DISTINCT / correlated subqueries).

## Exception Handling

| Error Code | Description |
| --- | --- |
| N/A (validation) | Thrown for an invalid `status`, `sourceDocumentType`, `orderBy`, or `orderDirection` value |
| N/A | Read-only; returns an empty result when no entries match |
