goon/CLAUDE.md
jtrzupek c0bb3f403f docs(claude.md): how to ship mobile changes (Expo OTA via publish_update.py, not git)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 10:08:23 +02:00

54 lines
3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Goon
Self-hosted aggregator of adult-content scene metadata. Multi-source ingest (TPDB, StashDB, 30+ tubes) → dedup → on-demand stream resolution (yt-dlp + JWPlayer unpacker) → API + Expo mobile client.
Stack: Python 3.12 (FastAPI + SQLAlchemy + Alembic), Postgres 16, React Native (Expo), Docker Compose.
Git: github.com/goon-foss/goon (remote: `goonfoss`). Public OSS repo. 18+ — see `DISCLAIMER.md`.
---
## Zmiany mobilne (Expo) → publikuj przez OTA, nie zostawiaj w gicie
Klient `mobile/` (React Native + Expo) aktualizuje się przez **self-hosted Expo Updates (OTA)**, nie przez sklep ani rebuild APK. Zmiany JS (ekrany, komponenty, `api.ts`) lecą silent.
**KRYTYCZNE: `git commit` NIE publikuje OTA.** Sam commit (ani push) nie zmienia NIC na telefonie. Po zmianie w `mobile/` trzeba zbudować bundle i opublikować:
```
# z roota repo; konkretne wartości env w .env.local / prywatnej pamięci (NIE hardcoduj IP tutaj)
GOON_VPS_SSH=<root@vps> GOON_VPS_UPDATES_DIR=/root/goon/app/static/expo-updates \
GOON_PUBLIC_UPDATES_URL=https://api.goon-foss.org/expo-updates/asset \
python scripts/publish_update.py --runtime 1.1
```
Skrypt: `expo export` (build) → scp bundla na VPS pod `app/static/expo-updates/<runtime>/<update_id>/` → przełącza `current.json` (endpoint `GET /expo-updates/manifest` serwuje aktywny). Apka pobiera przy następnym launchu.
Reguły:
- **runtime = `1.1`** (== `runtimeVersion` w `app.json`/APK). Bump TYLKO przy native change (wtedy też nowy APK przez PackageInstaller). `RUNTIME_DEFAULT` w skrypcie = 1.1.
- **Apply dwustopniowy**: 1. launch pobiera w tle, 2. launch aplikuje → po publish **restart apki 2×**.
- **Publish odpala AI** (nie człowiek, nie git-hook). Skrypt działa one-shot też na Windows git-bash (fix 2026-06-02: scp source `.`+`cwd=DIST`, `MSYS_NO_PATHCONV`, defensywne odkręcanie zmanglowanej ścieżki).
- **Backend (`app/`) to OSOBNY deploy** — scp `app/`→VPS + `docker compose restart` (worker/api). NIE przez OTA. `./app` i `./scripts` są wolumenami w compose, więc restart wystarcza (bez rebuildu obrazu).
---
## Kanban (auto-aggregation)
Ten workspace ma własny Kanban (custom tracker type `kanban` w `.nimbalyst/trackers/kanban.yaml`) z kolumnami:
**Backlog → Następne → W trakcie → Czeka → Zrobione**
### Reguła auto-agregacji — WAŻNE
Kiedy podczas sesji pojawi się nowy temat / bug / pomysł / blocker, na który **nie ma teraz czasu** lub jest poboczny względem aktualnego zadania — **utwórz tracker item** zamiast tylko wspomnieć o nim w czacie:
```
mcp__nimbalyst-mcp__tracker_create(
type: "kanban",
title: "<krótki tytuł>",
status: "backlog",
description: "<1-2 zdania kontekstu + ścieżka pliku jeśli dotyczy>"
)
```
Powód: Jan często skupia się na pierwszej rzeczy z planu, a pozostałe znikają. Kanban jest gwarancją, że nic nie wypadnie. Jeśli wspomnisz coś w czacie i nie założysz ticketu — to się zgubi.
Status `next` = "wybrane na najbliższe dni" (3-5 max). `waiting` = zablokowane na zewnętrzne. `done` ustawia użytkownik, nigdy AI.