fix: resolve architecture validation violations
- Add invoice exceptions module with proper exception hierarchy - Replace HTTPException with service-layer exceptions in invoice API - Add InvoicePDFGeneratedResponse and InvoiceStatsResponse Pydantic models - Replace db.commit() with db.flush() in services for proper transaction control - Update invoice service to use exceptions from app/exceptions/invoice.py All 14 errors and 14 warnings are now resolved. Validation passes with only INFO-level findings. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -97,7 +97,7 @@ class InvoicePDFService:
|
||||
# Update invoice record with PDF path and timestamp
|
||||
invoice.pdf_path = str(pdf_path)
|
||||
invoice.pdf_generated_at = datetime.now(UTC)
|
||||
db.commit()
|
||||
db.flush()
|
||||
|
||||
return str(pdf_path)
|
||||
|
||||
@@ -151,7 +151,7 @@ class InvoicePDFService:
|
||||
# Clear PDF fields
|
||||
invoice.pdf_path = None
|
||||
invoice.pdf_generated_at = None
|
||||
db.commit()
|
||||
db.flush()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -25,9 +25,17 @@ from sqlalchemy import and_, func
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.exceptions import (
|
||||
OrderNotFoundException,
|
||||
ValidationException,
|
||||
)
|
||||
from app.exceptions.invoice import (
|
||||
InvoiceNotFoundException,
|
||||
InvoicePDFGenerationException,
|
||||
InvoicePDFNotFoundException,
|
||||
InvoiceSettingsAlreadyExistException,
|
||||
InvoiceSettingsNotFoundException,
|
||||
InvoiceValidationException,
|
||||
OrderNotFoundException,
|
||||
)
|
||||
from models.database.invoice import (
|
||||
Invoice,
|
||||
InvoiceStatus,
|
||||
@@ -89,18 +97,6 @@ LU_VAT_RATES = {
|
||||
}
|
||||
|
||||
|
||||
class InvoiceNotFoundException(Exception):
|
||||
"""Raised when invoice not found."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class InvoiceSettingsNotFoundException(Exception):
|
||||
"""Raised when vendor invoice settings not found."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class InvoiceService:
|
||||
"""Service for invoice operations."""
|
||||
|
||||
@@ -205,9 +201,7 @@ class InvoiceService:
|
||||
"""Get vendor invoice settings or raise exception."""
|
||||
settings = self.get_settings(db, vendor_id)
|
||||
if not settings:
|
||||
raise InvoiceSettingsNotFoundException(
|
||||
f"Invoice settings not configured for vendor {vendor_id}"
|
||||
)
|
||||
raise InvoiceSettingsNotFoundException(vendor_id)
|
||||
return settings
|
||||
|
||||
def create_settings(
|
||||
@@ -229,7 +223,7 @@ class InvoiceService:
|
||||
**data.model_dump(),
|
||||
)
|
||||
db.add(settings)
|
||||
db.commit()
|
||||
db.flush()
|
||||
db.refresh(settings)
|
||||
|
||||
logger.info(f"Created invoice settings for vendor {vendor_id}")
|
||||
@@ -249,7 +243,7 @@ class InvoiceService:
|
||||
setattr(settings, key, value)
|
||||
|
||||
settings.updated_at = datetime.now(UTC)
|
||||
db.commit()
|
||||
db.flush()
|
||||
db.refresh(settings)
|
||||
|
||||
logger.info(f"Updated invoice settings for vendor {vendor_id}")
|
||||
@@ -278,7 +272,7 @@ class InvoiceService:
|
||||
is_vat_registered=bool(vendor.effective_tax_number),
|
||||
)
|
||||
db.add(settings)
|
||||
db.commit()
|
||||
db.flush()
|
||||
db.refresh(settings)
|
||||
|
||||
logger.info(f"Created invoice settings from vendor data for vendor {vendor.id}")
|
||||
@@ -435,7 +429,7 @@ class InvoiceService:
|
||||
)
|
||||
|
||||
db.add(invoice)
|
||||
db.commit()
|
||||
db.flush()
|
||||
db.refresh(invoice)
|
||||
|
||||
logger.info(
|
||||
@@ -465,7 +459,7 @@ class InvoiceService:
|
||||
"""Get invoice by ID or raise exception."""
|
||||
invoice = self.get_invoice(db, vendor_id, invoice_id)
|
||||
if not invoice:
|
||||
raise InvoiceNotFoundException(f"Invoice {invoice_id} not found")
|
||||
raise InvoiceNotFoundException(invoice_id)
|
||||
return invoice
|
||||
|
||||
def get_invoice_by_number(
|
||||
@@ -539,7 +533,7 @@ class InvoiceService:
|
||||
|
||||
invoice.status = new_status
|
||||
invoice.updated_at = datetime.now(UTC)
|
||||
db.commit()
|
||||
db.flush()
|
||||
db.refresh(invoice)
|
||||
|
||||
logger.info(f"Updated invoice {invoice.invoice_number} status to {new_status}")
|
||||
|
||||
@@ -163,7 +163,7 @@ class SubscriptionService:
|
||||
)
|
||||
|
||||
db.add(subscription)
|
||||
db.commit()
|
||||
db.flush()
|
||||
db.refresh(subscription)
|
||||
|
||||
logger.info(
|
||||
@@ -212,7 +212,7 @@ class SubscriptionService:
|
||||
)
|
||||
|
||||
db.add(subscription)
|
||||
db.commit()
|
||||
db.flush()
|
||||
db.refresh(subscription)
|
||||
|
||||
logger.info(f"Created subscription for vendor {vendor_id}: {data.tier}")
|
||||
@@ -232,7 +232,7 @@ class SubscriptionService:
|
||||
setattr(subscription, key, value)
|
||||
|
||||
subscription.updated_at = datetime.now(UTC)
|
||||
db.commit()
|
||||
db.flush()
|
||||
db.refresh(subscription)
|
||||
|
||||
logger.info(f"Updated subscription for vendor {vendor_id}")
|
||||
@@ -255,7 +255,7 @@ class SubscriptionService:
|
||||
if subscription.status == SubscriptionStatus.TRIAL.value:
|
||||
subscription.status = SubscriptionStatus.ACTIVE.value
|
||||
|
||||
db.commit()
|
||||
db.flush()
|
||||
db.refresh(subscription)
|
||||
|
||||
logger.info(f"Upgraded vendor {vendor_id} from {old_tier} to {new_tier}")
|
||||
@@ -275,7 +275,7 @@ class SubscriptionService:
|
||||
subscription.cancellation_reason = reason
|
||||
subscription.updated_at = datetime.now(UTC)
|
||||
|
||||
db.commit()
|
||||
db.flush()
|
||||
db.refresh(subscription)
|
||||
|
||||
logger.info(f"Cancelled subscription for vendor {vendor_id}")
|
||||
@@ -342,13 +342,13 @@ class SubscriptionService:
|
||||
"""
|
||||
subscription = self.get_or_create_subscription(db, vendor_id)
|
||||
subscription.increment_order_count()
|
||||
db.commit()
|
||||
db.flush()
|
||||
|
||||
def reset_period_counters(self, db: Session, vendor_id: int) -> None:
|
||||
"""Reset counters for a new billing period."""
|
||||
subscription = self.get_subscription_or_raise(db, vendor_id)
|
||||
subscription.reset_period_counters()
|
||||
db.commit()
|
||||
db.flush()
|
||||
logger.info(f"Reset period counters for vendor {vendor_id}")
|
||||
|
||||
# =========================================================================
|
||||
|
||||
Reference in New Issue
Block a user