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.
Files changed (265) hide show
  1. package/Readme.md +35 -9
  2. package/android/manifest-additions.xml +28 -0
  3. package/android/src/main/AndroidManifest.xml +3 -7
  4. package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundNotificationManager.kt +21 -13
  5. package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdatePlugin.kt +15 -0
  6. package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateWorker.kt +23 -7
  7. package/android/src/main/java/com/aoneahsan/nativeupdate/LiveUpdatePlugin.kt +346 -31
  8. package/android/src/main/java/com/aoneahsan/nativeupdate/NativeUpdatePlugin.kt +32 -34
  9. package/android/src/main/java/com/aoneahsan/nativeupdate/NotificationActionReceiver.kt +10 -1
  10. package/android/src/main/java/com/aoneahsan/nativeupdate/SecurityManager.kt +18 -18
  11. package/cli/AGENTS.md +43 -0
  12. package/cli/CLAUDE.md +65 -0
  13. package/cli/commands/backend-create.js +56 -15
  14. package/cli/commands/bundle-create.js +39 -7
  15. package/cli/commands/monitor.js +72 -51
  16. package/cli/index.js +10 -24
  17. package/cli/package.json +11 -3
  18. package/dist/esm/app-review/app-review-manager.js +0 -1
  19. package/dist/esm/app-review/index.js +0 -1
  20. package/dist/esm/app-review/platform-review-handler.js +0 -1
  21. package/dist/esm/app-review/review-conditions-checker.js +0 -1
  22. package/dist/esm/app-review/review-rate-limiter.js +0 -1
  23. package/dist/esm/app-review/types.js +0 -1
  24. package/dist/esm/app-update/app-update-checker.js +0 -1
  25. package/dist/esm/app-update/app-update-installer.d.ts +1 -0
  26. package/dist/esm/app-update/app-update-installer.js +19 -8
  27. package/dist/esm/app-update/app-update-manager.js +0 -1
  28. package/dist/esm/app-update/app-update-notifier.js +0 -1
  29. package/dist/esm/app-update/index.js +0 -1
  30. package/dist/esm/app-update/platform-app-update.js +12 -3
  31. package/dist/esm/app-update/types.js +0 -1
  32. package/dist/esm/background-update/background-scheduler.js +0 -1
  33. package/dist/esm/background-update/index.js +0 -1
  34. package/dist/esm/background-update/notification-manager.js +0 -1
  35. package/dist/esm/config/support.js +0 -1
  36. package/dist/esm/core/analytics.d.ts +13 -0
  37. package/dist/esm/core/analytics.js +15 -1
  38. package/dist/esm/core/cache-manager.js +0 -1
  39. package/dist/esm/core/config.d.ts +6 -30
  40. package/dist/esm/core/config.js +1 -8
  41. package/dist/esm/core/errors.d.ts +1 -0
  42. package/dist/esm/core/errors.js +1 -1
  43. package/dist/esm/core/event-emitter.d.ts +0 -3
  44. package/dist/esm/core/event-emitter.js +8 -3
  45. package/dist/esm/core/logger.js +0 -1
  46. package/dist/esm/core/performance.js +0 -1
  47. package/dist/esm/core/plugin-manager.js +3 -1
  48. package/dist/esm/core/security.d.ts +22 -3
  49. package/dist/esm/core/security.js +46 -7
  50. package/dist/esm/definitions.d.ts +13 -40
  51. package/dist/esm/definitions.js +0 -1
  52. package/dist/esm/index.d.ts +3 -4
  53. package/dist/esm/index.js +3 -3
  54. package/dist/esm/live-update/bundle-manager.d.ts +8 -0
  55. package/dist/esm/live-update/bundle-manager.js +20 -1
  56. package/dist/esm/live-update/certificate-pinning.js +0 -1
  57. package/dist/esm/live-update/delta-processor.d.ts +1 -1
  58. package/dist/esm/live-update/delta-processor.js +3 -1
  59. package/dist/esm/live-update/download-manager.d.ts +36 -5
  60. package/dist/esm/live-update/download-manager.js +70 -24
  61. package/dist/esm/live-update/rollout-checker.d.ts +1 -1
  62. package/dist/esm/live-update/rollout-checker.js +5 -6
  63. package/dist/esm/live-update/update-manager.d.ts +12 -1
  64. package/dist/esm/live-update/update-manager.js +38 -11
  65. package/dist/esm/live-update/version-manager.d.ts +9 -12
  66. package/dist/esm/live-update/version-manager.js +40 -68
  67. package/dist/esm/plugin.js +82 -89
  68. package/dist/esm/security/crypto.js +11 -7
  69. package/dist/esm/security/validator.js +0 -1
  70. package/dist/esm/types/rollout.d.ts +85 -0
  71. package/dist/esm/types/rollout.js +25 -0
  72. package/dist/esm/web.d.ts +26 -1
  73. package/dist/esm/web.js +214 -75
  74. package/dist/plugin.cjs.js +1 -2
  75. package/dist/plugin.esm.js +1 -2
  76. package/dist/plugin.js +2 -3
  77. package/docs/AGENTS.md +38 -0
  78. package/docs/CHANGELOG.md +275 -0
  79. package/docs/CLAUDE.md +101 -0
  80. package/docs/MANUAL-TASKS.md +17 -0
  81. package/docs/MARKETING_WEBSITE_TRACKER.md +18 -2
  82. package/docs/MIGRATION.md +170 -0
  83. package/docs/PACKAGES.md +167 -0
  84. package/docs/PERFORMANCE.md +110 -0
  85. package/docs/PROJECT_COMPLETION_TRACKER.md +4 -35
  86. package/docs/README.md +12 -2
  87. package/docs/REMAINING_FEATURES.md +123 -76
  88. package/docs/ROADMAP.md +200 -120
  89. package/docs/SECURITY-IF-REPO-PUBLIC.md +232 -0
  90. package/docs/TESTING_REQUIREMENTS.md +1 -112
  91. package/docs/ai-knowledge-base/00-project-profile.md +38 -0
  92. package/docs/ai-knowledge-base/01-features.md +46 -0
  93. package/docs/ai-knowledge-base/02-routes.md +72 -0
  94. package/docs/ai-knowledge-base/03-tech-stack.md +57 -0
  95. package/docs/ai-knowledge-base/README.md +23 -0
  96. package/docs/analytics-tracking.md +37 -0
  97. package/docs/capacitor-official-plugins.md +46 -0
  98. package/docs/capawesome-plugins.md +29 -0
  99. package/docs/deployment/HOSTINGER_DEPLOY.md +370 -0
  100. package/docs/deployment/PRODUCTION-DEPLOY-CHECKLIST.md +184 -0
  101. package/docs/docs-site/plan.md +201 -0
  102. package/docs/docs-site/scope.md +127 -0
  103. package/docs/docs-site/tracker.json +235 -0
  104. package/docs/error-handling-tracking.md +37 -0
  105. package/docs/features/laravel-nova-backend/ASSESSMENT-SUMMARY.md +96 -0
  106. package/docs/features/laravel-nova-backend/IMPLEMENTATION-PLAN.md +504 -0
  107. package/docs/features/laravel-nova-backend/progress-tracker.json +184 -0
  108. package/docs/guides/testing-guide.md +15 -41
  109. package/docs/package-audit.md +41 -0
  110. package/docs/play-store/ASO-METADATA.md +5 -0
  111. package/docs/play-store/DATA-SAFETY.md +5 -0
  112. package/docs/play-store/DECLARATIONS.md +5 -0
  113. package/docs/play-store/README.md +27 -0
  114. package/docs/play-store/RELEASE-NOTES.md +99 -0
  115. package/docs/play-store/RELEASE-STEPS.md +6 -0
  116. package/docs/play-store/STORE-LISTING.md +7 -0
  117. package/docs/play-store/SUBMISSION-CHECKLIST.md +5 -0
  118. package/docs/production-readiness.md +1 -1
  119. package/docs/project-audit/2026-05-16/00-FINALIZATION-PLAN.md +123 -0
  120. package/docs/project-audit/2026-05-16/01-BATCH-PLAN.md +227 -0
  121. package/docs/project-audit/2026-05-16/02-AUDIT-FINDINGS.md +144 -0
  122. package/docs/project-audit/2026-05-16/sessions/batch-01.md +42 -0
  123. package/docs/project-audit/2026-05-16/sessions/batch-02.md +74 -0
  124. package/docs/project-audit/2026-05-16/sessions/batch-03.md +71 -0
  125. package/docs/project-audit/2026-05-16/sessions/batch-04.md +88 -0
  126. package/docs/project-audit/2026-05-16/sessions/batch-05.md +63 -0
  127. package/docs/project-audit/2026-05-16/sessions/batch-06.md +103 -0
  128. package/docs/project-audit/2026-05-16/sessions/batch-07.md +61 -0
  129. package/docs/project-audit/2026-05-16/sessions/batch-08.md +101 -0
  130. package/docs/project-audit/2026-05-16/sessions/batch-09.md +105 -0
  131. package/docs/project-audit/2026-05-16/sessions/batch-10.md +102 -0
  132. package/docs/project-audit/AUDIT-HISTORY.md +74 -0
  133. package/docs/project-audit/BATCH-PLAN.md +168 -0
  134. package/docs/project-audit/MARKETING-WEBSITE-FINDINGS-2026-05-11.md +73 -0
  135. package/docs/project-audit/PRODUCTION-READINESS-AUDIT-2026-05-08.md +275 -0
  136. package/docs/project-finalization/00-tracker.json +60 -0
  137. package/docs/project-knowledge-base/01-system-overview.md +227 -0
  138. package/docs/project-knowledge-base/02-routes-pages-forms-users.md +352 -0
  139. package/docs/project-knowledge-base/03-tech-stack-modules-services.md +379 -0
  140. package/docs/project-knowledge-base/04-data-models-integrations.md +244 -0
  141. package/docs/project-knowledge-base/05-docs-corpus-inventory.md +256 -0
  142. package/docs/project-knowledge-base/06-operations-testing-legal-content.md +208 -0
  143. package/docs/project-knowledge-base/README.md +103 -0
  144. package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-05-19.md +81 -0
  145. package/docs/rules-tracker.md +102 -0
  146. package/docs/security/PRE-LAUNCH-PENTEST-CHECKLIST.md +116 -0
  147. package/docs/seo-aeo-rules.json +3043 -0
  148. package/docs/social-media-marketing/README.md +81 -0
  149. package/docs/social-media-marketing/posts-batch-01.md +613 -0
  150. package/docs/social-media-marketing/posts-batch-02.md +528 -0
  151. package/docs/social-media-marketing/whatsapp-messages-batch-01.md +458 -0
  152. package/docs/social-media-marketing/whatsapp-status-batch-01.md +355 -0
  153. package/docs/tracking/finalization-2026-05-16-tracker.json +346 -0
  154. package/docs/tracking/full-audit-tracker.json +121 -0
  155. package/docs/tracking/production-readiness-audit-tracker.json +429 -0
  156. package/docs/tracking/seo-checklist-tracker.json +333 -0
  157. package/ios/Plugin/BackgroundUpdate/BackgroundUpdatePlugin.swift +66 -9
  158. package/ios/Plugin/LiveUpdate/LiveUpdatePlugin.swift +306 -52
  159. package/ios/Plugin/NativeUpdatePlugin.swift +22 -9
  160. package/ios/Plugin/Security/SecurityManager.swift +13 -14
  161. package/package.json +37 -38
  162. package/cli/node_modules/.yarn-integrity +0 -16
  163. package/cli/node_modules/commander/LICENSE +0 -22
  164. package/cli/node_modules/commander/Readme.md +0 -1148
  165. package/cli/node_modules/commander/esm.mjs +0 -16
  166. package/cli/node_modules/commander/index.js +0 -26
  167. package/cli/node_modules/commander/lib/argument.js +0 -145
  168. package/cli/node_modules/commander/lib/command.js +0 -2179
  169. package/cli/node_modules/commander/lib/error.js +0 -43
  170. package/cli/node_modules/commander/lib/help.js +0 -462
  171. package/cli/node_modules/commander/lib/option.js +0 -329
  172. package/cli/node_modules/commander/lib/suggestSimilar.js +0 -100
  173. package/cli/node_modules/commander/package-support.json +0 -16
  174. package/cli/node_modules/commander/package.json +0 -80
  175. package/cli/node_modules/commander/typings/esm.d.mts +0 -3
  176. package/cli/node_modules/commander/typings/index.d.ts +0 -884
  177. package/cli/yarn.lock +0 -8
  178. package/dist/esm/__tests__/bundle-manager.test.d.ts +0 -1
  179. package/dist/esm/__tests__/bundle-manager.test.js +0 -151
  180. package/dist/esm/__tests__/bundle-manager.test.js.map +0 -1
  181. package/dist/esm/__tests__/config.test.d.ts +0 -1
  182. package/dist/esm/__tests__/config.test.js +0 -70
  183. package/dist/esm/__tests__/config.test.js.map +0 -1
  184. package/dist/esm/__tests__/delta-processor.test.d.ts +0 -1
  185. package/dist/esm/__tests__/delta-processor.test.js +0 -77
  186. package/dist/esm/__tests__/delta-processor.test.js.map +0 -1
  187. package/dist/esm/__tests__/firestore-schema.test.d.ts +0 -1
  188. package/dist/esm/__tests__/firestore-schema.test.js +0 -74
  189. package/dist/esm/__tests__/firestore-schema.test.js.map +0 -1
  190. package/dist/esm/__tests__/integration.test.d.ts +0 -1
  191. package/dist/esm/__tests__/integration.test.js +0 -78
  192. package/dist/esm/__tests__/integration.test.js.map +0 -1
  193. package/dist/esm/__tests__/manifest-reader.test.d.ts +0 -1
  194. package/dist/esm/__tests__/manifest-reader.test.js +0 -271
  195. package/dist/esm/__tests__/manifest-reader.test.js.map +0 -1
  196. package/dist/esm/__tests__/rollout-checker.test.d.ts +0 -1
  197. package/dist/esm/__tests__/rollout-checker.test.js +0 -210
  198. package/dist/esm/__tests__/rollout-checker.test.js.map +0 -1
  199. package/dist/esm/__tests__/security.test.d.ts +0 -1
  200. package/dist/esm/__tests__/security.test.js +0 -54
  201. package/dist/esm/__tests__/security.test.js.map +0 -1
  202. package/dist/esm/__tests__/version-manager.test.d.ts +0 -1
  203. package/dist/esm/__tests__/version-manager.test.js +0 -45
  204. package/dist/esm/__tests__/version-manager.test.js.map +0 -1
  205. package/dist/esm/app-review/app-review-manager.js.map +0 -1
  206. package/dist/esm/app-review/index.js.map +0 -1
  207. package/dist/esm/app-review/platform-review-handler.js.map +0 -1
  208. package/dist/esm/app-review/review-conditions-checker.js.map +0 -1
  209. package/dist/esm/app-review/review-rate-limiter.js.map +0 -1
  210. package/dist/esm/app-review/types.js.map +0 -1
  211. package/dist/esm/app-update/app-update-checker.js.map +0 -1
  212. package/dist/esm/app-update/app-update-installer.js.map +0 -1
  213. package/dist/esm/app-update/app-update-manager.js.map +0 -1
  214. package/dist/esm/app-update/app-update-notifier.js.map +0 -1
  215. package/dist/esm/app-update/index.js.map +0 -1
  216. package/dist/esm/app-update/platform-app-update.js.map +0 -1
  217. package/dist/esm/app-update/types.js.map +0 -1
  218. package/dist/esm/background-update/background-scheduler.js.map +0 -1
  219. package/dist/esm/background-update/index.js.map +0 -1
  220. package/dist/esm/background-update/notification-manager.js.map +0 -1
  221. package/dist/esm/config/support.js.map +0 -1
  222. package/dist/esm/core/analytics.js.map +0 -1
  223. package/dist/esm/core/cache-manager.js.map +0 -1
  224. package/dist/esm/core/config.js.map +0 -1
  225. package/dist/esm/core/errors.js.map +0 -1
  226. package/dist/esm/core/event-emitter.js.map +0 -1
  227. package/dist/esm/core/logger.js.map +0 -1
  228. package/dist/esm/core/performance.js.map +0 -1
  229. package/dist/esm/core/plugin-manager.js.map +0 -1
  230. package/dist/esm/core/security.js.map +0 -1
  231. package/dist/esm/definitions.js.map +0 -1
  232. package/dist/esm/firestore/firestore-client.d.ts +0 -109
  233. package/dist/esm/firestore/firestore-client.js +0 -264
  234. package/dist/esm/firestore/firestore-client.js.map +0 -1
  235. package/dist/esm/firestore/index.d.ts +0 -11
  236. package/dist/esm/firestore/index.js +0 -11
  237. package/dist/esm/firestore/index.js.map +0 -1
  238. package/dist/esm/firestore/manifest-reader.d.ts +0 -87
  239. package/dist/esm/firestore/manifest-reader.js +0 -294
  240. package/dist/esm/firestore/manifest-reader.js.map +0 -1
  241. package/dist/esm/firestore/schema.d.ts +0 -507
  242. package/dist/esm/firestore/schema.js +0 -73
  243. package/dist/esm/firestore/schema.js.map +0 -1
  244. package/dist/esm/index.js.map +0 -1
  245. package/dist/esm/live-update/bundle-manager.js.map +0 -1
  246. package/dist/esm/live-update/certificate-pinning.js.map +0 -1
  247. package/dist/esm/live-update/delta-processor.js.map +0 -1
  248. package/dist/esm/live-update/download-manager.js.map +0 -1
  249. package/dist/esm/live-update/rollout-checker.js.map +0 -1
  250. package/dist/esm/live-update/update-manager.js.map +0 -1
  251. package/dist/esm/live-update/version-manager.js.map +0 -1
  252. package/dist/esm/plugin.js.map +0 -1
  253. package/dist/esm/security/crypto.js.map +0 -1
  254. package/dist/esm/security/validator.js.map +0 -1
  255. package/dist/esm/web.js.map +0 -1
  256. package/dist/plugin.cjs.js.map +0 -1
  257. package/dist/plugin.esm.js.map +0 -1
  258. package/dist/plugin.js.map +0 -1
  259. package/docs/FIREBASE_INTEGRATION_TRACKER.md +0 -321
  260. package/docs/FIREBASE_QUERIES_AND_INDEXES_AUDIT.md +0 -221
  261. package/docs/examples/firebase-backend-example.md +0 -27
  262. package/docs/guides/no-cost-backend-implementation-plan.md +0 -77
  263. package/docs/guides/no-cost-firestore-google-drive-backend.md +0 -60
  264. package/docs/play-console-rejection-rules.json +0 -428
  265. /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.