# Kasy App

Flutter app with Firebase backend — generated by kasy.

---

## Documentation

Full Kasy documentation (CLI, iOS release, features, push, etc.) will be published at **[docs.kasy.dev](https://docs.kasy.dev)** (site coming soon).

In this project, use the local guides (links stay inside this repo only):

| Guide | Content |
|-------|---------|
| [docs/auth-setup.md](docs/auth-setup.md) | Enable Google, Apple and Facebook login |
| [docs/ios-release.md](docs/ios-release.md) | Publish to iOS on Mac (`kasy ios`) |
| [docs/codemagic-release.md](docs/codemagic-release.md) | Publish without a Mac (`kasy codemagic`) |

---

## Getting started

```sh
flutter run          # auto-detects device
make run-ios         # iOS
make run-android     # Android
```

**Physical device via cable**
- iOS: connect iPhone → trust this computer → Xcode → Window → Devices → pair
- Android: Settings → Developer options → enable USB debugging

**Backend deploy** (when ready):

```sh
kasy deploy
```

---

## Keys and credentials

This project uses two types of credentials. Understanding the difference avoids confusion when configuring.

### App keys (stay in the project)

They live in `.vscode/launch.json` as build environment variables (`--dart-define`). Flutter reads them via `String.fromEnvironment()`. **Never go to the server.**

| Variable | Module | How to get |
|----------|--------|------------|
| `RC_TEST_KEY` | RevenueCat | RevenueCat dashboard → Apps → Test Store → key (`test_…`). **One key for both iOS+Android.** Auto-used on simulator/emulator. |
| `RC_IOS_PROD_KEY` | RevenueCat | RevenueCat dashboard → Apps → App Store → key (`appl_…`). Auto-used on physical iPhone (Sandbox and Production). |
| `RC_ANDROID_PROD_KEY` | RevenueCat | RevenueCat dashboard → Apps → Google Play → key (`goog_…`). Auto-used on physical Android. |
| `RC_WEB_API_KEY` | RevenueCat Web | RevenueCat dashboard → Apps → Web Billing → **production** key (`rcb_…`, not `rcb_sb_`) for release builds |

### RevenueCat: `kasy run` picks the right key automatically

The CLI detects whether you're running on **simulator/emulator** or **physical device** and injects the right key:

| Where you run | Key used |
|---|---|
| iOS Simulator / Android Emulator | `RC_TEST_KEY` (test_) |
| Physical iPhone | `RC_IOS_PROD_KEY` (appl_) — falls back to `RC_TEST_KEY` if missing |
| Physical Android | `RC_ANDROID_PROD_KEY` (goog_) — falls back to `RC_TEST_KEY` if missing |

Force manually: `kasy run --rc=test` or `kasy run --rc=prod`. `--rc=auto` (default) applies the rule above.

- **Why the split?** Simulators can't run real in-app purchases against `appl_`/`goog_` — only RevenueCat Test Store works there. On physical devices, `appl_`/`goog_` covers both Sandbox and Production (the SDK detects the environment).
- **TestFlight and release:** use the production keys. **NEVER ship `test_` to the store** — the RevenueCat SDK crashes the app on release.
- **VS Code (F5 without kasy run):** `launch.json` defaults to `RC_TEST_KEY` (or production if test_ is missing). To switch manually, run via `kasy run`.
| `SENTRY_DSN` | Sentry | Dashboard Sentry → Project → DSN |
| `MIXPANEL_TOKEN` | Mixpanel | Dashboard Mixpanel → Settings → Token |

To update, edit `.vscode/launch.json` or pass via command line:

```sh
flutter run --dart-define=RC_ANDROID_API_KEY=your_key
```

---

### Server secrets (stay in GCP Secret Manager)

Used by **Cloud Functions** at runtime. **Never in the app code.**

| Secret | Used by | How to get |
|--------|---------|------------|
| `REVENUECAT_WEBHOOK_KEY` | Subscription webhook | Dashboard RevenueCat → Webhooks → Authorization header |
| `META_ACCESS_TOKEN` | Meta Conversions API | Meta Business Manager → System Users → Token |
| `META_DATASET_ID` | Meta Conversions API | Meta Business Manager → Events Manager → Dataset ID |

To configure or update each secret:

```sh
firebase functions:secrets:set REVENUECAT_WEBHOOK_KEY --project=YOUR_PROJECT_ID
firebase functions:secrets:set META_ACCESS_TOKEN --project=YOUR_PROJECT_ID
firebase functions:secrets:set META_DATASET_ID --project=YOUR_PROJECT_ID
```

> Each command asks for the value interactively. The value **does not appear** in the terminal.

To see existing secrets:

```sh
gcloud secrets list --project=YOUR_PROJECT_ID
```

---

## Internationalization (i18n)

The app supports **3 languages**: English (`en`), Portuguese (`pt`), and Spanish (`es`).

### How the language is chosen

```
App opens
  ├─ Has language saved by user? → use saved
  └─ No → read device/browser language
            ├─ Is en, pt or es? → use that language
            └─ None of these → use default language (base_locale)
```

### Change default language (fallback)

When the user's device is in an unsupported language (e.g. Japanese, French), the app uses the **default language**. Default is English. To change to Portuguese:

**`slang.yaml`**
```yaml
base_locale: pt   # change here: en | pt | es
```

Then run:
```sh
dart run slang
```

### Add or edit translations

Files are in `lib/i18n/`:
- `en.i18n.json` — English
- `pt.i18n.json` — Portuguese
- `es.i18n.json` — Spanish

After editing any `.i18n.json`, always run `dart run slang` to regenerate `translations.g.dart`.

### Language selector

The user can change the language in **Settings → Language**. The choice is saved on the device and restored on next app open.

---

## RevenueCat webhook

The webhook receives purchase events (new subscription, renewal, cancellation) from RevenueCat.

**In RevenueCat dashboard:** Webhooks → add function URL → Authorization header = value of `REVENUECAT_WEBHOOK_KEY`.

---

## Deploy

```sh
# Full deploy (Functions + Firestore rules + Storage rules)
firebase deploy --only functions,firestore:rules,storage --project=YOUR_PROJECT_ID

# Functions only
firebase deploy --only functions --project=YOUR_PROJECT_ID
```

---

## Publish to iOS (App Store)

Full guide: [docs/ios-release.md](docs/ios-release.md)

```bash
kasy ios configure   # once — Apple credentials
kasy ios release     # build IPA and upload to App Store Connect
```

No Mac: [docs/codemagic-release.md](docs/codemagic-release.md)

---

## Security

`.gitignore` already excludes: `firebase_key.json`, `.env`, `.env.*`, `*.pem`, `*.keystore`, `.kasy/apple.env`, `.kasy/codemagic.env`.

Never commit credentials to the repository.
