write down the frontend test account, which existed only in one person's notes

A shared guest account was hand-seeded into the production DB on 2026-09-22 so
the frontend developer could see the notification and leaderboard screens before
any real traffic exists: deviceId "frontend-test-device", user 6, with 24
Notification rows and 20 LeaderboardEntry rows across both periods, ordered
differently per period so the ?period= parameter is visibly doing something.

None of that was recorded in the repo. db.sqlite3 is gitignored, so the account
existed only in the head of whoever set it up — exactly the kind of thing that
disappears at a handoff. It is now in docs/frontend/README.md, where the
frontend developer looks, and in docs/operations.md, where whoever runs the
server looks.

Verified against production before writing it down: the account still resolves
to user 6 with isNewUser false, notifications return rows, and both leaderboard
periods return six entries. The notifications payload is keyed "items", not
"results", which is noted because it is easy to read as an empty response.

The operations entry carries the warning that matters: this is hand-written data
in a production database, purge_demo_data will not catch it (it only matches
[SEED]/[DEMO] prefixes on Grade/Plan/Character/User), and it has to go before
real users arrive or they will see invented notifications.

The Swagger description now says a deviceId can be any string and that
pre-seeded ones exist on request, but deliberately does not print the specific
value: /api/docs/ is reachable from the public internet, and a public API
reference should not advertise a shared account that anyone can sign into.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-23 01:55:16 +03:30
parent ac3999ea92
commit 5003b8a852
3 changed files with 53 additions and 0 deletions

View File

@@ -456,6 +456,11 @@ SPECTACULAR_SETTINGS = {
'دارد. توکنِ دسترسی یک ساعت اعتبار دارد؛ با `POST /api/auth/refresh` '
'تازه‌اش کنید.\n'
'\n'
'`deviceId` هر رشته‌ای می‌تواند باشد و هر مقدارِ تازه یک حسابِ جدا '
'می‌سازد، پس برای تست لازم نیست منتظرِ چیزی بمانید. چند `deviceId` '
'از پیش‌آماده هم برای دیدنِ صفحه‌های داده‌دار وجود دارد — از تیمِ '
'بک‌اند بخواهید.\n'
'\n'
'**در همین صفحه:** روی **Authorize** بزنید و *فقط خودِ توکن* را وارد '
'کنید — کلمه‌ی `Bearer` را Swagger خودش اضافه می‌کند.\n'
'\n'

View File

@@ -53,6 +53,29 @@ export const api = createClient({ baseUrl: import.meta.env.VITE_API_URL ?? '/api
> کدِ شماره‌ی تست در پاسخِ API برنمی‌گردد. اگر `devOtp` خالی آمد، یعنی همین
> مسیر فعال است، نه اینکه چیزی خراب باشد.
**یک حسابِ تستِ آماده هم روی پروداکشن هست** که از قبل داده دارد، تا برای دیدنِ
صفحه‌های اعلان و لیدربرد مجبور نباشید منتظرِ تولیدِ داده‌ی واقعی بمانید:
```bash
curl -X POST https://api.math.tadrisino2.ir/api/auth/session \
-H 'Content-Type: application/json' \
-d '{"type":"guest","deviceId":"frontend-test-device"}'
```
- کاربرِ شماره‌ی ۶، با نامِ «حساب تست فرانت». هیچ پیامکی و هیچ توکنی که دست
به دست شود در کار نیست — همان `deviceId` کافی‌ست.
- `GET /api/notifications` روی این حساب چند اعلانِ واقعی دارد. **پاسخ در کلیدِ
`items` است**، نه `results`.
- `GET /api/leaderboard?period=weekly` و `?period=all_time` هر کدام ۶ ردیف
می‌دهند، با **ترتیبِ عمداً متفاوت** بینِ دو بازه، تا بشود دید پارامترِ
`period` واقعاً اثر می‌کند.
- این داده دستی روی دیتابیسِ پروداکشن ساخته شده و در گیت نیست؛ پیش از باز
شدنِ سرویس روی کاربرانِ واقعی باید پاک شود (`docs/operations.md`).
⚠️ این حساب **مشترک** است. هر کسی که همین `deviceId` را بفرستد وارد همان حساب
می‌شود، پس رویش چیزی که مالِ خودتان باشد نگذارید. برای کارِ روزمره یک
`deviceId` مخصوصِ خودتان بسازید — هر رشته‌ای قبول است.
**۲. فهرستِ پایه‌ها تا ششم است.** `GRADES` در `App.tsx` هاردکدِ ۱ تا ۶ است، ولی
جهتِ محصول از ششم به بالا رفته (ترانزیشنی: ۶، ۷، ۹، ۱۰). از `api.grades()`
بخوانید تا هر پایه‌ای که اضافه شد خودبه‌خود بیاید.

View File

@@ -157,6 +157,31 @@ curl -X POST https://api.math.tadrisino2.ir/api/auth/login \
- کدِ تصادفی بگذارید، نه `1234`، و پیش از باز شدنِ سرویس روی کاربرانِ واقعی
خالی‌اش کنید.
### حسابِ مهمانِ تستِ فرانت
مسیرِ مهمان (`POST /api/auth/session` با یک `deviceId`) اصلاً به پیامک کار
ندارد و همیشه کار می‌کند — هر رشته‌ای به‌عنوانِ `deviceId` یک حسابِ تازه
می‌سازد.
یک `deviceId` مشخص روی پروداکشن از قبل داده دارد:
```bash
curl -X POST https://api.math.tadrisino2.ir/api/auth/session \
-H 'Content-Type: application/json' \
-d '{"type":"guest","deviceId":"frontend-test-device"}'
```
کاربرِ شماره‌ی ۶، «حساب تست فرانت». رویش ۲۴ ردیفِ `Notification` و ۲۰ ردیفِ
`LeaderboardEntry` (هفتگی و کل، با ترتیبِ عمداً متفاوت) نشسته تا تیمِ فرانت
بتواند آن صفحه‌ها را قبل از وجودِ ترافیکِ واقعی ببیند.
⚠️ **این داده دستی روی دیتابیسِ پروداکشن نوشته شده و در گیت نیست.** پیش از باز
شدنِ سرویس روی کاربرانِ واقعی باید برود، وگرنه اعلان‌ها و لیدربردِ ساختگی را
کاربرِ واقعی می‌بیند. `purge_demo_data` این‌ها را **نمی‌گیرد** — آن فرمان فقط
دنبالِ پیشوندِ `[SEED]`/`[DEMO]` روی Grade/Plan/Character/User می‌گردد. پاک
کردن یعنی حذفِ دستیِ ردیف‌های `Notification` و `LeaderboardEntry` از پنلِ
ادمین (اول بکاپ، بخشِ بالا).
## سرور
`api.math.tadrisino2.ir` روی یک **ماشینِ مشترکِ شرکت** اجرا می‌شود