# 🛠️ Development Guide

Panduan untuk menjalankan dari source, memodifikasi backend/frontend, dan konvensi proyek.

## Prasyarat

- **Node.js ≥ 20** (diuji pada v24)
- **macOS** (tray icon, Keychain, dan LaunchAgent spesifik macOS)
- npm

## Setup

```bash
git clone <repo-anda> antigravity-tc
cd antigravity-tc
npm install
cp env.example .env   # lalu isi nilai
npm run build:web     # build frontend sekali sebelum jalan dari source
```

File `.env` hidup di **`~/.antigravity-tc/.env`** (bukan folder project/cwd). Saat pertama kali jalan, app otomatis membuatnya dari `env.example` — atau memigrasi `.env` lama di folder project bila ada. Override lokal saat development tetap bisa dengan mengedit file itu.

### Variabel `.env`

| Variabel | Keterangan |
| --- | --- |
| `PORT` | Port server (default `3456`) |
| `APP_PASSWORD` | Password admin (jika kosong: `1234567890`; password yang diganti via dashboard selalu menang) |
| `DB_PATH` | Path `data.sqlite` 9Router (opsional; bisa juga dari dashboard) |
| `OAUTH_CLIENT_ID` / `OAUTH_CLIENT_SECRET` | Opsional — kredensial OAuth publik Antigravity CLI sudah tertanam bawaan di `server.js` (base64); isi hanya untuk memakai client sendiri |
| `OAUTH_METHOD` | `tab` (default) atau `popup` |

## Menjalankan

```bash
npm start              # TUI interaktif + tray
node index.js --hidden # langsung mode tray
npm run dev:web        # frontend: Vite dev server di :5173 (proxy API ke :3456)
```

Alur development frontend: jalankan `npm start` (backend) + `npm run dev:web` (frontend) di terminal berbeda, lalu buka `http://localhost:5173` — hot reload setiap edit `web/src/**`.

## Struktur Proyek

```
index.js              Entry point: single-instance lock, tray, TUI, lifecycle
server.js             HTTP server + semua API route
src/
  paths.js            Path ~/.antigravity-tc/ + migrasi database
  config.js           Config (library `conf`)
  jwt.js              Auth JWT — secret random per instalasi
  tunnel.js           Cloudflare Quick Tunnel (download binary, spawn, parse URL)
  autostart.js        LaunchAgent macOS (di tulis native, bukan via auto-launch)
  tray.js             Tray icon macOS (systray2)
  cli.js              TUI menu (@inquirer/prompts)
web/                  Frontend Vue 3 + Vite + Tailwind (lihat build.md)
  src/admin/          Dashboard admin (App, LoginCard, DashboardView, SettingsView, store.js)
  src/public/         Halaman donasi publik (PKCE, modal eligibility)
  src/shared/         Komponen & helper bersama (Mascot, api, toast)
```

## API Endpoints

Semua endpoint `/api/*` selain `verify-password`, `session`, `logout`, `password-status`, dan `oauth-config` membutuhkan **JWT admin** (cookie `admin_session` httpOnly).

| Endpoint | Method | Fungsi |
| --- | --- | --- |
| `/api/verify-password` | POST | Login → set cookie JWT |
| `/api/password` | POST | Ganti password (admin) |
| `/api/settings` | GET/POST | Baca/ubah pengaturan (path DB 9Router) |
| `/api/autostart` | POST | Toggle auto-start |
| `/api/tunnel` | GET/POST | Status / toggle tunnel publik |
| `/api/donations` | GET | List donasi + statistik (paginasi) |
| `/api/donations/import` | POST | Import CSV (dedupe by email) |
| `/api/donations/:id/check-eligibility` | POST | CE + auto refresh token |
| `/api/donations/:id/sync` | POST | Upsert ke 9Router by email |
| `/api/generate`, `/api/insert` | POST | Query SQL / insert manual (admin) |
| `/api/keychain`, `/api/decode` | POST | Ambil token dari Keychain (admin) |

## Konvensi & Catatan Teknis

- **CommonJS** di backend (`require`/`module.exports`), ESLint flat config di `eslint.config.js` — `npm run lint` harus bersih sebelum commit/publish.
- **Priority insert 9Router**: selalu `COUNT(provider antigravity + authType oauth) + 1` (urutan terakhir), `isActive = 0`.
- **Import CSV**: email sama → update hanya jika data baru lebih baru (banding Expiry, lalu CreatedAt).
- **Tailwind**: content glob di `web/tailwind.config.js` memakai path absolut (`__dirname`) — jangan ubah ke relatif, karena resolve-nya bergantung cwd proses build.
- **JWT secret**: dibuat random sekali per instalasi, disimpan di config — tidak pernah ikut ter-publish.
- **Single instance**: lock di `$TMPDIR/antigravity-token-collector.lock`; instance kedua keluar dengan pesan "Sudah berjalan di menubar."
- Desain frontend: neobrutalist (hard shadow, border hitam tebal, warna flat) — design system ada di `web/src/styles.css`, maskot Astro-G di `web/src/shared/Mascot.vue`.

## Testing Manual Cepat

```bash
# login (password default)
curl -c ck.txt -X POST localhost:3456/api/verify-password \
  -H 'Content-Type: application/json' -d '{"password":"1234567890"}'

# settings (harus 200)
curl -b ck.txt localhost:3456/api/settings

# tanpa cookie (harus 401)
curl localhost:3456/api/donations
```
