diff --git a/CLAUDE.md b/CLAUDE.md index 52f90bc..a8b786d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -88,7 +88,7 @@ python manage.py test accounts # single app python manage.py test accounts.tests.SomeTestCase.test_something # single test ``` -Local dev requires `DJANGO_DEBUG=1` (enables Swagger auth via `DEV_MASTER_OTP`/`devOtp` in responses). `DEBUG` defaults to `False`. Production also requires `DJANGO_SECRET_KEY`, `DJANGO_ALLOWED_HOSTS` (comma-separated), and ideally `CACHE_URL` (Redis). Without it the app still boots on per-process `LocMemCache` and `/api/health` warns — throttles and admin-driven cache invalidation are then per worker. On the server it is empty on purpose (owner, 2026-10-07): the Redis on that machine belongs to other teams and we do not connect to it. Our own Redis is an open pre-launch decision; until then limits are ≈3× the configured number (3 workers). +Local dev requires `DJANGO_DEBUG=1` (enables Swagger auth via `DEV_MASTER_OTP`/`devOtp` in responses). `DEBUG` defaults to `False`. Production also requires `DJANGO_SECRET_KEY`, `DJANGO_ALLOWED_HOSTS` (comma-separated), and ideally `CACHE_URL` (Redis). Without it the app still boots on per-process `LocMemCache` and `/api/health` warns — throttles and admin-driven cache invalidation are then per worker. On the server since 2026-10-08 it points at our own Redis (`zareian-redis.service`, port 6390, localhost, password-protected, 256 MB `allkeys-lru`, no persistence), never the company's Redis on 6379. Its outage is logged and rate limits stop applying (fail-open); not tested under real Redis failure on the server. No pytest; uses Django's built-in test runner. No linter/formatter configured. @@ -126,7 +126,7 @@ API docs: Swagger `/api/docs/`, Redoc `/api/redoc/`, admin `/admin/`. **Structured logging**: `config.middleware.APIRequestLoggingMiddleware` (last in `MIDDLEWARE`, closest to the view) logs every `/api/` request as JSON (method/path/status/duration/user, no body/headers/secrets) via `config/log_formatters.py`. -**SQLite** is current DB (`OPTIONS.timeout=20`, and `transaction_mode: IMMEDIATE` so every `atomic()` takes the write lock up front — SQLite ignores `select_for_update`, so without it those guards locked nothing). Tests run on a file DB (`.test-db.sqlite3`). Postgres migration is still pending. +**Postgres** is the server's DB since 2026-10-08 (own cluster `14/zareian`, port 5440, localhost only; DB `zareian_mathapp`, role `zareian_app`; selected by `DB_NAME`/`DB_USER`/`DB_PASSWORD`/`DB_HOST`/`DB_PORT` in `.env`; passwords in `~/mathapp-v2/.pg_password`, `.redis_password`). It is separate from the company's `main` cluster on 5432 — never touch that. Without `DB_NAME` the app falls back to SQLite (local dev, tests); both run the full suite green. Data was moved with `dumpdata`/`loaddata`; model-count comparison matched. Guards that relied on SQLite's `IMMEDIATE` now rely on real row locks; concurrency tests pass on Postgres, not load-tested. `deploy.sh` backs up with `pg_dump -Fc` (restore into a scratch DB not tested). Operator guide: `~/Desktop/گزارشات Tadrisino/گزارش-۲۹/راهنمای-Postgres-و-Redis.html`. The old `db.sqlite3` stays on the server as a frozen pre-move copy. **SMS** goes through Kavenegar (`KAVENEGAR_API_KEY`/`KAVENEGAR_SENDER`); failures return explicit 503, not a fake success. @@ -329,7 +329,7 @@ reliably pull the final answer out of a solution and produced ~40% broken output ## Known gaps (per README pre-deploy checklist) -- Still on SQLite, not Postgres. +- Postgres is live; no off-machine backup yet (owner waiting for the destination from the senior). - Throttle rates need periodic review against real traffic. - `DEV_MASTER_OTP` (`0000`) must stay gated behind `DEBUG` — never enabled in prod. - No video content exists yet, though `Lesson.kind`/`video_url` can express it. diff --git a/docs/operations.md b/docs/operations.md index 7519711..42da204 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -68,10 +68,10 @@ curl -i https://mathapi.tadrisino2.ir/api/health ## بکاپ و بازیابی -`db.sqlite3` در گیت **نیست** و تنها نسخه‌ی داده‌ی کاربران است. `deploy.sh` پیش از `migrate` -خودش بکاپ می‌گیرد (`.deploy-backups/db-before-deploy-<زمان>.sqlite3`، با `integrity_check`، ۲ تای -آخر نگه داشته می‌شود) و اگر بکاپ نشد migrate را اجرا نمی‌کند. این بکاپ روی همان ماشین است؛ نسخه‌ی -بیرون از ماشین هنوز نیست. برای بکاپِ دستی (مثلاً پیش از تغییرِ `.env` یا کارِ ادمین): +دیتابیسِ سرور Postgres است (cluster جدای `zareian`، پورت ۵۴۴۰، فقط localhost؛ راهنمای کامل: `گزارش-۲۹/راهنمای-Postgres-و-Redis.html`). `deploy.sh` پیش از `migrate` +با `pg_dump -Fc` بکاپ می‌گیرد (`.deploy-backups/db-before-deploy-<زمان>.pgdump`، ۲ تای آخر) و اگر بکاپ نشد migrate را اجرا نمی‌کند. بازیابی از آن روی دیتابیسِ جدا آزموده نشده. +بکاپ روی همان ماشین است؛ نسخه‌ی بیرون از ماشین هنوز نیست. بدون `DB_NAME` برنامه روی `db.sqlite3` (فقط توسعه‌ی محلی) می‌ماند. بکاپِ دستیِ SQLite (توسعه‌ی محلی): + ```bash cd /home/administrator/mathapp-v2