chore: init monorepo with GPL-3.0 license, docs, backend skeleton, frontend wiring

This commit is contained in:
loki5512344 2026-09-06 14:34:57 +02:00
commit 43cf0e277d
Signed by: boba
GPG key ID: 253067914055423B
57 changed files with 5027 additions and 0 deletions

View file

@ -0,0 +1,82 @@
# Философия каталога Indexium — Open Source Only, Zero Storage
> **Тезис:** Indexium — не хостинг файлов. Ты даёшь свой GitHub, мы даём индексацию, поиск и доверие. Все моды в каталоге обязаны быть open source.
---
## 1. Принцип Zero Storage
| Храним у себя | НЕ храним у себя |
|---|---|
| Метаданные `fabric.mod.json` / `mods.toml` | `.jar` / `.zip` артефакты |
| `README.md`, `LICENSE`, иконка (кэш) | Скомпилированный байткод |
| `SHA256`, `file_size`, `game_versions`, `loaders` | Исходники (берём с GitHub) |
| `search_vector` для FTS | Логи скачиваний с IP |
**Как работает:**
- Релиз публикуется в `github.com/<owner>/<repo>/releases` → webhook → воркер делает 2-3 `Range Request` к CDN (`objects.githubusercontent.com`) → парсит только центральную директорию ZIP → сохраняет метаданные в Postgres → отдаёт клиенту **прямую ссылку** `https://github.com/.../releases/download/...`
- Трафик не идёт через нас. Мы не платим за egress, не упираемся в лимиты хранения.
**Почему это круто:**
- Дешёво: VPS $5 + managed Postgres, без S3.
- Честно: автор контролирует файлы, может удалить релиз — он пропадёт и у нас (через webhook `release.deleted`).
- Устойчиво к DMCA: мы — индексатор, а не дистрибьютор (как `crates.io` vs `GitHub`).
---
## 2. Open Source Only — честь и правило
### Что значит "обязан быть open source"
Мод принимается в каталог только если:
1. **Репозиторий публичный** (`private: false` через GitHub API).
2. **Есть файл лицензии** в корне: `LICENSE` / `COPYING` / `LICENSE.md`. Проверяем через `GET /repos/{owner}/{repo}/license` — поле `license.spdx_id != null` и `license.spdx_id != "NOASSERTION"`.
3. **Лицензия из allow-list OSI:** `MIT`, `Apache-2.0`, `GPL-2.0`, `GPL-3.0`, `LGPL-2.1`, `LGPL-3.0`, `MPL-2.0`, `BSD-2/3-Clause`, `CC0-1.0`, `Unlicense`, `EUPL-1.2`, `AGPL-3.0`. Список расширяется через ADR.
4. **Исходники соответствуют артефакту** (best-effort): проверяем что в репо есть `fabric.mod.json` / `gradle.properties` с тем же `mod_id`/`version` что и в `.jar`. Полная reproducible-build проверка — в backlog.
5. **Нет обфускации/шифрования** в релизе без исходников: если воркер находит `Runtime.exec` без открытого кода — флаг `suspicious`.
> **На MVP** достаточно п.1 + п.2 (любая распознанная лицензия GitHub). Строгий OSI allow-list включаем после первых 100 модов.
### Как проверяем при импорте
```
POST /mods/import { repo: "owner/repo" }
→ GitHub API: GET /repos/{repo} → private? reject 422
→ GET /repos/{repo}/license → null? reject 422 "LICENSE required — open source only"
→ GET /repos/{repo}/contents/fabric.mod.json?ref=main → not found? reject
→ Создаём mods + ставим webhook
```
При каждом `release.published` повторно проверяем лицензию — если автор сменил на `NOASSERTION`/сделал приватным → мод помечается `deprecated`, скрывается из поиска, но старые версии доступны (кэш).
### Что показываем пользователю
- Бейдж `OSI: MIT` на карточке мода, ссылка на `LICENSE` на GitHub.
- Фильтр `license:MIT` в поиске.
- Страница `/manifesto` — манифест: "Почему только open source" (прозрачность, безопасность, форки, обучение).
### Edge cases
- **Форки:** разрешены, но `slug` уникален, показываем `fork_of: owner/repo`. Оригинал помечается `upstream`.
- **Мульти-мод репо (монорепо):** на MVP 1 репо = 1 мод. Позже — поддержка `mods.toml` с несколькими `modId`.
- **Организация vs личный акк:** оба ок, если репо публичное и лицензия есть.
- **Что если автор закрыл репо?** Webhook `repository.privatized` → скрываем мод, чистим кэш, храним метаданные 30 дней для восстановления.
---
## 3. Что это даёт экосистеме
- **Доверие:** любой может `git clone`, проверить код, собрать самому — нет "левый jar с майнером".
- **Долговечность:** даже если Indexium умрёт, моды живут на GitHub.
- **Культура:** стимулируем PR'ы, а не "скачал и забыл". Профили показывают контрибьюторов, а не только owner.
---
## 4. Что НЕ делаем
- Не принимаем бинарники без исходников (даже если автор "обещает" открыть позже).
- Не зеркалируем закрытые репозитории, даже с токеном.
- Не храним `.jar` у себя даже кэшем (кроме 64KB хвоста для парсинга — эфемерно).
См. также: `docs/auth-profiles.md` — как профили усиливают open source (контрибьюторы, верификация), `docs/adr/004-open-source-only.md`.