chore: init monorepo with GPL-3.0 license, docs, backend skeleton, frontend wiring
This commit is contained in:
commit
43cf0e277d
57 changed files with 5027 additions and 0 deletions
82
docs/catalog-philosophy.md
Normal file
82
docs/catalog-philosophy.md
Normal 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`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue