feat: dapp registry + /api/getDapps, /img/dapps, DappAdmin; dapp-link verifier default-on (IDRS_VERIFY_DAPPS); is_live sticky override; fix edit-without-upload (Dapp+Token)

This commit is contained in:
proitlab committed 2026-08-18 14:43:09 +07:00
1 parent 77d6cd5b92
commit 3b68820beb
9 files changed
+447 -51

No files matched your search

+6 -6
View File
@@ -3,13 +3,13 @@
Project conventions and operational gotchas for agents working in this repo.
## Layout
- `app/main.py` — FastAPI app: public endpoints `GET /api/getTokenInfo`, `GET /api/version/android`, `GET /img/token/<filename>` + `GET /public/img/token/<filename>` (alias, seed iconUrl path); mounts `/static`; startup calls `db.init_db()`.
- `app/admin.py` — sqladmin panel: `TokenAdmin` (custom WTForms form, `on_model_change`), `VersionAdmin`, `create_admin(app)`. Upload icons saved under `app/static/icons/token/` with `iconUrl = {IDRS_PUBLIC_URL}/img/token/<filename>`.
- `app/models.py` — SQLAlchemy `Token`/`Version`, engine, `SessionLocal`, `ICON_DIR`, `DB_PATH` (env `IDRS_DB_PATH`).
- `app/db.py` — seed from `tokenList.json`/`versionAndroid.json` (once, empty DB only).
- `app/verify.py` — icon-reachability verifier: daemon thread started on app startup, gated by env `IDRS_VERIFY_ENABLED` (absent/0/false/off → disabled, default). When enabled, token live iff `iconUrl` reachable (local file stat under `icons/token/`, or external HTTP HEAD/GET 2xx); empty → false; flips after 2 consecutive failed passes, auto-recovers; interval env `IDRS_VERIFY_INTERVAL` (default 600s). When disabled, `is_live` is admin-owned (editable form field). External hosts must be reachable from the server or those tokens flip false while enabled.
- `app/main.py` — FastAPI app: public endpoints `GET /api/getTokenInfo`, `GET /api/version/android`, `GET /api/getDapps`, `GET /img/token/<filename>`, `GET /img/dapps/<filename>` + `/public/img/...` aliases (seed iconUrl path); mounts `/static`; startup calls `db.init_db()`.
- `app/admin.py` — sqladmin panel: `TokenAdmin` (custom WTForms form, `on_model_change`), `VersionAdmin`, `DappAdmin` (URL field + `imageFile` upload, auto `created_at`/`updated_at`, `id` not writable), `create_admin(app)`. Upload icons saved under `app/static/icons/token/` with `iconUrl = {IDRS_PUBLIC_URL}/img/token/<filename>`; dapp uploads under `icons/dapps/`.
- `app/models.py` — SQLAlchemy `Token`/`Version`/`Dapp`, engine, `SessionLocal`, `ICON_DIR`, `DB_PATH` (env `IDRS_DB_PATH`).
- `app/db.py` — seed from `tokenList.json`/`versionAndroid.json`/`dapps.json` (once, empty DB only). Dapp seed mirrors each `image` into `icons/dapps/` and rewrites to `{IDRS_PUBLIC_URL}/img/dapps/<file>` (gate: `image/*` only, sniff `octet-stream`, `text/html`→skip; on failure keep original URL; collision → `-N` suffix).
- `app/verify.py` — icon/link-reachability verifiers: daemon threads started on app startup, gated by env `IDRS_VERIFY_TOKENS` (token `iconUrl`, absent/0/false/off → disabled, default) and `IDRS_VERIFY_DAPPS` (dapp `link`, **enabled by default**; `0/false/off` disables). When enabled, `is_live` = reachability (local file stat under `icons/token/`, or external HTTP HEAD/GET 2xx; dapp link strict 2xx, whitespace-stripped); empty → false; flips after 2 consecutive failed passes, auto-recovers; interval env `IDRS_VERIFY_INTERVAL` (default 600s). When disabled, `is_live` is admin-owned (editable form field). `IDRS_VERIFY_TOKENS` only. Dapp admin-set `is_live=false` is sticky via `is_live_override` (verifier skips overridden dapps). External hosts must be reachable from the server or those tokens/dapps flip false while enabled.
- `app/auth.py` — `AdminAuthBackend`, fail-closed creds.
- `tokenList.json` / `versionAndroid.json` — seed source (read-only after seed).
- `tokenList.json` / `versionAndroid.json` / `dapps.json` — seed source (read-only after seed).
## Environment / secrets
- `.env` (gitignored) → `ADMIN_USERNAME`, `ADMIN_PASSWORD`, `IDRS_PUBLIC_URL` (default `https://idrs.databisnis.id`). Test creds `admin`/`testpass123` — change before exposure.