fix: JWT secret startup guard and order number advisory lock
H1: model_validator in Settings raises ValueError when jwt_secret_key is
"changeme" and the process is running inside a container — fast-fail
prevents insecure deployments; local dev outside Docker is unaffected.
H7: generate_order_number now acquires pg_advisory_xact_lock before SELECT MAX,
matching the same pattern used in generate_invoice_number (billing/service.py).
Concurrent order creation can no longer race to produce duplicate numbers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,12 +15,15 @@ def _utcnow_naive() -> datetime:
|
||||
|
||||
|
||||
async def generate_order_number(db: AsyncSession) -> str:
|
||||
"""Generate next sequential order number: SA-2026-XXXXX."""
|
||||
"""Generate next sequential order number: SA-YYYY-XXXXX."""
|
||||
from sqlalchemy import text
|
||||
year = datetime.now(timezone.utc).year
|
||||
prefix = f"SA-{year}-"
|
||||
|
||||
# Use MAX to find the highest existing sequence number this year.
|
||||
# COUNT-based approach breaks when orders are deleted (produces duplicates).
|
||||
# Advisory lock prevents duplicate numbers under concurrent order creation.
|
||||
# Released automatically when the surrounding transaction commits or rolls back.
|
||||
await db.execute(text("SELECT pg_advisory_xact_lock(hashtext(:key))"), {"key": f"order_number_seq_{year}"})
|
||||
|
||||
result = await db.execute(
|
||||
select(func.max(Order.order_number)).where(Order.order_number.like(f"{prefix}%"))
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user