Remove silent fallbacks found in the 2026-10-03 audit
- /api/ai/ask: the stub answer is reachable only under DEBUG or RAG_FORCE_MOCK. Without RAG keys on the server it used to return 200 with "this is a stub, set OPENAI_API_KEY" and spend the student's quota; now 503. - /api/home: the `grade` alias is gone and sending it is a 400 instead of a silent fallback to the user's own grade. No client sent it. - activate_subscription logs ERROR when the paid order's plan no longer exists (it silently became 30 days). - resolve_grade_title logs instead of `except: pass`; curriculum_io no longer reads an `intro_text` key no file contains. - CLAUDE.md: "No silent fallbacks" rules for future agents. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import logging
|
||||
|
||||
from django.db import models, transaction
|
||||
from django.utils import timezone
|
||||
|
||||
@@ -5,6 +7,8 @@ from statuslog.signals import status_changed
|
||||
|
||||
from .models import HeartsPass, QuestionCredit, Subscription
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def has_unlimited_hearts(user_id: int) -> bool:
|
||||
"""
|
||||
@@ -126,6 +130,11 @@ def activate_subscription(subscription_id: int, plan_id: int | None = None):
|
||||
return None
|
||||
old_status = subscription.status
|
||||
plan = Plan.objects.filter(pk=plan_id).first() if plan_id else None
|
||||
if plan_id and plan is None:
|
||||
# پلنِ سفارشِ پرداختشده پاک شده؛ جایگزین (پلنِ Subscription یا ۳۰ روز)
|
||||
# ممکن است کمتر از آنچه خریده شده باشد. کاربر بیاشتراک نمیماند، ولی
|
||||
# باید دیده شود. پلن را پاک نکنید؛ on_sale=False کنید.
|
||||
logger.error('activate_subscription: پلنِ %s برای اشتراکِ %s پیدا نشد', plan_id, subscription_id)
|
||||
plan = plan or subscription.plan
|
||||
duration_days = plan.duration_days if plan else 30
|
||||
now = timezone.now()
|
||||
|
||||
Reference in New Issue
Block a user