207 lines
4.7 KiB
Markdown
207 lines
4.7 KiB
Markdown
# Dewemoji Operations Runbook
|
|
|
|
This is the single operational guide for local, staging, and production workflows.
|
|
|
|
## 1) Environment model
|
|
|
|
### Local (safe default)
|
|
|
|
```env
|
|
APP_ENV=local
|
|
APP_DEBUG=true
|
|
APP_URL=http://127.0.0.1:8000
|
|
DB_CONNECTION=sqlite
|
|
DEWEMOJI_BILLING_MODE=sandbox
|
|
DEWEMOJI_LICENSE_ACCEPT_ALL=false
|
|
DEWEMOJI_ALLOWED_ORIGINS=http://127.0.0.1:8000,http://localhost:8000
|
|
```
|
|
|
|
### Staging / Production
|
|
|
|
- Use `DEWEMOJI_BILLING_MODE=live`
|
|
- Configure real DB + provider credentials
|
|
- Keep `DEWEMOJI_LICENSE_ACCEPT_ALL=false`
|
|
|
|
For full production variable template, use `production-env.md`.
|
|
|
|
## 2) Live deployment sequence
|
|
|
|
### Pre-deploy
|
|
|
|
1. Confirm env values are set in server/Coolify.
|
|
2. Confirm webhook URLs are reachable:
|
|
- `https://<domain>/v1/paypal/webhook`
|
|
- `https://<domain>/webhooks/pakasir`
|
|
3. Recommended:
|
|
|
|
```env
|
|
DEWEMOJI_BILLING_PENDING_COOLDOWN_SECONDS=120
|
|
```
|
|
|
|
### Deploy code
|
|
|
|
```bash
|
|
git fetch --all
|
|
git checkout main
|
|
git pull origin main
|
|
composer install --no-dev --optimize-autoloader
|
|
```
|
|
|
|
### Post-deploy (required order)
|
|
|
|
```bash
|
|
php artisan optimize:clear
|
|
php artisan migrate --force
|
|
php artisan config:cache
|
|
```
|
|
|
|
Optional:
|
|
|
|
```bash
|
|
php artisan route:cache
|
|
php artisan view:cache
|
|
php artisan queue:restart
|
|
```
|
|
|
|
## 3) Ensure admin access
|
|
|
|
Promote existing user:
|
|
|
|
```bash
|
|
php artisan tinker --execute="\App\Models\User::where('email','dewemoji@gmail.com')->update(['role'=>'admin']);"
|
|
```
|
|
|
|
Or create missing admin:
|
|
|
|
```bash
|
|
php artisan tinker --execute="
|
|
\$u=\App\Models\User::firstOrCreate(
|
|
['email'=>'dewemoji@gmail.com'],
|
|
['name'=>'Dewemoji Admin','password'=>\Illuminate\Support\Facades\Hash::make('ChangeMeNow123!'),'tier'=>'free','email_verified_at'=>now()]
|
|
);
|
|
\$u->role='admin';
|
|
\$u->save();
|
|
"
|
|
```
|
|
|
|
## 4) Live smoke tests
|
|
|
|
### Core routes
|
|
|
|
1. `/`
|
|
2. `/emoji/grinning-face`
|
|
3. `/pricing`
|
|
4. `/api-docs`
|
|
5. `/support`
|
|
6. `/privacy`
|
|
7. `/terms`
|
|
8. `/robots.txt`
|
|
9. `/sitemap.xml`
|
|
|
|
### API checks
|
|
|
|
```bash
|
|
BASE=https://<domain>/v1
|
|
curl -s "$BASE/health" | jq .
|
|
curl -s "$BASE/categories" | jq 'keys | length'
|
|
curl -s "$BASE/emojis?q=love&limit=5" | jq '.items | length'
|
|
```
|
|
|
|
### Billing and webhook checks
|
|
|
|
```bash
|
|
tail -n 200 storage/logs/laravel.log
|
|
php artisan tinker --execute="dump(\App\Models\WebhookEvent::latest()->take(10)->get(['id','provider','event_type','status','created_at'])->toArray());"
|
|
php artisan tinker --execute="dump(\App\Models\Payment::latest()->take(10)->get(['id','provider','plan_code','status','created_at'])->toArray());"
|
|
```
|
|
|
|
## 5) Billing runtime validation (staging)
|
|
|
|
Verify these behaviors end-to-end:
|
|
|
|
1. pending cooldown lock on repeat checkout attempts (`409 pending_cooldown`)
|
|
2. resume pending payment via dashboard `Pay`
|
|
3. webhook delay handling (`pending` -> `paid` transition)
|
|
4. race/edge handling (`payment_not_pending`, `payment_expired`)
|
|
|
|
Minimum assertions:
|
|
|
|
- cooldown response includes `retry_after`
|
|
- resume PayPal returns `mode=redirect` + `approve_url`
|
|
- resume Pakasir returns `mode=qris` with expiry data
|
|
|
|
## 6) Staging SQL sync
|
|
|
|
Set MySQL connection env, then run in container:
|
|
|
|
```bash
|
|
cd /var/www/html
|
|
php artisan migrate
|
|
php artisan dewemoji:import-live-sql /var/www/html/dewemojiAPI_DB.sql --truncate
|
|
```
|
|
|
|
Sanity check:
|
|
|
|
```bash
|
|
php artisan tinker --execute="echo DB::table('emojis')->count().PHP_EOL;"
|
|
php artisan tinker --execute="echo DB::table('emoji_keywords')->count().PHP_EOL;"
|
|
```
|
|
|
|
Expected: emojis ~2131, emoji_keywords ~13420.
|
|
|
|
## 7) MySQL GUI access via SSH tunnel
|
|
|
|
For internal-only Coolify MySQL, tunnel to container IP.
|
|
|
|
Resolve MySQL container IP:
|
|
|
|
```bash
|
|
MYSQL_IP=$(ssh SERVER_USER@SERVER_HOST "docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \$(docker ps --format '{{.ID}} {{.Names}}' | awk '/mysql|mariadb/{print \$1; exit}')")
|
|
echo "$MYSQL_IP"
|
|
```
|
|
|
|
Create tunnel:
|
|
|
|
```bash
|
|
ssh -N -L 3307:${MYSQL_IP}:3306 SERVER_USER@SERVER_HOST
|
|
```
|
|
|
|
Then connect in Sequel Ace/TablePlus using:
|
|
|
|
- Host `127.0.0.1`
|
|
- Port `3307`
|
|
- standard DB credentials
|
|
|
|
## 8) Local provider parity test (optional)
|
|
|
|
Switch local to live provider mode and verify with real keys.
|
|
|
|
```bash
|
|
BASE=http://127.0.0.1:8000/v1
|
|
curl -X POST "$BASE/license/verify" -H "Content-Type: application/json" -d '{"key":"<real_key>"}'
|
|
```
|
|
|
|
Also test activate/deactivate cycle, then return local env to sandbox mode.
|
|
|
|
## 9) APK release dependency note
|
|
|
|
App updater URLs used by the site:
|
|
|
|
- `https://dewemoji.com/downloads/version.json`
|
|
- `https://dewemoji.com/downloads/dewemoji-latest.apk`
|
|
|
|
For detailed APK build/release flow, use `dewemoji-apk-companion-build-walkthrough.md`.
|
|
|
|
## 10) Rollback
|
|
|
|
1. Re-deploy previous known-good commit.
|
|
2. Run:
|
|
|
|
```bash
|
|
php artisan optimize:clear
|
|
php artisan config:cache
|
|
php artisan queue:restart
|
|
```
|
|
|
|
3. If issue is dataset-specific, switch to a known-good snapshot via admin tooling.
|