fix(accounts): recover ledger-only account instead of blanket 409 (libra-#50)
When add_account reported the Open already existed, the endpoint raised 409 before the DB-mirror step — so an account present in the ledger but missing from libra's DB (a prior sync failure with no cross-DB atomicity, or an out-of-band open) was stranded: invisible to permissions with no recovery path. Now 409 only when the account is already in the DB too; otherwise sync it and return success. Adds a recovery test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
26eb9d4579
commit
39440b75a7
2 changed files with 48 additions and 5 deletions
27
views_api.py
27
views_api.py
|
|
@ -3750,14 +3750,31 @@ async def api_admin_add_chart_account(
|
|||
metadata=metadata,
|
||||
)
|
||||
|
||||
from .account_sync import sync_single_account_from_beancount
|
||||
|
||||
if result.get("already_existed"):
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.CONFLICT,
|
||||
detail=f"Account {payload.name} already exists",
|
||||
)
|
||||
# The Open directive is already in the ledger. If it's also already
|
||||
# mirrored into libra's DB, it's a true duplicate → 409. If not (a prior
|
||||
# sync failed — there's no cross-DB atomicity — or it was opened out of
|
||||
# band), mirror it now so it becomes grantable instead of being stranded
|
||||
# with no recovery path.
|
||||
from .crud import get_account_by_name
|
||||
|
||||
if await get_account_by_name(payload.name) is not None:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.CONFLICT,
|
||||
detail=f"Account {payload.name} already exists",
|
||||
)
|
||||
|
||||
synced = await sync_single_account_from_beancount(payload.name)
|
||||
return {
|
||||
"success": True,
|
||||
"account_name": payload.name,
|
||||
"synced_to_libra_db": synced,
|
||||
"already_existed": True,
|
||||
}
|
||||
|
||||
# Mirror into libra DB so permissions / metadata layer sees it.
|
||||
from .account_sync import sync_single_account_from_beancount
|
||||
synced = await sync_single_account_from_beancount(payload.name)
|
||||
|
||||
return {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue