senior's post-demo changes: parent report in the student's own account, Jalali birth date, invoices, math-only tutor, priced quotas
- remove the family app from the root (separate parent accounts, invite codes, parental settings); progress.0006 drops its tables, permissions and migration history, and Profile.parent_phone, the two family notification types and ?userId= on /api/progress/nodes go with it - GET /api/user/weekly-report: last 7 days next to the 7 before (estimated minutes, questions, accuracy, islands, tutor questions) for the "parent report" page - profile birthDate in Jalali (accounts/jalali.py), ages 5-99, birthYear derived from it - GET /api/payment/invoices; orders now snapshot list price and plan title - tutor answers only math: server pre-filter, scope rule in the prompt (tutor-v11), refusal marker replaced with fixed text; self-harm gets a help line instead - streamed answers now record token usage (it was always 0) - daily tutor quota: AI_DAILY_QUOTA_FREE (default 3) vs Plan.ai_daily_quota - delete_users management command for wiping test accounts across every app - docs/ai-cost-and-guardrails.md: measured cost per question and guardrail results Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
# Generated by Django 5.2.17 on 2026-10-01 21:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
# اعلانهای بخشِ والدین (اتصالِ خانواده، گزارشِ هفتگیِ والد) که ۲۰۲۶-۱۰-۰۱ حذف شد.
|
||||
# نوعشان دیگر در choices نیست، پس ردیفهای قدیمی هم پاک میشوند تا در اپ اعلانِ
|
||||
# بیمعنا («فرزندت دعوت را پذیرفت») نماند.
|
||||
FAMILY_TYPES = ('family_link_accepted', 'weekly_report_ready')
|
||||
|
||||
|
||||
def delete_family_notifications(apps, schema_editor):
|
||||
apps.get_model('notifications', 'Notification').objects.filter(type__in=FAMILY_TYPES).delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('notifications', '0002_alter_notification_type'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(delete_family_notifications, migrations.RunPython.noop),
|
||||
migrations.AlterField(
|
||||
model_name='notification',
|
||||
name='type',
|
||||
field=models.CharField(choices=[('xp_earned', 'امتیاز گرفتی'), ('lesson_completed', 'درس تکمیل شد'), ('node_completed', 'جزیره تمام شد'), ('order_paid', 'پرداخت موفق'), ('ticket_replied', 'پاسخ تیکت')], max_length=30),
|
||||
),
|
||||
]
|
||||
@@ -5,15 +5,13 @@ class Notification(models.Model):
|
||||
# انواع رویدادهایی که این اپ فقط بهشون گوش میده (event-listener)؛
|
||||
# خودش تولیدکنندهی رویداد نیست. طبق سند معماری:
|
||||
# LessonCompleted/XPEarned (Progress), OrderPaid (Payment),
|
||||
# TicketReplied (Support), FamilyLinkAccepted/WeeklyReportReady (Family)
|
||||
# TicketReplied (Support).
|
||||
TYPE_CHOICES = [
|
||||
('xp_earned', 'امتیاز گرفتی'),
|
||||
('lesson_completed', 'درس تکمیل شد'),
|
||||
('node_completed', 'جزیره تمام شد'),
|
||||
('order_paid', 'پرداخت موفق'),
|
||||
('ticket_replied', 'پاسخ تیکت'),
|
||||
('family_link_accepted', 'اتصال خانواده تأیید شد'),
|
||||
('weekly_report_ready', 'گزارش هفتگی آماده شد'),
|
||||
]
|
||||
|
||||
user_id = models.IntegerField(db_index=True) # ارجاع سبک به accounts.User
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
اپ Notifications برخلاف بقیهی اپها به هیچ اپی رفرنس سبک نمیده و خودش
|
||||
تولیدکنندهی رویداد نیست؛ فقط event-listenerه (طبق سند معماری داده).
|
||||
چون این پروژه یک مونولیت جنگوییه، «گوش دادن به رویداد» با یک تابع کمکی
|
||||
پیادهسازی شده که سایر اپها (Progress، Payment، Support، Family) مستقیماً
|
||||
پیادهسازی شده که سایر اپها (Progress، Payment، Support) مستقیماً
|
||||
از این ماژول import و صدا میزنن — دقیقاً همون الگوی call_payment_gateway
|
||||
در payment/services.py و create_order که سرور-به-سرور از subscription
|
||||
صدا زده میشه.
|
||||
|
||||
Reference in New Issue
Block a user