native-update 1.4.9 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +35 -9
- package/android/manifest-additions.xml +28 -0
- package/android/src/main/AndroidManifest.xml +3 -7
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundNotificationManager.kt +21 -13
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdatePlugin.kt +15 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateWorker.kt +23 -7
- package/android/src/main/java/com/aoneahsan/nativeupdate/LiveUpdatePlugin.kt +346 -31
- package/android/src/main/java/com/aoneahsan/nativeupdate/NativeUpdatePlugin.kt +32 -34
- package/android/src/main/java/com/aoneahsan/nativeupdate/NotificationActionReceiver.kt +10 -1
- package/android/src/main/java/com/aoneahsan/nativeupdate/SecurityManager.kt +18 -18
- package/cli/AGENTS.md +43 -0
- package/cli/CLAUDE.md +65 -0
- package/cli/commands/backend-create.js +56 -15
- package/cli/commands/bundle-create.js +39 -7
- package/cli/commands/monitor.js +72 -51
- package/cli/index.js +10 -24
- package/cli/package.json +11 -3
- package/dist/esm/app-review/app-review-manager.js +0 -1
- package/dist/esm/app-review/index.js +0 -1
- package/dist/esm/app-review/platform-review-handler.js +0 -1
- package/dist/esm/app-review/review-conditions-checker.js +0 -1
- package/dist/esm/app-review/review-rate-limiter.js +0 -1
- package/dist/esm/app-review/types.js +0 -1
- package/dist/esm/app-update/app-update-checker.js +0 -1
- package/dist/esm/app-update/app-update-installer.d.ts +1 -0
- package/dist/esm/app-update/app-update-installer.js +19 -8
- package/dist/esm/app-update/app-update-manager.js +0 -1
- package/dist/esm/app-update/app-update-notifier.js +0 -1
- package/dist/esm/app-update/index.js +0 -1
- package/dist/esm/app-update/platform-app-update.js +12 -3
- package/dist/esm/app-update/types.js +0 -1
- package/dist/esm/background-update/background-scheduler.js +0 -1
- package/dist/esm/background-update/index.js +0 -1
- package/dist/esm/background-update/notification-manager.js +0 -1
- package/dist/esm/config/support.js +0 -1
- package/dist/esm/core/analytics.d.ts +13 -0
- package/dist/esm/core/analytics.js +15 -1
- package/dist/esm/core/cache-manager.js +0 -1
- package/dist/esm/core/config.d.ts +6 -30
- package/dist/esm/core/config.js +1 -8
- package/dist/esm/core/errors.d.ts +1 -0
- package/dist/esm/core/errors.js +1 -1
- package/dist/esm/core/event-emitter.d.ts +0 -3
- package/dist/esm/core/event-emitter.js +8 -3
- package/dist/esm/core/logger.js +0 -1
- package/dist/esm/core/performance.js +0 -1
- package/dist/esm/core/plugin-manager.js +3 -1
- package/dist/esm/core/security.d.ts +22 -3
- package/dist/esm/core/security.js +46 -7
- package/dist/esm/definitions.d.ts +13 -40
- package/dist/esm/definitions.js +0 -1
- package/dist/esm/index.d.ts +3 -4
- package/dist/esm/index.js +3 -3
- package/dist/esm/live-update/bundle-manager.d.ts +8 -0
- package/dist/esm/live-update/bundle-manager.js +20 -1
- package/dist/esm/live-update/certificate-pinning.js +0 -1
- package/dist/esm/live-update/delta-processor.d.ts +1 -1
- package/dist/esm/live-update/delta-processor.js +3 -1
- package/dist/esm/live-update/download-manager.d.ts +36 -5
- package/dist/esm/live-update/download-manager.js +70 -24
- package/dist/esm/live-update/rollout-checker.d.ts +1 -1
- package/dist/esm/live-update/rollout-checker.js +5 -6
- package/dist/esm/live-update/update-manager.d.ts +12 -1
- package/dist/esm/live-update/update-manager.js +38 -11
- package/dist/esm/live-update/version-manager.d.ts +9 -12
- package/dist/esm/live-update/version-manager.js +40 -68
- package/dist/esm/plugin.js +82 -89
- package/dist/esm/security/crypto.js +11 -7
- package/dist/esm/security/validator.js +0 -1
- package/dist/esm/types/rollout.d.ts +85 -0
- package/dist/esm/types/rollout.js +25 -0
- package/dist/esm/web.d.ts +26 -1
- package/dist/esm/web.js +214 -75
- package/dist/plugin.cjs.js +1 -2
- package/dist/plugin.esm.js +1 -2
- package/dist/plugin.js +2 -3
- package/docs/AGENTS.md +38 -0
- package/docs/CHANGELOG.md +275 -0
- package/docs/CLAUDE.md +101 -0
- package/docs/MANUAL-TASKS.md +17 -0
- package/docs/MARKETING_WEBSITE_TRACKER.md +18 -2
- package/docs/MIGRATION.md +170 -0
- package/docs/PACKAGES.md +167 -0
- package/docs/PERFORMANCE.md +110 -0
- package/docs/PROJECT_COMPLETION_TRACKER.md +4 -35
- package/docs/README.md +12 -2
- package/docs/REMAINING_FEATURES.md +123 -76
- package/docs/ROADMAP.md +200 -120
- package/docs/SECURITY-IF-REPO-PUBLIC.md +232 -0
- package/docs/TESTING_REQUIREMENTS.md +1 -112
- package/docs/ai-knowledge-base/00-project-profile.md +38 -0
- package/docs/ai-knowledge-base/01-features.md +46 -0
- package/docs/ai-knowledge-base/02-routes.md +72 -0
- package/docs/ai-knowledge-base/03-tech-stack.md +57 -0
- package/docs/ai-knowledge-base/README.md +23 -0
- package/docs/analytics-tracking.md +37 -0
- package/docs/capacitor-official-plugins.md +46 -0
- package/docs/capawesome-plugins.md +29 -0
- package/docs/deployment/HOSTINGER_DEPLOY.md +370 -0
- package/docs/deployment/PRODUCTION-DEPLOY-CHECKLIST.md +184 -0
- package/docs/docs-site/plan.md +201 -0
- package/docs/docs-site/scope.md +127 -0
- package/docs/docs-site/tracker.json +235 -0
- package/docs/error-handling-tracking.md +37 -0
- package/docs/features/laravel-nova-backend/ASSESSMENT-SUMMARY.md +96 -0
- package/docs/features/laravel-nova-backend/IMPLEMENTATION-PLAN.md +504 -0
- package/docs/features/laravel-nova-backend/progress-tracker.json +184 -0
- package/docs/guides/testing-guide.md +15 -41
- package/docs/package-audit.md +41 -0
- package/docs/play-store/ASO-METADATA.md +5 -0
- package/docs/play-store/DATA-SAFETY.md +5 -0
- package/docs/play-store/DECLARATIONS.md +5 -0
- package/docs/play-store/README.md +27 -0
- package/docs/play-store/RELEASE-NOTES.md +99 -0
- package/docs/play-store/RELEASE-STEPS.md +6 -0
- package/docs/play-store/STORE-LISTING.md +7 -0
- package/docs/play-store/SUBMISSION-CHECKLIST.md +5 -0
- package/docs/production-readiness.md +1 -1
- package/docs/project-audit/2026-05-16/00-FINALIZATION-PLAN.md +123 -0
- package/docs/project-audit/2026-05-16/01-BATCH-PLAN.md +227 -0
- package/docs/project-audit/2026-05-16/02-AUDIT-FINDINGS.md +144 -0
- package/docs/project-audit/2026-05-16/sessions/batch-01.md +42 -0
- package/docs/project-audit/2026-05-16/sessions/batch-02.md +74 -0
- package/docs/project-audit/2026-05-16/sessions/batch-03.md +71 -0
- package/docs/project-audit/2026-05-16/sessions/batch-04.md +88 -0
- package/docs/project-audit/2026-05-16/sessions/batch-05.md +63 -0
- package/docs/project-audit/2026-05-16/sessions/batch-06.md +103 -0
- package/docs/project-audit/2026-05-16/sessions/batch-07.md +61 -0
- package/docs/project-audit/2026-05-16/sessions/batch-08.md +101 -0
- package/docs/project-audit/2026-05-16/sessions/batch-09.md +105 -0
- package/docs/project-audit/2026-05-16/sessions/batch-10.md +102 -0
- package/docs/project-audit/AUDIT-HISTORY.md +74 -0
- package/docs/project-audit/BATCH-PLAN.md +168 -0
- package/docs/project-audit/MARKETING-WEBSITE-FINDINGS-2026-05-11.md +73 -0
- package/docs/project-audit/PRODUCTION-READINESS-AUDIT-2026-05-08.md +275 -0
- package/docs/project-finalization/00-tracker.json +60 -0
- package/docs/project-knowledge-base/01-system-overview.md +227 -0
- package/docs/project-knowledge-base/02-routes-pages-forms-users.md +352 -0
- package/docs/project-knowledge-base/03-tech-stack-modules-services.md +379 -0
- package/docs/project-knowledge-base/04-data-models-integrations.md +244 -0
- package/docs/project-knowledge-base/05-docs-corpus-inventory.md +256 -0
- package/docs/project-knowledge-base/06-operations-testing-legal-content.md +208 -0
- package/docs/project-knowledge-base/README.md +103 -0
- package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-05-19.md +81 -0
- package/docs/rules-tracker.md +102 -0
- package/docs/security/PRE-LAUNCH-PENTEST-CHECKLIST.md +116 -0
- package/docs/seo-aeo-rules.json +3043 -0
- package/docs/social-media-marketing/README.md +81 -0
- package/docs/social-media-marketing/posts-batch-01.md +613 -0
- package/docs/social-media-marketing/posts-batch-02.md +528 -0
- package/docs/social-media-marketing/whatsapp-messages-batch-01.md +458 -0
- package/docs/social-media-marketing/whatsapp-status-batch-01.md +355 -0
- package/docs/tracking/finalization-2026-05-16-tracker.json +346 -0
- package/docs/tracking/full-audit-tracker.json +121 -0
- package/docs/tracking/production-readiness-audit-tracker.json +429 -0
- package/docs/tracking/seo-checklist-tracker.json +333 -0
- package/ios/Plugin/BackgroundUpdate/BackgroundUpdatePlugin.swift +66 -9
- package/ios/Plugin/LiveUpdate/LiveUpdatePlugin.swift +306 -52
- package/ios/Plugin/NativeUpdatePlugin.swift +22 -9
- package/ios/Plugin/Security/SecurityManager.swift +13 -14
- package/package.json +37 -38
- package/cli/node_modules/.yarn-integrity +0 -16
- package/cli/node_modules/commander/LICENSE +0 -22
- package/cli/node_modules/commander/Readme.md +0 -1148
- package/cli/node_modules/commander/esm.mjs +0 -16
- package/cli/node_modules/commander/index.js +0 -26
- package/cli/node_modules/commander/lib/argument.js +0 -145
- package/cli/node_modules/commander/lib/command.js +0 -2179
- package/cli/node_modules/commander/lib/error.js +0 -43
- package/cli/node_modules/commander/lib/help.js +0 -462
- package/cli/node_modules/commander/lib/option.js +0 -329
- package/cli/node_modules/commander/lib/suggestSimilar.js +0 -100
- package/cli/node_modules/commander/package-support.json +0 -16
- package/cli/node_modules/commander/package.json +0 -80
- package/cli/node_modules/commander/typings/esm.d.mts +0 -3
- package/cli/node_modules/commander/typings/index.d.ts +0 -884
- package/cli/yarn.lock +0 -8
- package/dist/esm/__tests__/bundle-manager.test.d.ts +0 -1
- package/dist/esm/__tests__/bundle-manager.test.js +0 -151
- package/dist/esm/__tests__/bundle-manager.test.js.map +0 -1
- package/dist/esm/__tests__/config.test.d.ts +0 -1
- package/dist/esm/__tests__/config.test.js +0 -70
- package/dist/esm/__tests__/config.test.js.map +0 -1
- package/dist/esm/__tests__/delta-processor.test.d.ts +0 -1
- package/dist/esm/__tests__/delta-processor.test.js +0 -77
- package/dist/esm/__tests__/delta-processor.test.js.map +0 -1
- package/dist/esm/__tests__/firestore-schema.test.d.ts +0 -1
- package/dist/esm/__tests__/firestore-schema.test.js +0 -74
- package/dist/esm/__tests__/firestore-schema.test.js.map +0 -1
- package/dist/esm/__tests__/integration.test.d.ts +0 -1
- package/dist/esm/__tests__/integration.test.js +0 -78
- package/dist/esm/__tests__/integration.test.js.map +0 -1
- package/dist/esm/__tests__/manifest-reader.test.d.ts +0 -1
- package/dist/esm/__tests__/manifest-reader.test.js +0 -271
- package/dist/esm/__tests__/manifest-reader.test.js.map +0 -1
- package/dist/esm/__tests__/rollout-checker.test.d.ts +0 -1
- package/dist/esm/__tests__/rollout-checker.test.js +0 -210
- package/dist/esm/__tests__/rollout-checker.test.js.map +0 -1
- package/dist/esm/__tests__/security.test.d.ts +0 -1
- package/dist/esm/__tests__/security.test.js +0 -54
- package/dist/esm/__tests__/security.test.js.map +0 -1
- package/dist/esm/__tests__/version-manager.test.d.ts +0 -1
- package/dist/esm/__tests__/version-manager.test.js +0 -45
- package/dist/esm/__tests__/version-manager.test.js.map +0 -1
- package/dist/esm/app-review/app-review-manager.js.map +0 -1
- package/dist/esm/app-review/index.js.map +0 -1
- package/dist/esm/app-review/platform-review-handler.js.map +0 -1
- package/dist/esm/app-review/review-conditions-checker.js.map +0 -1
- package/dist/esm/app-review/review-rate-limiter.js.map +0 -1
- package/dist/esm/app-review/types.js.map +0 -1
- package/dist/esm/app-update/app-update-checker.js.map +0 -1
- package/dist/esm/app-update/app-update-installer.js.map +0 -1
- package/dist/esm/app-update/app-update-manager.js.map +0 -1
- package/dist/esm/app-update/app-update-notifier.js.map +0 -1
- package/dist/esm/app-update/index.js.map +0 -1
- package/dist/esm/app-update/platform-app-update.js.map +0 -1
- package/dist/esm/app-update/types.js.map +0 -1
- package/dist/esm/background-update/background-scheduler.js.map +0 -1
- package/dist/esm/background-update/index.js.map +0 -1
- package/dist/esm/background-update/notification-manager.js.map +0 -1
- package/dist/esm/config/support.js.map +0 -1
- package/dist/esm/core/analytics.js.map +0 -1
- package/dist/esm/core/cache-manager.js.map +0 -1
- package/dist/esm/core/config.js.map +0 -1
- package/dist/esm/core/errors.js.map +0 -1
- package/dist/esm/core/event-emitter.js.map +0 -1
- package/dist/esm/core/logger.js.map +0 -1
- package/dist/esm/core/performance.js.map +0 -1
- package/dist/esm/core/plugin-manager.js.map +0 -1
- package/dist/esm/core/security.js.map +0 -1
- package/dist/esm/definitions.js.map +0 -1
- package/dist/esm/firestore/firestore-client.d.ts +0 -109
- package/dist/esm/firestore/firestore-client.js +0 -264
- package/dist/esm/firestore/firestore-client.js.map +0 -1
- package/dist/esm/firestore/index.d.ts +0 -11
- package/dist/esm/firestore/index.js +0 -11
- package/dist/esm/firestore/index.js.map +0 -1
- package/dist/esm/firestore/manifest-reader.d.ts +0 -87
- package/dist/esm/firestore/manifest-reader.js +0 -294
- package/dist/esm/firestore/manifest-reader.js.map +0 -1
- package/dist/esm/firestore/schema.d.ts +0 -507
- package/dist/esm/firestore/schema.js +0 -73
- package/dist/esm/firestore/schema.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/live-update/bundle-manager.js.map +0 -1
- package/dist/esm/live-update/certificate-pinning.js.map +0 -1
- package/dist/esm/live-update/delta-processor.js.map +0 -1
- package/dist/esm/live-update/download-manager.js.map +0 -1
- package/dist/esm/live-update/rollout-checker.js.map +0 -1
- package/dist/esm/live-update/update-manager.js.map +0 -1
- package/dist/esm/live-update/version-manager.js.map +0 -1
- package/dist/esm/plugin.js.map +0 -1
- package/dist/esm/security/crypto.js.map +0 -1
- package/dist/esm/security/validator.js.map +0 -1
- package/dist/esm/web.js.map +0 -1
- package/dist/plugin.cjs.js.map +0 -1
- package/dist/plugin.esm.js.map +0 -1
- package/dist/plugin.js.map +0 -1
- package/docs/FIREBASE_INTEGRATION_TRACKER.md +0 -321
- package/docs/FIREBASE_QUERIES_AND_INDEXES_AUDIT.md +0 -221
- package/docs/examples/firebase-backend-example.md +0 -27
- package/docs/guides/no-cost-backend-implementation-plan.md +0 -77
- package/docs/guides/no-cost-firestore-google-drive-backend.md +0 -60
- package/docs/play-console-rejection-rules.json +0 -428
- /package/docs/{MARKETING_WEBSITE_PLAN.md → archive/MARKETING_WEBSITE_PLAN.md} +0 -0
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
# Hostinger Deployment Guide
|
|
2
|
+
|
|
3
|
+
Step-by-step deploy of the Laravel + Nova backend to Hostinger Business
|
|
4
|
+
(shared hosting, SSH-enabled). Target URL:
|
|
5
|
+
**https://nativeupdatebe.aoneahsan.com**.
|
|
6
|
+
|
|
7
|
+
Tested against Hostinger hPanel, shared Business plan, PHP 8.2, MySQL.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 0. What you need before starting
|
|
12
|
+
|
|
13
|
+
| Item | Where to get it |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Hostinger SSH access | hPanel → Advanced → SSH Access → "Enable" |
|
|
16
|
+
| MySQL database | hPanel → Databases → MySQL Databases → Create |
|
|
17
|
+
| Nova license key | nova.laravel.com (account → licenses) |
|
|
18
|
+
| PayPal Live credentials | developer.paypal.com → My Apps & Credentials → Live |
|
|
19
|
+
| PayPal subscription plans | PayPal Dashboard → Subscriptions → Plans (create Pro + Enterprise, copy the `P-...` IDs) |
|
|
20
|
+
| PayPal webhook ID | Set up in step 4, skip for now |
|
|
21
|
+
| FilesHub API key | fileshub.zaions.com admin |
|
|
22
|
+
| Google OAuth client | console.cloud.google.com → APIs & Services → Credentials (used for both dashboard sign-in and Google Drive) |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 1. Build the production zip (local machine)
|
|
27
|
+
|
|
28
|
+
Already built by the maintainer. Current artifact lives at:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
production-deploy/nu-backend-YYYYMMDD-HHMMSS.zip
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
If you need to rebuild:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
cd /home/ahsan/Documents/01-code/projects/native-update/backend
|
|
38
|
+
|
|
39
|
+
# Ensure Nova + PayPal deps resolve
|
|
40
|
+
composer install
|
|
41
|
+
composer update --no-interaction
|
|
42
|
+
|
|
43
|
+
# Production-only deps + Vite build
|
|
44
|
+
php artisan optimize:clear
|
|
45
|
+
composer install --no-dev --optimize-autoloader --classmap-authoritative
|
|
46
|
+
npm run build
|
|
47
|
+
|
|
48
|
+
# Produce the zip
|
|
49
|
+
mkdir -p ../production-deploy
|
|
50
|
+
zip -qr "../production-deploy/nu-backend-$(date +%Y%m%d-%H%M%S).zip" . \
|
|
51
|
+
-x "node_modules/*" ".git/*" "tests/*" ".env" ".env.*" \
|
|
52
|
+
"storage/logs/*.log" "storage/framework/cache/data/*" \
|
|
53
|
+
"storage/framework/sessions/*" "storage/framework/views/*.php" \
|
|
54
|
+
"*.sqlite" ".phpunit.result.cache" "*.DS_Store"
|
|
55
|
+
|
|
56
|
+
# Restore dev deps locally
|
|
57
|
+
composer install
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The zip is ~67 MB. Upload it to Hostinger via SFTP to `~/uploads/`.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 2. Hostinger hPanel one-time setup
|
|
65
|
+
|
|
66
|
+
1. **Subdomain**. hPanel → Domains → Subdomains → Create:
|
|
67
|
+
- Subdomain: `nativeupdatebe`
|
|
68
|
+
- Domain: `aoneahsan.com`
|
|
69
|
+
- Document root: leave as Hostinger's default for now; we'll symlink
|
|
70
|
+
it to Laravel's `public/` in step 3.
|
|
71
|
+
|
|
72
|
+
2. **Database**. hPanel → Databases → MySQL Databases → Create:
|
|
73
|
+
- DB name: `nativeupdate_backend` (Hostinger will prefix with your user)
|
|
74
|
+
- User: `nativeupdate_user`
|
|
75
|
+
- Password: generate a strong one; save it.
|
|
76
|
+
|
|
77
|
+
3. **SSH**. hPanel → Advanced → SSH Access → Enable (if not already).
|
|
78
|
+
Note the port (usually 65002) and username.
|
|
79
|
+
|
|
80
|
+
4. **Upload the deploy zip** via hPanel File Manager (or SFTP) to
|
|
81
|
+
`~/uploads/`. (No Firebase credentials file is needed — auth is Google
|
|
82
|
+
Socialite + Sanctum, configured entirely via `.env`.)
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 3. SSH deploy (first time)
|
|
87
|
+
|
|
88
|
+
SSH in:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
ssh -p 65002 <USER>@<HOST>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Create the app directory one level above `public_html` and extract:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
cd ~/domains/nativeupdatebe.aoneahsan.com
|
|
98
|
+
mkdir -p app && cd app
|
|
99
|
+
unzip -q ~/uploads/nu-backend-*.zip -d .
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Point `public_html` at Laravel's `public/`:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
cd ~/domains/nativeupdatebe.aoneahsan.com
|
|
106
|
+
rm -rf public_html
|
|
107
|
+
ln -s app/public public_html
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Configure the environment:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
cd ~/domains/nativeupdatebe.aoneahsan.com/app
|
|
114
|
+
cp .env.example .env
|
|
115
|
+
nano .env
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Fill in the following (paste real values for each `_________` placeholder):
|
|
119
|
+
|
|
120
|
+
```dotenv
|
|
121
|
+
APP_NAME="Native Update"
|
|
122
|
+
APP_ENV=production
|
|
123
|
+
APP_KEY= # php artisan key:generate runs next
|
|
124
|
+
APP_DEBUG=false
|
|
125
|
+
APP_TIMEZONE=UTC
|
|
126
|
+
APP_URL=https://nativeupdatebe.aoneahsan.com
|
|
127
|
+
|
|
128
|
+
LOG_CHANNEL=daily
|
|
129
|
+
LOG_LEVEL=warning
|
|
130
|
+
|
|
131
|
+
# MySQL from step 2
|
|
132
|
+
DB_CONNECTION=mysql
|
|
133
|
+
DB_HOST=127.0.0.1
|
|
134
|
+
DB_PORT=3306
|
|
135
|
+
DB_DATABASE=_________
|
|
136
|
+
DB_USERNAME=_________
|
|
137
|
+
DB_PASSWORD=_________
|
|
138
|
+
|
|
139
|
+
# FilesHub
|
|
140
|
+
FILESHUB_BASE_URL=https://fileshub.zaions.com
|
|
141
|
+
FILESHUB_API_KEY=_________
|
|
142
|
+
FILESHUB_APP_ID=native-update
|
|
143
|
+
|
|
144
|
+
# Sanctum (OAuth-issued bearer tokens)
|
|
145
|
+
SANCTUM_TOKEN_EXPIRATION=10080 # minutes (7 days)
|
|
146
|
+
|
|
147
|
+
# Frontend (for OAuth redirect back to the dashboard SPA)
|
|
148
|
+
FRONTEND_URL=https://nativeupdate.aoneahsan.com
|
|
149
|
+
|
|
150
|
+
# Google OAuth — sign-in (Socialite) AND Google Drive integration
|
|
151
|
+
GOOGLE_CLIENT_ID=_________
|
|
152
|
+
GOOGLE_CLIENT_SECRET=_________
|
|
153
|
+
GOOGLE_REDIRECT_URI=${APP_URL}/api/auth/google/callback
|
|
154
|
+
GOOGLE_DRIVE_REDIRECT_URI=${APP_URL}/api/dashboard/google-drive/callback
|
|
155
|
+
|
|
156
|
+
# PayPal (live)
|
|
157
|
+
PAYPAL_MODE=live
|
|
158
|
+
PAYPAL_LIVE_CLIENT_ID=_________
|
|
159
|
+
PAYPAL_LIVE_CLIENT_SECRET=_________
|
|
160
|
+
PAYPAL_PLAN_PRO=P-_________
|
|
161
|
+
PAYPAL_PLAN_ENTERPRISE=P-_________
|
|
162
|
+
PAYPAL_WEBHOOK_ID= # fill in step 4
|
|
163
|
+
|
|
164
|
+
# Nova
|
|
165
|
+
NOVA_LICENSE_KEY=_________
|
|
166
|
+
|
|
167
|
+
# Admin
|
|
168
|
+
ADMIN_EMAILS=aoneahsan@gmail.com
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Generate APP_KEY and lock down permissions:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
php artisan key:generate --force
|
|
175
|
+
|
|
176
|
+
find . -type d -exec chmod 755 {} \;
|
|
177
|
+
find . -type f -exec chmod 644 {} \;
|
|
178
|
+
chmod -R 775 storage bootstrap/cache
|
|
179
|
+
chmod 600 .env
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
> The full, authoritative env contract (every `[REQUIRED]`/`[OPTIONAL]` key with its purpose)
|
|
183
|
+
> is `backend/.env.example`. Populate the server `.env` from it — an incomplete `.env` (missing
|
|
184
|
+
> a required key) is a common cause of a booting-but-500 backend.
|
|
185
|
+
|
|
186
|
+
Run migrations and cache config for production:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
php artisan migrate --force
|
|
190
|
+
php artisan storage:link
|
|
191
|
+
php artisan config:cache
|
|
192
|
+
php artisan route:cache
|
|
193
|
+
php artisan view:cache
|
|
194
|
+
php artisan nova:publish
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Smoke-test:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
curl -sS https://nativeupdatebe.aoneahsan.com/api/health
|
|
201
|
+
# Expected: {"status":"ok","app":"Native Update","env":"production","time":"..."}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Log in to Nova at `https://nativeupdatebe.aoneahsan.com/nova` with an
|
|
205
|
+
email listed in `ADMIN_EMAILS` (sign in via Google — Socialite issues the
|
|
206
|
+
Sanctum session; the first sign-in by an `ADMIN_EMAILS` address is granted
|
|
207
|
+
the `super-admin` role) and verify the Apps / Builds / ApiKeys /
|
|
208
|
+
SigningKeys / Subscriptions resources render.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 4. Register the PayPal webhook
|
|
213
|
+
|
|
214
|
+
In PayPal Dashboard → Webhooks → Add Webhook:
|
|
215
|
+
|
|
216
|
+
- URL: `https://nativeupdatebe.aoneahsan.com/api/webhooks/paypal`
|
|
217
|
+
- Events (minimum):
|
|
218
|
+
- `BILLING.SUBSCRIPTION.ACTIVATED`
|
|
219
|
+
- `BILLING.SUBSCRIPTION.CANCELLED`
|
|
220
|
+
- `BILLING.SUBSCRIPTION.SUSPENDED`
|
|
221
|
+
- `BILLING.SUBSCRIPTION.EXPIRED`
|
|
222
|
+
- `BILLING.SUBSCRIPTION.PAYMENT.FAILED`
|
|
223
|
+
- `PAYMENT.SALE.COMPLETED`
|
|
224
|
+
|
|
225
|
+
Copy the webhook ID PayPal assigns (starts with `WH-`). SSH back in:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
cd ~/domains/nativeupdatebe.aoneahsan.com/app
|
|
229
|
+
sed -i 's|^PAYPAL_WEBHOOK_ID=.*|PAYPAL_WEBHOOK_ID=WH-xxxxxxxxxxxx|' .env
|
|
230
|
+
php artisan config:cache
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Run PayPal's Webhook Simulator from the dashboard to fire a
|
|
234
|
+
`BILLING.SUBSCRIPTION.ACTIVATED` event. Expected response: `200 ok`.
|
|
235
|
+
Check the logs:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
tail -n 100 ~/domains/nativeupdatebe.aoneahsan.com/app/storage/logs/laravel-*.log
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Should contain `PayPal webhook received` or `PayPal subscription activated`.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## 5. Cron for scheduled tasks (REQUIRED as of v3.1.0)
|
|
246
|
+
|
|
247
|
+
The backend now runs a scheduled job: `analytics:cleanup` (defined in
|
|
248
|
+
`routes/console.php`) prunes old `device_activities` **and**
|
|
249
|
+
`analytics_events` rows monthly. Without the scheduler cron below those
|
|
250
|
+
tables grow unbounded, so this cron is now required, not optional.
|
|
251
|
+
|
|
252
|
+
hPanel → Advanced → Cron Jobs → Add (runs every minute; Laravel's
|
|
253
|
+
scheduler decides internally when each job is actually due):
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
* * * * * cd ~/domains/nativeupdatebe.aoneahsan.com/app && php artisan schedule:run >/dev/null 2>&1
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 6. Re-deploys
|
|
262
|
+
|
|
263
|
+
For each subsequent release:
|
|
264
|
+
|
|
265
|
+
1. Rebuild the zip locally (see step 1).
|
|
266
|
+
2. SFTP it to `~/uploads/nu-backend-NEW.zip`.
|
|
267
|
+
3. SSH in and atomic-swap:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
cd ~/domains/nativeupdatebe.aoneahsan.com
|
|
271
|
+
mv app app.old
|
|
272
|
+
mkdir app && cd app
|
|
273
|
+
unzip -q ~/uploads/nu-backend-NEW.zip -d .
|
|
274
|
+
|
|
275
|
+
# Carry over secrets + stored files
|
|
276
|
+
cp ../app.old/.env .env
|
|
277
|
+
cp -a ../app.old/storage/app storage/ 2>/dev/null || true
|
|
278
|
+
|
|
279
|
+
# Fix perms
|
|
280
|
+
find . -type d -exec chmod 755 {} \;
|
|
281
|
+
find . -type f -exec chmod 644 {} \;
|
|
282
|
+
chmod -R 775 storage bootstrap/cache
|
|
283
|
+
chmod 600 .env
|
|
284
|
+
|
|
285
|
+
# Rebuild caches + apply migrations
|
|
286
|
+
php artisan migrate --force
|
|
287
|
+
php artisan config:cache
|
|
288
|
+
php artisan route:cache
|
|
289
|
+
php artisan view:cache
|
|
290
|
+
|
|
291
|
+
# Re-point public_html (only needed if symlink was lost)
|
|
292
|
+
cd ..
|
|
293
|
+
rm -rf public_html && ln -s app/public public_html
|
|
294
|
+
|
|
295
|
+
# Smoke-test then clean up old release
|
|
296
|
+
curl -sS https://nativeupdatebe.aoneahsan.com/api/health
|
|
297
|
+
rm -rf app.old
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## 7. Rollback
|
|
303
|
+
|
|
304
|
+
If a deploy breaks things and you didn't delete `app.old` yet:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
cd ~/domains/nativeupdatebe.aoneahsan.com
|
|
308
|
+
rm -rf app
|
|
309
|
+
mv app.old app
|
|
310
|
+
rm -rf public_html && ln -s app/public public_html
|
|
311
|
+
php artisan config:cache
|
|
312
|
+
curl -sS https://nativeupdatebe.aoneahsan.com/api/health
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Migrations that were applied on the new release may need a manual
|
|
316
|
+
`php artisan migrate:rollback --step=N` depending on what they changed.
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## 8. Known Hostinger constraints
|
|
321
|
+
|
|
322
|
+
- **No persistent queue workers needed.** The backend uses
|
|
323
|
+
`QUEUE_CONNECTION=database`, but the only async work — the update-check
|
|
324
|
+
device-activity + analytics writes — is dispatched with
|
|
325
|
+
`dispatch(...)->afterResponse()`, which runs **in-process** during the
|
|
326
|
+
request's terminating phase (no `queue:work` daemon required). If a
|
|
327
|
+
future feature dispatches a real queued job, add a 1-minute cron running
|
|
328
|
+
`php artisan queue:work --stop-when-empty`.
|
|
329
|
+
- **No Redis.** Cache + sessions use the MySQL `CACHE_STORE=database`
|
|
330
|
+
driver. The v3.1.0 latest-build cache (`App::getLatestBuildForChannel`,
|
|
331
|
+
45s TTL) works with any driver, including `database` and `file`.
|
|
332
|
+
- **PHP 8.3+ is required** (Laravel 13 / `composer.json` `php: ^8.3`).
|
|
333
|
+
Select PHP 8.3 or newer in hPanel → Advanced → PHP Configuration before
|
|
334
|
+
deploying; PHP 8.2 will fail to boot the framework.
|
|
335
|
+
- **Node/npm are not available via SSH on all plans.** The Vite build step
|
|
336
|
+
runs locally; the zip ships pre-built `public/build/` assets.
|
|
337
|
+
- **Nova admin assets** are served from `public/vendor/nova/...` after
|
|
338
|
+
`php artisan nova:publish` — re-run after every deploy.
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## 9. v3.1.0 deploy notes
|
|
343
|
+
|
|
344
|
+
This release adds one migration and shifts two hot-path writes; nothing in
|
|
345
|
+
the standard deploy flow above changes, but confirm each of these:
|
|
346
|
+
|
|
347
|
+
1. **Run the new migration.** `php artisan migrate --force` applies
|
|
348
|
+
`2026_07_02_000001_extend_builds_channel_index` (adds a covering index
|
|
349
|
+
`builds_channel_lookup_idx` on `builds(app_id, channel, status,
|
|
350
|
+
created_at)`). Purely additive — no data change, safe to run live.
|
|
351
|
+
2. **Re-cache config/routes/views** after the swap (already in the deploy
|
|
352
|
+
steps): `php artisan config:cache && php artisan route:cache &&
|
|
353
|
+
php artisan view:cache`.
|
|
354
|
+
3. **Confirm the scheduler cron** from section 5 exists — `analytics:cleanup`
|
|
355
|
+
now also prunes `analytics_events`, so the monthly run matters.
|
|
356
|
+
4. **No queue worker required** — see section 8 (the update-check writes run
|
|
357
|
+
via `afterResponse()`).
|
|
358
|
+
|
|
359
|
+
### Large bundle downloads (optional)
|
|
360
|
+
|
|
361
|
+
`BundleController@download` streams bundle files through PHP (a
|
|
362
|
+
`StreamedResponse`). This is deliberate: it keeps the signed-URL / auth
|
|
363
|
+
check as the single chokepoint in front of every download. On a server with
|
|
364
|
+
`mod_xsendfile` (Apache) or `X-Accel-Redirect` (nginx), that streaming can
|
|
365
|
+
be offloaded to the web server after the auth check by returning an
|
|
366
|
+
`X-Sendfile` / `X-Accel-Redirect` header instead of the file body — freeing
|
|
367
|
+
the PHP-FPM worker for the duration of the transfer. This is a documented
|
|
368
|
+
option only; it is **not implemented** (Hostinger shared hosting does not
|
|
369
|
+
expose the needed web-server config, and the current streaming approach is
|
|
370
|
+
correct and safe as-is).
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Production Deployment Checklist — Native Update Backend (Laravel 13 + Nova 5)
|
|
2
|
+
|
|
3
|
+
**Last updated:** 2026-07-02
|
|
4
|
+
**Scope:** `backend/` only. The plugin (`/`) and website (`website/`) ship via npm/Firebase Hosting respectively and have their own pipelines.
|
|
5
|
+
**Companion:** `docs/deployment/HOSTINGER_DEPLOY.md` (host-specific steps for Hostinger).
|
|
6
|
+
|
|
7
|
+
This checklist is the source of truth for "is this deploy safe to ship?". Run through it on every release until automation in `.github/workflows/release.yml` (Batch 8) replaces the manual gates.
|
|
8
|
+
|
|
9
|
+
> **v3.1.0 deploy notes:** (1) Requires **PHP ≥ 8.3** (Laravel 13). (2) Runs one new migration
|
|
10
|
+
> `2026_07_02_000001_extend_builds_channel_index` (additive covering index — safe live). (3) The
|
|
11
|
+
> latest-build cache (`App::getLatestBuildForChannel`, 45s TTL) works with any `CACHE_STORE` incl.
|
|
12
|
+
> `database`/`file`. (4) The update-check device/analytics writes use `dispatch(...)->afterResponse()`
|
|
13
|
+
> — in-process, **no queue worker required**. (5) `analytics:cleanup` now prunes `analytics_events`
|
|
14
|
+
> too, so the scheduler cron (§5) is **required**, not optional.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 0 · Pre-flight (local machine, before pushing the deploy zip)
|
|
19
|
+
|
|
20
|
+
- [ ] `git status` is clean on the branch you're shipping from.
|
|
21
|
+
- [ ] `git pull --rebase` against the deploy branch — no unmerged remote work.
|
|
22
|
+
- [ ] `composer install --no-interaction` succeeds.
|
|
23
|
+
- [ ] `php artisan test` is **green** (all Feature + Unit tests pass).
|
|
24
|
+
- [ ] `php artisan route:list --except-vendor` shows the routes you expect (no accidental new public routes).
|
|
25
|
+
- [ ] `php -l app/` and `php -l routes/` report no syntax errors.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 1 · `.env` for production (NOT committed; copied to server)
|
|
30
|
+
|
|
31
|
+
The committed `.env.example` has `[REQUIRED]` tags on every var. On the server, populate a real `.env` with the production values. Verify each of these is set correctly:
|
|
32
|
+
|
|
33
|
+
- [ ] `APP_ENV=production`
|
|
34
|
+
- [ ] `APP_DEBUG=false` — **never** `true` in production (leaks stack traces, env, DB creds).
|
|
35
|
+
- [ ] `APP_KEY` — generated once via `php artisan key:generate` on the server (or copied from a sealed vault). Never re-rotate without re-encrypting cookies/sessions.
|
|
36
|
+
- [ ] `APP_URL=https://nativeupdatebe.aoneahsan.com`
|
|
37
|
+
- [ ] `LOG_CHANNEL=daily`, `LOG_LEVEL=warning` (or `error`) — `debug` floods disk and leaks request shapes.
|
|
38
|
+
- [ ] `CORS_ALLOWED_ORIGINS=https://nativeupdate.aoneahsan.com[,...]` — explicit list, no wildcards.
|
|
39
|
+
- [ ] DB creds (`DB_HOST`, `DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD`) — production DB, not staging.
|
|
40
|
+
- [ ] FilesHub: `FILESHUB_API_KEY`, `FILESHUB_BASE_URL`, `FILESHUB_APP_ID=native-update`.
|
|
41
|
+
- [ ] Sanctum: `SANCTUM_TOKEN_EXPIRATION=10080` (minutes — 7 days; tune for security/UX trade-off).
|
|
42
|
+
- [ ] Google OAuth (Socialite sign-in + Drive picker): `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`, `GOOGLE_REDIRECT_URI=${APP_URL}/api/auth/google/callback`, `GOOGLE_DRIVE_REDIRECT_URI=${APP_URL}/api/dashboard/google-drive/callback`. Both redirect URIs must be registered in Google Cloud Console for the OAuth client.
|
|
43
|
+
- [ ] PayPal: `PAYPAL_MODE=live`, `PAYPAL_LIVE_*` filled, `PAYPAL_PLAN_PRO`, `PAYPAL_PLAN_ENTERPRISE`, `PAYPAL_WEBHOOK_ID`.
|
|
44
|
+
- [ ] RBAC bootstrap: `ADMIN_EMAILS=ahsan@…[,…]` — first sign-in by any of these emails auto-assigns `super-admin` via spatie/laravel-permission.
|
|
45
|
+
- [ ] Cache + queue: `CACHE_STORE=redis` (recommended for prod), `QUEUE_CONNECTION=redis` if Redis is available. Keep `database` only on tiny single-server deploys, and ensure `queue:work` is daemonized (see step 4).
|
|
46
|
+
- [ ] File permissions on `.env`: `chmod 640` and owner = web user. NEVER world-readable.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 2 · Deploy artifact (zip)
|
|
51
|
+
|
|
52
|
+
The `backend/CLAUDE.md` "Production Deployment Zip Standard" section is the canonical zip recipe. Quick version:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
cd backend
|
|
56
|
+
php artisan optimize:clear
|
|
57
|
+
composer install --no-dev --optimize-autoloader --classmap-authoritative
|
|
58
|
+
npm ci && npm run build # builds Vite assets if Nova-themed
|
|
59
|
+
# zip into ../production-deploy/backend-production-YYYYMMDD-HHMMSS.zip
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
After zipping:
|
|
63
|
+
```bash
|
|
64
|
+
composer install # restore dev deps locally so tests still work
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- [ ] Zip excludes `tests/`, `node_modules/`, `.git/`, `*.sqlite`, `storage/logs/*.log`, `storage/framework/{cache/data,sessions,views}/*`.
|
|
68
|
+
- [ ] Zip includes `vendor/` (production-only), built `public/build/` Vite assets, `composer.lock`, `package-lock.json`.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 3 · On-server deploy (after upload + extract)
|
|
73
|
+
|
|
74
|
+
Run these in order on the server, as the web user:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# 1. Install production deps if you didn't ship vendor/
|
|
78
|
+
composer install --no-dev --optimize-autoloader
|
|
79
|
+
|
|
80
|
+
# 2. Build front-end assets if not pre-built (yarn, not npm; usually pre-built in the zip)
|
|
81
|
+
yarn install && yarn build
|
|
82
|
+
|
|
83
|
+
# 3. Run migrations against production DB (forced — no prompt)
|
|
84
|
+
php artisan migrate --force
|
|
85
|
+
|
|
86
|
+
# 4. Symlink storage if first deploy
|
|
87
|
+
php artisan storage:link
|
|
88
|
+
|
|
89
|
+
# 5. Cache config + routes + views (don't skip — speeds boot 5–10x)
|
|
90
|
+
php artisan config:cache
|
|
91
|
+
php artisan route:cache
|
|
92
|
+
php artisan view:cache
|
|
93
|
+
|
|
94
|
+
# 6. Refresh permissions on storage + bootstrap/cache
|
|
95
|
+
chown -R www-data:www-data storage bootstrap/cache
|
|
96
|
+
chmod -R u+rwX,g+rX,o-rwx storage bootstrap/cache
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
- [ ] `php artisan about` reports `APP_DEBUG=false`, correct DB, correct queue/cache drivers.
|
|
100
|
+
- [ ] `php artisan health-check` (or hit `/up`) returns 200.
|
|
101
|
+
- [ ] Curl an API endpoint with a known-bad token — expect `401`, not a stack trace.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 4 · Long-running processes (must be daemonized)
|
|
106
|
+
|
|
107
|
+
`QUEUE_CONNECTION=database` (or `redis`) means jobs only run when a worker is alive. Without this, PayPal webhook handling, future analytics rollups, etc. will pile up silently.
|
|
108
|
+
|
|
109
|
+
- [ ] systemd unit OR supervisor entry that runs `php artisan queue:work --tries=3 --max-time=3600` on boot.
|
|
110
|
+
- [ ] Worker auto-restarts on failure.
|
|
111
|
+
- [ ] Worker reload on deploy: `php artisan queue:restart` is run at end of step 3.
|
|
112
|
+
- [ ] Log rotation configured for `storage/logs/laravel-*.log` (Laravel's `daily` channel rotates by date but doesn't prune).
|
|
113
|
+
|
|
114
|
+
If using Horizon (Redis):
|
|
115
|
+
- [ ] `horizon` service is up.
|
|
116
|
+
- [ ] `/horizon` route is admin-gated (NOT publicly accessible).
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 5 · Scheduler cron (if using `app/Console/Kernel.php` schedule)
|
|
121
|
+
|
|
122
|
+
Every Laravel project that uses `Schedule::command(...)` needs:
|
|
123
|
+
|
|
124
|
+
```cron
|
|
125
|
+
* * * * * cd /var/www/nativeupdatebe && php artisan schedule:run >> /dev/null 2>&1
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
- [ ] Cron entry exists for the web user.
|
|
129
|
+
- [ ] `php artisan schedule:list` shows the expected scheduled jobs.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 6 · Security gates
|
|
134
|
+
|
|
135
|
+
- [ ] HTTPS is forced at the web-server level (nginx 301 from `:80`, or Cloudflare full-strict).
|
|
136
|
+
- [ ] HSTS header is set with `max-age=31536000; includeSubDomains; preload`.
|
|
137
|
+
- [ ] `/.env`, `/storage/`, `/.git/`, `/composer.json` return 404 over HTTP (not the file). Test with `curl -I`.
|
|
138
|
+
- [ ] `/nova` is reachable but rejects non-super-admin users (test with a `user`-role account → redirect / 403).
|
|
139
|
+
- [ ] `/horizon` (if used) is admin-gated.
|
|
140
|
+
- [ ] PayPal webhook (`/api/webhooks/paypal`) verifies signatures — test by POSTing junk; expect 401.
|
|
141
|
+
- [ ] Rate-limit on `/api/v1/updates/check` (configured via `throttle:` middleware) — verify by sending 60+ requests; expect 429.
|
|
142
|
+
- [ ] CORS preflight: `curl -X OPTIONS -H "Origin: https://evil.example" https://nativeupdatebe.aoneahsan.com/api/v1/updates/check` returns no `Access-Control-Allow-Origin` for the bogus origin (config/cors.php uses an explicit allowlist).
|
|
143
|
+
- [ ] RBAC bootstrap: every email listed in `ADMIN_EMAILS` will auto-receive the `super-admin` role on first sign-in. Verify the list matches the product stance (invite-only via `ADMIN_EMAILS` + manual `php artisan native-update:role-assign` for adds; open signup = leave `ADMIN_EMAILS` empty so everyone joins as `user`).
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 7 · Post-deploy smoke
|
|
148
|
+
|
|
149
|
+
- [ ] Sign in via Google OAuth on the website dashboard — token issued, Nova accessible for any `super-admin`.
|
|
150
|
+
- [ ] Create an App in the dashboard — row appears in DB.
|
|
151
|
+
- [ ] Generate an API key — works.
|
|
152
|
+
- [ ] Hit `/api/v1/updates/check` from a real device or curl with a valid `X-API-Key` and `X-Device-ID` — returns 200 + manifest.
|
|
153
|
+
- [ ] Trigger a PayPal sandbox subscription end-to-end (in sandbox mode) and verify the webhook lands as a row update.
|
|
154
|
+
- [ ] Tail `storage/logs/laravel-$(date +%F).log` for 5 minutes — no `error`/`emergency` lines.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 8 · Rollback plan
|
|
159
|
+
|
|
160
|
+
- [ ] Previous deploy's zip is preserved in `production-deploy/` (immutable artifact name).
|
|
161
|
+
- [ ] DB migrations were reversible OR a snapshot was taken pre-migration.
|
|
162
|
+
- [ ] Rollback procedure is one of: `(a)` swap symlinks back to the prior release dir, `(b)` re-extract the prior zip.
|
|
163
|
+
- [ ] `queue:restart` is run after rollback so workers pick up the prior code path.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## 9 · Sign-off
|
|
168
|
+
|
|
169
|
+
| Field | Value |
|
|
170
|
+
|---|---|
|
|
171
|
+
| Release tag | _e.g. `backend-v1.4.0`_ |
|
|
172
|
+
| Deployed at | _UTC timestamp_ |
|
|
173
|
+
| Deployed by | _name + git commit SHA_ |
|
|
174
|
+
| Database snapshot | _path / id_ |
|
|
175
|
+
| Smoke-test result | _link to log_ |
|
|
176
|
+
| Approver | _name_ |
|
|
177
|
+
|
|
178
|
+
Append this row to `docs/deployment/DEPLOY-LOG.md` after each deploy.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Future automation (Batch 8)
|
|
183
|
+
|
|
184
|
+
This manual checklist will be reduced once `.github/workflows/release.yml` automates: artifact build, test gate, deployment-zip creation, and tag-pinned publish. Items in §1 (env), §6 (security gates), and §7 (post-deploy smoke) will remain manual because they touch live secrets and live traffic.
|