Debt and Borrowing
Schedule over-budget with borrowing, then repay debt
01
Sample Code
from uuid import uuid4
from datetime import date, datetime, UTC
from psp.components.budget.domain import (
TokenType, BudgetPlan, Period, PeriodType,
DebtObligation, DebtStatus, EnforcementPolicy,
)
from psp.components.budget.adapters.persistence import (
InMemoryTokenTypeRepository,
InMemoryBudgetPlanRepository,
InMemoryDebtObligationRepository,
)
# Setup
token_repo = InMemoryTokenTypeRepository()
plan_repo = InMemoryBudgetPlanRepository()
debt_repo = InMemoryDebtObligationRepository()
owner_id = uuid4()
now = datetime.now(UTC)
# Create token type and plan with auto_borrow
deep = TokenType(id=uuid4(), owner_id=owner_id, name="deep")
token_repo.save(deep)
plan = BudgetPlan(
id=uuid4(),
owner_id=owner_id,
period_type=PeriodType.DAY,
effective_from=date.today(),
allocations={deep.id: 4},
enforcement_policy=EnforcementPolicy.AUTO_BORROW,
)
plan_repo.save(plan)
print(f"Plan allows auto-borrow, allocation: {plan.allocations[deep.id]}")
# Create debt (simulating over-budget scheduling)
period = Period.today(PeriodType.DAY)
debt = DebtObligation(
id=uuid4(),
owner_id=owner_id,
token_type_id=deep.id,
source_period=period,
original_amount=2, # Borrowed 2 extra tokens
remaining_amount=2,
)
debt_repo.save(debt)
print(f"Created debt: {debt.original_amount} tokens borrowed")
# Repay part of debt
repaid = debt.repay(1, now)
debt_repo.save(repaid)
print(f"Repaid 1, remaining: {repaid.remaining_amount}, status: {repaid.status.value}")
# Repay rest
fully_repaid = repaid.repay(1, now)
debt_repo.save(fully_repaid)
print(f"Fully repaid, status: {fully_repaid.status.value}")