# BiznisPortal Launch Checklist

## Obavezne env promenljive

- `DATABASE_URL`
- `AUTH_SECRET`
- `ADMIN_EMAIL`
- `ADMIN_PASSWORD`
- `NEXT_PUBLIC_GOOGLE_MAPS_API_KEY` ili admin setting `integrations.googleMapsApiKey`
- `WEATHER_API_URL` samo ako je `WEATHER_PROVIDER=custom`
- `FX_API_URL` samo ako je `FX_PROVIDER=custom`
- `MEDIA_STORAGE_DRIVER=local|s3`
- `MEDIA_BUCKET`
- `MEDIA_REGION`
- `MEDIA_ENDPOINT`
- `MEDIA_PUBLIC_BASE_URL`
- `MEDIA_ACCESS_KEY_ID`
- `MEDIA_SECRET_ACCESS_KEY`
- `NOTIFICATIONS_WEB_PUSH_ENABLED`
- `NOTIFICATIONS_WEB_PUSH_PUBLIC_KEY`
- `NOTIFICATIONS_WEB_PUSH_PRIVATE_KEY`
- `NOTIFICATIONS_WEB_PUSH_SUBJECT`
- `NOTIFICATIONS_NATIVE_PUSH_ENABLED`
- `NOTIFICATIONS_NATIVE_PUSH_MODE`
- ako je `direct`:
  - `NOTIFICATIONS_FCM_PROJECT_ID`
  - `NOTIFICATIONS_FCM_CLIENT_EMAIL`
  - `NOTIFICATIONS_FCM_PRIVATE_KEY`
  - `NOTIFICATIONS_APNS_KEY_ID`
  - `NOTIFICATIONS_APNS_TEAM_ID`
  - `NOTIFICATIONS_APNS_PRIVATE_KEY`
  - `NOTIFICATIONS_APNS_BUNDLE_ID`
- ako je `webhook`:
  - `NOTIFICATIONS_NATIVE_PUSH_WEBHOOK_URL`
- `CAPACITOR_SERVER_URL` ako buildujete Partner wrapper
- `ANDROID_KEYSTORE_FILE`
- `ANDROID_KEYSTORE_PASSWORD`
- `ANDROID_KEY_ALIAS`
- `ANDROID_KEY_PASSWORD`
- `IOS_DEVELOPMENT_TEAM`
- `IOS_BUNDLE_IDENTIFIER`
- `IOS_EXPORT_METHOD`

## Pre produkcije

1. Pokrenuti `npm run prisma:generate`.
2. Pokrenuti migracije: `npx prisma migrate deploy`.
3. Pokrenuti seed: `npm run prisma:seed`.
4. U adminu otvoriti `/admin/podesavanja` i popuniti:
   - portal kontakt podatke
   - Google Maps ključ
   - weather/fx provider vrednosti
   - custom weather/fx URL ako provider nije podrazumevani
   - storage driver i S3/R2 kredencijale
   - maintenance token
   - web push public key ako Partner aplikacija treba da šalje push obaveštenja
   - native push webhook URL ako Partner wrapper treba da šalje Android/iOS push poruke
5. Otvoriti `/admin/podesavanja` i proveriti Launch Readiness kartice.
6. Ako ide kontrolisano puštanje, uključiti `features.softLaunchEnabled`, uneti start/end datum i pragove u `/admin/podesavanja`, a zatim proveriti `/admin/soft-launch`.
7. Otvoriti `/admin/commercial-scale` i proveriti onboarding klijenata, komercijalne upite, PDF dispatch i partner app usage.
8. Otvoriti `/admin/market-leadership` i proveriti SEO dominaciju po gradovima i kategorijama, trust signale, partner app adoption, oglasni inventar i AI-assisted enrichment preporuke.
9. Po potrebi otvoriti `/api/admin/settings/diagnostics` kao admin za sirovi JSON readiness report.
10. Proveriti `/api/health`.
11. Proveriti `/api/public/mobile/bootstrap` i `/api/public/recommendations`.
12. Proveriti klijentski portal `/portal/login`.
13. Ulogovati se na `/portal` i proveriti onboarding checklist, komercijalni centar, analitiku, sinhronizaciju uređaja i push readiness karticu.
14. Ako se priprema Android/iOS wrapper, pratiti korake iz:
   - `/docs/biznisportal-partner-capacitor-wrapper.md`
   - `/docs/biznisportal-partner-mobile-release.md`
15. Za signed mobile release proveriti:
   - `npm run native:android:build`
   - `npm run native:ios:build`
   - zatim sa kredencijalima:
     - `npm run native:android:release`
     - `npm run native:ios:release`

## Cron / maintenance

- Endpoint: `POST /api/internal/maintenance`
- Auth: `Authorization: Bearer <maintenance-token>`
- Preporuka: pokretati na svakih 1h

Task trenutno:

- završava istekle kampanje
- aktivira kampanje kojima je počeo termin
- deaktivira istekla isticanja
- označava istekle poslove
- pomera dospele račune u overdue

## Provera pre puštanja

- `npm run lint`
- `npm run build`
- `npm run smoke`
- `npm run launch:check`
- javne rute:
  - `/`
  - `/kompanije`
  - `/mesta`
  - `/dogadjaji`
  - `/nekretnine`
  - `/automobili`
  - `/poslovi`
  - `/prodavnica`
  - `/magazin`
  - `/paketi-i-cene`
  - `/oglasavanje`
  - `/zasto-biznis-portal`
  - `/o-nama`
  - `/kontakt`
  - `/portal/login`
- admin rute:
  - `/admin`
  - `/admin/podesavanja`
  - `/admin/soft-launch`
  - `/admin/commercial-scale`
  - `/admin/market-leadership`
  - `/admin/paketi`
  - `/admin/paketi/isticanja`
  - `/admin/oglasi`
  - `/admin/magazin`
  - `/admin/naplata`
  - `/admin/notifikacije`
  - `/admin/portal-nalozi`
  - `/admin/sifrarnici/bedzevi`

## Bulk import

- CSV/JSON import kompanija i mesta:
  - `npm run import:companies -- ./imports/kompanije.csv`
- Premium bundle za brzo punjenje portala:
  - `npm run import:bundle`

Očekivana polja:

- `name`
- `slug`
- `type`
- `categorySlug` ili `categorySlugs` (`slug1|slug2`)
- `citySlug`
- `municipalitySlug`
- `neighborhoodSlug`
- `email`
- `phone`
- `website`
- `address`
- `slogan`
- `description`
- `tier`
- `status`
- `isVerified`
- `lat`
- `lng`
- `logoUrl`
- `coverUrl`
- `socialsJson`
- `addonEvents`
- `addonRealEstate`
- `addonCars`
- `isFeatured`

Za nekretnine i automobile podržano je i:

- `galleryUrls` kao `url1|url2|url3`

Za poslove i magazin podržano je i:

- `coverMediaUrl`

## Custom weather / FX provider shape

Ako koristite `integrations.weatherProvider=custom`, endpoint treba da vrati ili:

- `{ "location": "Beograd", "temperatureC": 12.4, "condition": "Vedro" }`

ili Open-Meteo kompatibilan payload sa `current.temperature_2m` i `current.weather_code`.

Ako koristite `integrations.fxProvider=custom`, endpoint treba da vrati ili:

- `{ "base": "EUR", "target": "RSD", "rate": 117.18 }`

ili Frankfurter kompatibilan payload sa `rates.RSD`.
