Two data feeds now come from the XC_VM_Update release instead of a stale static seed and a paid MaxMind edition. blocked_asns catalog: - Drop the ~69k-row static blocked_asns seed from database.sql and the unused `allocated` column (migration 013); the table starts empty. - AsnCatalogSync (new) downloads blocked_asns.json.gz from the release and upserts the reference columns (isp/domain/country/num_ips/type), pruning ASNs that left the catalog. The user-owned `blocked` flag is never written, and a blocked ASN is never pruned. Runs on MAIN via cron:maxmind. Free GeoIP2-ISP: - Remove the committed paid GeoIP2-ISP.mmdb. Every node now fetches the free, self-built GeoIP2-ISP.mmdb from the release (md5-gated, fetchReleaseFile) unless a paid GeoIP2-ISP edition is configured, so ASN lookups work without a licence. version.json's geoisp_version is recorded for the info tab; the fallback path's geolite2_version update was cleaned up. - getGeolite() no longer fetches GeoLite2-ASN (unused); GeoIP2-ISP and the ASN catalog resolve via getIspDatabase()/getAsnCatalog() over a shared releaseAsset(). settings_audit.md documents the settings-table audit that motivated the schema cleanup (dead columns, drift, module-owned columns).
8.9 KiB
Аудит таблицы settings — осиротевшие / мёртвые / дрейф
Дата: 2026-08-30. Объём: таблица settings против админской страницы Settings
(src/Public/Views/admin/settings.php) и остального PHP/JS-кода.
Метод
- Живой источник истины:
SELECT COLUMN_NAME ... information_schemaпо продовой БД (xc_vm.settings) → 274 колонки. - Поля UI: каждый
name="…"вsettings.php→ 214 полей формы. - Проверка использования (точная): настройки читаются по строковому ключу
(
$rSettings['x'],SettingsManager::get('x'), формаname="x"). Поэтому колонка считается используемой только если её имя встречается как строковый литерал в кавычках ('x'/"x") где-либо вsrc/**.php|.js(исключая дамп схемы,src/migrations/,vendor/,assets/). Это отсекает ложные срабатывания по подстроке (например,thread_countвнутриcache_thread_count, или колонкаffmpeg_gpuпротив глобала$rFFMPEG_GPU, который берётся изFfmpegPaths::gpu()).
1. Осиротевшие поля на странице Settings — НЕТ
Все 214 name= ложатся в реальную колонку. Единственные «не-колонки» объяснимы:
submit_settings— кнопка отправки формы.user_agent,http_proxy,cookie,headers— это не колонкиsettings;SettingsService::edit()(строки 30-33) роутит их в таблицуstreams_arguments(argument_default_value), а не вsettings.
2. Мёртвые колонки — 12 (в БД, 0 ссылок ни в src/, ни в модулях; 2B доделано)
Обновление 2026-08-30:
ffmpeg_gpuоживлён (динамическийFfmpegBinaries+FfmpegPaths::resolve($cpu, $gpu), дропдаун в settings, таблица на вкладке info).⚠️ Важная поправка метода: аудит сканировал только
src/репозитория, а внешние модули (Plex, Watchfolder — отдельные репозитории, ставятся в рантайме) тоже читают/пишут core-колонкиsettings. Перепроверка по ним перенесла 5 колонок из «мёртвых» в живые (см. 2C). Перед сносом любой «мёртвой» колонки — обязательно грепать по ВСЕМ доступным модулям, не только по репозиторию.
2A. «Умерло» — в схеме database.sql, но не используются ни в src/, ни в модулях (12)
Остатки вырезанных/переделанных фич; всё ещё ставятся на каждой установке, но ничего их не читает и не пишет.
| Колонка | Вероятная причина / почему мертва |
|---|---|
custom_ip_header |
кастомный заголовок client-IP — фича удалена |
detect_restream_ports |
детект рестрима урезан (живы только detect_restream_block_user/_ip) |
detect_restream_servers |
то же |
release_parser |
старый конфиг парсера релизов (вытеснен parse_type/alternative_titles) |
hls_accelerator |
удалённый тумблер HLS-акселератора |
redirect_timeout |
не используется |
reissues |
не используется |
reseller_restrictions |
не используется |
split_clients |
легаси (в отличие от живой split_by) |
stats_pid |
stats-крон больше не трекает PID здесь (ср. живые backups_pid/watch_pid) |
tmdb_pid |
tmdb-крон больше не трекает PID здесь |
stb_change_pass |
удалённый тумблер смены пароля STB |
2C. Живы через модули — НЕ мёртвые, НЕ дропать (5)
Core-колонки settings, чьи UI и логику предоставляют внешние модули (не панель).
Аудит по src/ их не видел; подтверждены грепом по Module_Plex / Module_Watchfolder.
| Колонка | Модуль(и) | Использование |
|---|---|---|
scan_seconds |
Plex + Watchfolder | UPDATE settings + форма + чтение |
thread_count_movie |
Plex | UPDATE + getAll()['thread_count_movie'] в PlexCron |
thread_count_show |
Plex | UPDATE + чтение в PlexCron |
thread_count |
Watchfolder | UPDATE + чтение в WatchCron |
fallback_parser |
Watchfolder | UPDATE + чтение в WatchCron/WatchItem |
2B. «Пропустили» — ✅ РЕШЕНО (доделано, коммит 1dd488fb)
auto_unban_ip / ban_duration_value / ban_duration_unit были только в живой БД
(ручной ALTER), логики не было. Доделана фича авто-разбана: миграция 012
- seed в
database.sql(дрейф устранён), UI в секции flood/bruteforce, прун протухших авто-банов вRootSignalsCronJob(MAIN, только авто-баны поnotes; ручные баны не трогаются, существующий синкblocked_ips→iptables снимает их с нод).
3. Дрейф схемы
- В живой БД, но не в
database.sql: было 3 (auto_unban_ip,ban_duration_*) — устранено миграцией012+ добавлением вdatabase.sql(см. 2B). - В
database.sql, но не в живой БД: нет.
4. Колонки в БД, но не редактируемые на странице Settings — 61
Включает 12 мёртвых + 5 модульных (2C: scan_seconds, thread_count*, fallback_parser
— UI даёт модуль, как dropbox/cache задаются на других страницах). Остальные 44 — легитимны:
Рантайм / внутреннее (корректно скрыто):
id, backups_pid, watch_pid, stats_pid, tmdb_pid, last_backup,
last_cache, last_cache_taken, status_uuid, update_data, update_version,
xc_vm_version, total_users, license, log_clear.
(*stats_pid/tmdb_pid также в списке мёртвых — живого PID-трекинга нет.)
Задаются на других страницах админки (корректно):
automatic_backups, backups_to_keep, dropbox_keep, dropbox_remote,
dropbox_token (страница Backup → editBackup); cache_changes,
cache_thread_count, enable_cache (Cache/Cron → editCacheCron);
redis_handler, redis_password (инсталлер / другое).
Используются кодом, но без UI на этой странице — проверить, намеренно (advanced) или пропущено:
alternative_titles, auto_update_lbs, cc_time, connection_loop_count,
connection_loop_per, cpu_limit, mem_limit, detect_restream_block_ip,
legacy_mag_auth, mag_security, max_genres, max_items (только в JS),
ministra_allow_blank, percentage_match, send_altsvc_header,
send_protection_headers, send_server_header, send_unique_header,
send_unique_header_domain, send_xc_vm_header, stalker_lock_images.
5. Рекомендованные шаги
- Снести 12 «умерших» колонок (раздел 2A; НЕ трогать 2C-модульные) — миграция
013_drop_dead_settings.sql(ALTER TABLE settings DROP COLUMN …) и убрать их из seeddatabase.sql. Необратимо; делать только после финальной проверки grep. - ✅ 2B сделано — фича авто-разбана доделана (коммит
1dd488fb, миграция012). - Пройтись по 21 «used but no UI» — по каждой решить: вывести на страницу, перенести в advanced-вкладку или оставить дефолтом только в коде.
Приложение — сырые счётчики
- 274 живых колонки · 218 полей формы · 12 мёртвых (2A) · 5 модульных (Plex/Watchfolder) · 3 доделано (2B: auto_unban) · 61 без UI.