boot running without errors

This commit is contained in:
patrick-motsch 2026-02-04 22:34:41 +01:00
parent fd923b89b8
commit d5226a5599
3 changed files with 77 additions and 77 deletions

View file

@ -92,11 +92,11 @@ class BillingObjects:
def _initializeDatabase(self):
"""Initialize database connection."""
self.db = DatabaseConnector(
databaseName=BILLING_DATABASE,
host=APP_CONFIG.get('Database_Host', 'localhost'),
port=int(APP_CONFIG.get('Database_Port', '5432')),
user=APP_CONFIG.get('Database_User', 'admin'),
password=APP_CONFIG.get('Database_Password', 'admin')
dbDatabase=BILLING_DATABASE,
dbHost=APP_CONFIG.get('DB_HOST', 'localhost'),
dbPort=int(APP_CONFIG.get('DB_PORT', '5432')),
dbUser=APP_CONFIG.get('DB_USER'),
dbPassword=APP_CONFIG.get('DB_PASSWORD_SECRET')
)
def setUserContext(self, currentUser: User, mandateId: str = None):
@ -128,7 +128,7 @@ class BillingObjects:
try:
results = self.db.getRecordset(
BillingSettings,
filterDict={"mandateId": mandateId}
recordFilter={"mandateId": mandateId}
)
return results[0] if results else None
except Exception as e:
@ -200,7 +200,7 @@ class BillingObjects:
try:
results = self.db.getRecordset(
BillingAccount,
filterDict={"id": accountId}
recordFilter={"id": accountId}
)
return results[0] if results else None
except Exception as e:
@ -220,7 +220,7 @@ class BillingObjects:
try:
results = self.db.getRecordset(
BillingAccount,
filterDict={
recordFilter={
"mandateId": mandateId,
"accountType": AccountTypeEnum.MANDATE.value
}
@ -244,7 +244,7 @@ class BillingObjects:
try:
results = self.db.getRecordset(
BillingAccount,
filterDict={
recordFilter={
"mandateId": mandateId,
"userId": userId,
"accountType": AccountTypeEnum.USER.value
@ -255,6 +255,25 @@ class BillingObjects:
logger.error(f"Error getting user account: {e}")
return None
def getAccountsByMandate(self, mandateId: str) -> List[Dict[str, Any]]:
"""
Get all billing accounts for a mandate.
Args:
mandateId: Mandate ID
Returns:
List of BillingAccount dicts
"""
try:
return self.db.getRecordset(
BillingAccount,
recordFilter={"mandateId": mandateId}
)
except Exception as e:
logger.error(f"Error getting accounts for mandate: {e}")
return []
def createAccount(self, account: BillingAccount) -> Dict[str, Any]:
"""
Create a new billing account.
@ -405,7 +424,7 @@ class BillingObjects:
"""
try:
filterDict = {"accountId": accountId}
results = self.db.getRecordset(BillingTransaction, filterDict=filterDict)
results = self.db.getRecordset(BillingTransaction, recordFilter=filterDict)
# Apply date filters if provided
if startDate or endDate:
@ -442,7 +461,7 @@ class BillingObjects:
List of transaction dicts
"""
# Get all accounts for mandate
accounts = self.db.getRecordset(BillingAccount, filterDict={"mandateId": mandateId})
accounts = self.db.getRecordset(BillingAccount, recordFilter={"mandateId": mandateId})
allTransactions = []
for account in accounts:
@ -616,7 +635,7 @@ class BillingObjects:
"periodType": periodType.value
}
results = self.db.getRecordset(UsageStatistics, filterDict=filterDict)
results = self.db.getRecordset(UsageStatistics, recordFilter=filterDict)
# Filter by year
filtered = [s for s in results if s.get("periodStart") and s["periodStart"].year == year]

View file

@ -136,11 +136,11 @@ async def getBalance(
raise HTTPException(status_code=500, detail=str(e))
@router.get("/balance/{mandateId}", response_model=BillingBalanceResponse)
@router.get("/balance/{targetMandateId}", response_model=BillingBalanceResponse)
@limiter.limit("60/minute")
async def getBalanceForMandate(
request: Request,
mandateId: str = Path(..., description="Mandate ID"),
targetMandateId: str = Path(..., description="Mandate ID"),
ctx: RequestContext = Depends(getRequestContext)
):
"""
@ -149,7 +149,7 @@ async def getBalanceForMandate(
try:
billingService = getBillingService(
ctx.currentUser,
mandateId,
targetMandateId,
featureCode="billing"
)
@ -158,12 +158,12 @@ async def getBalanceForMandate(
# Get mandate name from app interface
from modules.interfaces.interfaceDbApp import getInterface as getAppInterface
appInterface = getAppInterface(ctx.currentUser, mandateId=mandateId)
mandate = appInterface.getMandate(mandateId)
appInterface = getAppInterface(ctx.currentUser, mandateId=targetMandateId)
mandate = appInterface.getMandate(targetMandateId)
mandateName = mandate.get("name", "") if mandate else ""
return BillingBalanceResponse(
mandateId=mandateId,
mandateId=targetMandateId,
mandateName=mandateName,
billingModel=checkResult.billingModel or BillingModelEnum.UNLIMITED,
balance=checkResult.currentBalance or 0.0,
@ -173,7 +173,7 @@ async def getBalanceForMandate(
)
except Exception as e:
logger.error(f"Error getting billing balance for mandate {mandateId}: {e}")
logger.error(f"Error getting billing balance for mandate {targetMandateId}: {e}")
raise HTTPException(status_code=500, detail=str(e))
@ -332,20 +332,20 @@ async def getAllowedProviders(
# Admin Endpoints
# =============================================================================
@router.get("/admin/settings/{mandateId}", response_model=Dict[str, Any])
@router.get("/admin/settings/{targetMandateId}", response_model=Dict[str, Any])
@limiter.limit("30/minute")
@requireSysAdmin
async def getSettingsAdmin(
request: Request,
mandateId: str = Path(..., description="Mandate ID"),
ctx: RequestContext = Depends(getRequestContext)
targetMandateId: str = Path(..., description="Mandate ID"),
ctx: RequestContext = Depends(getRequestContext),
_admin = Depends(requireSysAdmin)
):
"""
Get billing settings for a mandate (SysAdmin only).
"""
try:
billingInterface = getBillingInterface(ctx.currentUser, mandateId)
settings = billingInterface.getSettings(mandateId)
billingInterface = getBillingInterface(ctx.currentUser, targetMandateId)
settings = billingInterface.getSettings(targetMandateId)
if not settings:
raise HTTPException(status_code=404, detail="Billing settings not found")
@ -359,21 +359,21 @@ async def getSettingsAdmin(
raise HTTPException(status_code=500, detail=str(e))
@router.post("/admin/settings/{mandateId}", response_model=Dict[str, Any])
@router.post("/admin/settings/{targetMandateId}", response_model=Dict[str, Any])
@limiter.limit("10/minute")
@requireSysAdmin
async def createOrUpdateSettings(
request: Request,
mandateId: str = Path(..., description="Mandate ID"),
targetMandateId: str = Path(..., description="Mandate ID"),
settingsUpdate: BillingSettingsUpdate = Body(...),
ctx: RequestContext = Depends(getRequestContext)
ctx: RequestContext = Depends(getRequestContext),
_admin = Depends(requireSysAdmin)
):
"""
Create or update billing settings for a mandate (SysAdmin only).
"""
try:
billingInterface = getBillingInterface(ctx.currentUser, mandateId)
existingSettings = billingInterface.getSettings(mandateId)
billingInterface = getBillingInterface(ctx.currentUser, targetMandateId)
existingSettings = billingInterface.getSettings(targetMandateId)
if existingSettings:
# Update existing settings
@ -387,7 +387,7 @@ async def createOrUpdateSettings(
from modules.datamodels.datamodelBilling import BillingSettings
newSettings = BillingSettings(
mandateId=mandateId,
mandateId=targetMandateId,
billingModel=settingsUpdate.billingModel or BillingModelEnum.UNLIMITED,
defaultUserCredit=settingsUpdate.defaultUserCredit or 10.0,
warningThresholdPercent=settingsUpdate.warningThresholdPercent or 10.0,
@ -406,14 +406,14 @@ async def createOrUpdateSettings(
raise HTTPException(status_code=500, detail=str(e))
@router.post("/admin/credit/{mandateId}", response_model=Dict[str, Any])
@router.post("/admin/credit/{targetMandateId}", response_model=Dict[str, Any])
@limiter.limit("10/minute")
@requireSysAdmin
async def addCredit(
request: Request,
mandateId: str = Path(..., description="Mandate ID"),
targetMandateId: str = Path(..., description="Mandate ID"),
creditRequest: CreditAddRequest = Body(...),
ctx: RequestContext = Depends(getRequestContext)
ctx: RequestContext = Depends(getRequestContext),
_admin = Depends(requireSysAdmin)
):
"""
Add credit to a billing account (SysAdmin only).
@ -421,8 +421,8 @@ async def addCredit(
"""
try:
# Get settings to determine billing model
billingInterface = getBillingInterface(ctx.currentUser, mandateId)
settings = billingInterface.getSettings(mandateId)
billingInterface = getBillingInterface(ctx.currentUser, targetMandateId)
settings = billingInterface.getSettings(targetMandateId)
if not settings:
raise HTTPException(status_code=404, detail="Billing settings not found for this mandate")
@ -436,13 +436,13 @@ async def addCredit(
# Create user-level account if needed and add credit
account = billingInterface.getOrCreateUserAccount(
mandateId,
targetMandateId,
creditRequest.userId,
initialBalance=0.0
)
elif billingModel in [BillingModelEnum.PREPAY_MANDATE, BillingModelEnum.CREDIT_POSTPAY]:
# Create mandate-level account if needed and add credit
account = billingInterface.getOrCreateMandateAccount(mandateId, initialBalance=0.0)
account = billingInterface.getOrCreateMandateAccount(targetMandateId, initialBalance=0.0)
else:
raise HTTPException(status_code=400, detail=f"Cannot add credit to {billingModel.value} billing model")
@ -459,7 +459,7 @@ async def addCredit(
result = billingInterface.createTransaction(transaction)
logger.info(f"Added {creditRequest.amount} CHF credit to account {account['id']} in mandate {mandateId}")
logger.info(f"Added {creditRequest.amount} CHF credit to account {account['id']} in mandate {targetMandateId}")
return result
@ -470,34 +470,22 @@ async def addCredit(
raise HTTPException(status_code=500, detail=str(e))
@router.get("/admin/accounts/{mandateId}", response_model=List[AccountSummary])
@router.get("/admin/accounts/{targetMandateId}", response_model=List[AccountSummary])
@limiter.limit("30/minute")
@requireSysAdmin
async def getAccounts(
request: Request,
mandateId: str = Path(..., description="Mandate ID"),
ctx: RequestContext = Depends(getRequestContext)
targetMandateId: str = Path(..., description="Mandate ID"),
ctx: RequestContext = Depends(getRequestContext),
_admin = Depends(requireSysAdmin)
):
"""
Get all billing accounts for a mandate (SysAdmin only).
"""
try:
billingInterface = getBillingInterface(ctx.currentUser, mandateId)
billingInterface = getBillingInterface(ctx.currentUser, targetMandateId)
# Get all accounts for this mandate
from modules.connectors.connectorDbPostgre import DatabaseConnector
from modules.shared.configuration import APP_CONFIG
from modules.datamodels.datamodelBilling import BillingAccount
db = DatabaseConnector(
databaseName="poweron_billing",
host=APP_CONFIG.get('Database_Host', 'localhost'),
port=int(APP_CONFIG.get('Database_Port', '5432')),
user=APP_CONFIG.get('Database_User', 'admin'),
password=APP_CONFIG.get('Database_Password', 'admin')
)
accounts = db.getRecordset(BillingAccount, filterDict={"mandateId": mandateId})
# Get all accounts for this mandate via interface
accounts = billingInterface.getAccountsByMandate(targetMandateId)
result = []
for acc in accounts:
@ -519,21 +507,21 @@ async def getAccounts(
raise HTTPException(status_code=500, detail=str(e))
@router.get("/admin/transactions/{mandateId}", response_model=List[TransactionResponse])
@router.get("/admin/transactions/{targetMandateId}", response_model=List[TransactionResponse])
@limiter.limit("30/minute")
@requireSysAdmin
async def getTransactionsAdmin(
request: Request,
mandateId: str = Path(..., description="Mandate ID"),
targetMandateId: str = Path(..., description="Mandate ID"),
limit: int = Query(default=100, ge=1, le=1000),
ctx: RequestContext = Depends(getRequestContext)
ctx: RequestContext = Depends(getRequestContext),
_admin = Depends(requireSysAdmin)
):
"""
Get all transactions for a mandate (SysAdmin only).
"""
try:
billingInterface = getBillingInterface(ctx.currentUser, mandateId)
transactions = billingInterface.getTransactionsByMandate(mandateId, limit=limit)
billingInterface = getBillingInterface(ctx.currentUser, targetMandateId)
transactions = billingInterface.getTransactionsByMandate(targetMandateId, limit=limit)
result = []
for t in transactions:
@ -553,5 +541,5 @@ async def getTransactionsAdmin(
return result
except Exception as e:
logger.error(f"Error getting billing transactions for mandate {mandateId}: {e}")
logger.error(f"Error getting billing transactions for mandate {targetMandateId}: {e}")
raise HTTPException(status_code=500, detail=str(e))

View file

@ -255,17 +255,10 @@ class BillingService:
try:
from modules.security.rbac import RbacClass
from modules.datamodels.datamodelRbac import AccessRuleContext
from modules.connectors.connectorDbPostgre import DatabaseConnector
from modules.shared.configuration import APP_CONFIG
from modules.security.rootAccess import getRootDbAppConnector
# Get database connectors
dbApp = DatabaseConnector(
databaseName="poweron_app",
host=APP_CONFIG.get('Database_Host', 'localhost'),
port=int(APP_CONFIG.get('Database_Port', '5432')),
user=APP_CONFIG.get('Database_User', 'admin'),
password=APP_CONFIG.get('Database_Password', 'admin')
)
# Get database connector via established pattern
dbApp = getRootDbAppConnector()
rbac = RbacClass(dbApp, dbApp)
resourceKey = f"resource.aicore.{provider}"