JournalEntry.flag in API response misreports receivable/revenue as PENDING #35

Open
opened 2026-06-06 21:16:26 +00:00 by padreug · 0 comments
Owner

What

The JournalEntry response objects returned by some admin entry endpoints carry flag=PENDING, but the actual Beancount transaction written via Fava uses * (cleared) and is immediately reflected in BQL balances.

Specifically POST /api/v1/entries/receivable (views_api.py:1334+) returns:

return JournalEntry(
    id=entry_id,
    ...,
    flag=JournalEntryFlag.PENDING,  # ← misleading
    ...
)

while the underlying entry is constructed by format_receivable_entry in beancount_format.py with:

return format_transaction(
    ...,
    flag="*",  # Receivables are immediately cleared (approved)
    ...
)

Why it's confusing

A client reading the response would reasonably assume the entry needs an approval step (POST /entries/{id}/approve). That call then 404s with "Pending entry not found in Beancount ledger" because there is no pending entry — the on-disk one is already *. Surfaced during integration-test development: a test that posted a receivable and then tried to approve it failed because the entry was already cleared.

Fix

Return the actual flag the Beancount entry was written with. Either:

  1. Derive the flag from a single source of truth (e.g. format_receivable_entry returns the flag it used, the endpoint echoes it).
  2. Hardcode flag=JournalEntryFlag.CLEARED in the receivable and revenue endpoint responses to match what format_receivable_entry / format_revenue_entry write.

Then audit the other admin entry endpoints (/entries/revenue, possibly /entries) for the same pattern.

Scope

  • views_api.py:1334+ (receivable endpoint response)
  • views_api.py:1541+ (revenue endpoint response — already returns CLEARED; verify)
  • Any other entry endpoints whose response flag is hardcoded rather than reflecting format_*_entry's output.

Small fix, but it's the kind of doc-vs-code drift that wastes test- and integration-author time.

## What The `JournalEntry` response objects returned by some admin entry endpoints carry `flag=PENDING`, but the actual Beancount transaction written via Fava uses `*` (cleared) and is immediately reflected in BQL balances. Specifically `POST /api/v1/entries/receivable` (`views_api.py:1334+`) returns: ```python return JournalEntry( id=entry_id, ..., flag=JournalEntryFlag.PENDING, # ← misleading ... ) ``` while the underlying entry is constructed by `format_receivable_entry` in `beancount_format.py` with: ```python return format_transaction( ..., flag="*", # Receivables are immediately cleared (approved) ... ) ``` ## Why it's confusing A client reading the response would reasonably assume the entry needs an approval step (`POST /entries/{id}/approve`). That call then 404s with "Pending entry not found in Beancount ledger" because there is no pending entry — the on-disk one is already `*`. Surfaced during integration-test development: a test that posted a receivable and then tried to approve it failed because the entry was already cleared. ## Fix Return the actual flag the Beancount entry was written with. Either: 1. Derive the flag from a single source of truth (e.g. `format_receivable_entry` returns the flag it used, the endpoint echoes it). 2. Hardcode `flag=JournalEntryFlag.CLEARED` in the receivable and revenue endpoint responses to match what `format_receivable_entry` / `format_revenue_entry` write. Then audit the other admin entry endpoints (`/entries/revenue`, possibly `/entries`) for the same pattern. ## Scope - `views_api.py:1334+` (receivable endpoint response) - `views_api.py:1541+` (revenue endpoint response — already returns CLEARED; verify) - Any other entry endpoints whose response `flag` is hardcoded rather than reflecting `format_*_entry`'s output. Small fix, but it's the kind of doc-vs-code drift that wastes test- and integration-author time.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiolabs/libra#35
No description provided.