Compare commits

..

3 commits

Author SHA1 Message Date
9c88993c13 Merge pull request 'Show voided transactions in user-entries endpoint' (#34) from feat/show-voided-user-entries into main
Reviewed-on: #34
2026-06-07 13:38:30 +00:00
781059af5f fix(dashboard): detect voided rows by tag, not by flag char
The admin transactions table assumed voided entries used flag='x', but
the libra reject convention keeps the '!' flag and appends a 'voided'
tag. Without this, the dashboard rendered voided rows as orange 'Pending'
once they started reaching it. Detect via tag and give the voided icon
precedence over the flag-based branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-06 20:47:42 +02:00
1c89e69030 feat(api): include voided transactions in user-entries endpoint
The /api/v1/entries/user view was silently dropping any transaction tagged
'voided', so users couldn't see entries that had been rejected against
their accounts. Per the libra reject convention, voided entries keep the
'!' flag and carry a 'voided' tag for audit; clients can use the tag to
style them distinctly. Pending-approval listing still filters voided.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-06 20:47:27 +02:00
3 changed files with 8 additions and 8 deletions

View file

@ -1707,6 +1707,10 @@ window.app = Vue.createApp({
if (entry.tags && entry.tags.includes('equity-contribution')) return true if (entry.tags && entry.tags.includes('equity-contribution')) return true
if (entry.account && entry.account.includes('Equity')) return true if (entry.account && entry.account.includes('Equity')) return true
return false return false
},
isVoided(entry) {
// Voided entries keep '!' flag and carry a 'voided' tag (libra convention).
return Array.isArray(entry.tags) && entry.tags.includes('voided')
} }
}, },
async created() { async created() {

View file

@ -497,7 +497,10 @@
<!-- Status Flag Column --> <!-- Status Flag Column -->
<template v-slot:body-cell-flag="props"> <template v-slot:body-cell-flag="props">
<q-td :props="props"> <q-td :props="props">
<q-icon v-if="props.row.flag === '*'" name="check_circle" color="positive" size="sm"> <q-icon v-if="isVoided(props.row)" name="cancel" color="grey" size="sm">
<q-tooltip>Voided</q-tooltip>
</q-icon>
<q-icon v-else-if="props.row.flag === '*'" name="check_circle" color="positive" size="sm">
<q-tooltip>Cleared</q-tooltip> <q-tooltip>Cleared</q-tooltip>
</q-icon> </q-icon>
<q-icon v-else-if="props.row.flag === '!'" name="pending" color="orange" size="sm"> <q-icon v-else-if="props.row.flag === '!'" name="pending" color="orange" size="sm">
@ -506,9 +509,6 @@
<q-icon v-else-if="props.row.flag === '#'" name="flag" color="red" size="sm"> <q-icon v-else-if="props.row.flag === '#'" name="flag" color="red" size="sm">
<q-tooltip>Flagged</q-tooltip> <q-tooltip>Flagged</q-tooltip>
</q-icon> </q-icon>
<q-icon v-else-if="props.row.flag === 'x'" name="cancel" color="grey" size="sm">
<q-tooltip>Voided</q-tooltip>
</q-icon>
</q-td> </q-td>
</template> </template>

View file

@ -487,10 +487,6 @@ async def api_get_user_entries(
if e.get("flag") in _SYNTHETIC_FLAGS: if e.get("flag") in _SYNTHETIC_FLAGS:
continue continue
# Skip voided transactions
if "voided" in e.get("tags", []):
continue
# Extract user ID from metadata or account names # Extract user ID from metadata or account names
user_id_match = None user_id_match = None
entry_meta = e.get("meta", {}) entry_meta = e.get("meta", {})