native-update 2.0.0 → 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 (258) hide show
  1. package/Readme.md +28 -14
  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/LiveUpdatePlugin.kt +196 -29
  6. package/android/src/main/java/com/aoneahsan/nativeupdate/NativeUpdatePlugin.kt +21 -36
  7. package/cli/AGENTS.md +15 -1
  8. package/cli/CLAUDE.md +15 -1
  9. package/cli/commands/backend-create.js +56 -15
  10. package/cli/commands/bundle-create.js +39 -7
  11. package/cli/commands/monitor.js +72 -51
  12. package/cli/index.js +10 -24
  13. package/cli/package.json +11 -3
  14. package/dist/esm/app-review/app-review-manager.js +0 -1
  15. package/dist/esm/app-review/index.js +0 -1
  16. package/dist/esm/app-review/platform-review-handler.js +0 -1
  17. package/dist/esm/app-review/review-conditions-checker.js +0 -1
  18. package/dist/esm/app-review/review-rate-limiter.js +0 -1
  19. package/dist/esm/app-review/types.js +0 -1
  20. package/dist/esm/app-update/app-update-checker.js +0 -1
  21. package/dist/esm/app-update/app-update-installer.d.ts +1 -0
  22. package/dist/esm/app-update/app-update-installer.js +19 -8
  23. package/dist/esm/app-update/app-update-manager.js +0 -1
  24. package/dist/esm/app-update/app-update-notifier.js +0 -1
  25. package/dist/esm/app-update/index.js +0 -1
  26. package/dist/esm/app-update/platform-app-update.js +12 -3
  27. package/dist/esm/app-update/types.js +0 -1
  28. package/dist/esm/background-update/background-scheduler.js +0 -1
  29. package/dist/esm/background-update/index.js +0 -1
  30. package/dist/esm/background-update/notification-manager.js +0 -1
  31. package/dist/esm/config/support.js +0 -1
  32. package/dist/esm/core/analytics.d.ts +13 -0
  33. package/dist/esm/core/analytics.js +15 -1
  34. package/dist/esm/core/cache-manager.js +0 -1
  35. package/dist/esm/core/config.d.ts +0 -15
  36. package/dist/esm/core/config.js +0 -4
  37. package/dist/esm/core/errors.d.ts +1 -0
  38. package/dist/esm/core/errors.js +1 -1
  39. package/dist/esm/core/event-emitter.d.ts +0 -3
  40. package/dist/esm/core/event-emitter.js +8 -3
  41. package/dist/esm/core/logger.js +0 -1
  42. package/dist/esm/core/performance.js +0 -1
  43. package/dist/esm/core/plugin-manager.js +3 -1
  44. package/dist/esm/core/security.d.ts +11 -0
  45. package/dist/esm/core/security.js +27 -1
  46. package/dist/esm/definitions.d.ts +0 -11
  47. package/dist/esm/definitions.js +0 -1
  48. package/dist/esm/index.d.ts +3 -2
  49. package/dist/esm/index.js +3 -1
  50. package/dist/esm/live-update/bundle-manager.d.ts +8 -0
  51. package/dist/esm/live-update/bundle-manager.js +20 -1
  52. package/dist/esm/live-update/certificate-pinning.js +0 -1
  53. package/dist/esm/live-update/delta-processor.d.ts +1 -1
  54. package/dist/esm/live-update/delta-processor.js +3 -1
  55. package/dist/esm/live-update/download-manager.js +9 -2
  56. package/dist/esm/live-update/rollout-checker.d.ts +1 -1
  57. package/dist/esm/live-update/rollout-checker.js +5 -6
  58. package/dist/esm/live-update/update-manager.js +0 -1
  59. package/dist/esm/live-update/version-manager.d.ts +0 -12
  60. package/dist/esm/live-update/version-manager.js +0 -68
  61. package/dist/esm/plugin.js +69 -43
  62. package/dist/esm/security/crypto.js +11 -7
  63. package/dist/esm/security/validator.js +0 -1
  64. package/dist/esm/types/rollout.d.ts +85 -0
  65. package/dist/esm/types/rollout.js +25 -0
  66. package/dist/esm/web.d.ts +8 -0
  67. package/dist/esm/web.js +148 -54
  68. package/dist/plugin.cjs.js +1 -2
  69. package/dist/plugin.esm.js +1 -2
  70. package/dist/plugin.js +2 -3
  71. package/docs/CHANGELOG.md +124 -0
  72. package/docs/CLAUDE.md +1 -1
  73. package/docs/MANUAL-TASKS.md +17 -0
  74. package/docs/MARKETING_WEBSITE_TRACKER.md +18 -2
  75. package/docs/MIGRATION.md +83 -0
  76. package/docs/PACKAGES.md +167 -0
  77. package/docs/PERFORMANCE.md +110 -0
  78. package/docs/PROJECT_COMPLETION_TRACKER.md +4 -35
  79. package/docs/README.md +0 -1
  80. package/docs/REMAINING_FEATURES.md +123 -76
  81. package/docs/ROADMAP.md +200 -120
  82. package/docs/SECURITY-IF-REPO-PUBLIC.md +232 -0
  83. package/docs/TESTING_REQUIREMENTS.md +1 -112
  84. package/docs/ai-knowledge-base/00-project-profile.md +38 -0
  85. package/docs/ai-knowledge-base/01-features.md +46 -0
  86. package/docs/ai-knowledge-base/02-routes.md +72 -0
  87. package/docs/ai-knowledge-base/03-tech-stack.md +57 -0
  88. package/docs/ai-knowledge-base/README.md +23 -0
  89. package/docs/analytics-tracking.md +37 -0
  90. package/docs/capacitor-official-plugins.md +46 -0
  91. package/docs/capawesome-plugins.md +29 -0
  92. package/docs/deployment/HOSTINGER_DEPLOY.md +75 -34
  93. package/docs/deployment/PRODUCTION-DEPLOY-CHECKLIST.md +184 -0
  94. package/docs/docs-site/plan.md +201 -0
  95. package/docs/docs-site/scope.md +127 -0
  96. package/docs/docs-site/tracker.json +235 -0
  97. package/docs/error-handling-tracking.md +37 -0
  98. package/docs/guides/testing-guide.md +15 -41
  99. package/docs/package-audit.md +41 -0
  100. package/docs/play-store/ASO-METADATA.md +5 -0
  101. package/docs/play-store/DATA-SAFETY.md +5 -0
  102. package/docs/play-store/DECLARATIONS.md +5 -0
  103. package/docs/play-store/README.md +27 -0
  104. package/docs/play-store/RELEASE-NOTES.md +99 -0
  105. package/docs/play-store/RELEASE-STEPS.md +6 -0
  106. package/docs/play-store/STORE-LISTING.md +7 -0
  107. package/docs/play-store/SUBMISSION-CHECKLIST.md +5 -0
  108. package/docs/production-readiness.md +1 -1
  109. package/docs/project-audit/2026-05-16/00-FINALIZATION-PLAN.md +123 -0
  110. package/docs/project-audit/2026-05-16/01-BATCH-PLAN.md +227 -0
  111. package/docs/project-audit/2026-05-16/02-AUDIT-FINDINGS.md +144 -0
  112. package/docs/project-audit/2026-05-16/sessions/batch-01.md +42 -0
  113. package/docs/project-audit/2026-05-16/sessions/batch-02.md +74 -0
  114. package/docs/project-audit/2026-05-16/sessions/batch-03.md +71 -0
  115. package/docs/project-audit/2026-05-16/sessions/batch-04.md +88 -0
  116. package/docs/project-audit/2026-05-16/sessions/batch-05.md +63 -0
  117. package/docs/project-audit/2026-05-16/sessions/batch-06.md +103 -0
  118. package/docs/project-audit/2026-05-16/sessions/batch-07.md +61 -0
  119. package/docs/project-audit/2026-05-16/sessions/batch-08.md +101 -0
  120. package/docs/project-audit/2026-05-16/sessions/batch-09.md +105 -0
  121. package/docs/project-audit/2026-05-16/sessions/batch-10.md +102 -0
  122. package/docs/project-audit/AUDIT-HISTORY.md +74 -0
  123. package/docs/project-audit/BATCH-PLAN.md +168 -0
  124. package/docs/project-audit/MARKETING-WEBSITE-FINDINGS-2026-05-11.md +73 -0
  125. package/docs/project-audit/PRODUCTION-READINESS-AUDIT-2026-05-08.md +275 -0
  126. package/docs/project-finalization/00-tracker.json +60 -0
  127. package/docs/project-knowledge-base/01-system-overview.md +39 -30
  128. package/docs/project-knowledge-base/02-routes-pages-forms-users.md +87 -81
  129. package/docs/project-knowledge-base/03-tech-stack-modules-services.md +140 -108
  130. package/docs/project-knowledge-base/04-data-models-integrations.md +191 -254
  131. package/docs/project-knowledge-base/05-docs-corpus-inventory.md +83 -20
  132. package/docs/project-knowledge-base/06-operations-testing-legal-content.md +67 -29
  133. package/docs/project-knowledge-base/README.md +27 -14
  134. package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-05-19.md +81 -0
  135. package/docs/rules-tracker.md +102 -0
  136. package/docs/security/PRE-LAUNCH-PENTEST-CHECKLIST.md +116 -0
  137. package/docs/social-media-marketing/README.md +81 -0
  138. package/docs/social-media-marketing/posts-batch-01.md +613 -0
  139. package/docs/social-media-marketing/posts-batch-02.md +528 -0
  140. package/docs/social-media-marketing/whatsapp-messages-batch-01.md +458 -0
  141. package/docs/social-media-marketing/whatsapp-status-batch-01.md +355 -0
  142. package/docs/tracking/finalization-2026-05-16-tracker.json +346 -0
  143. package/docs/tracking/full-audit-tracker.json +121 -0
  144. package/docs/tracking/production-readiness-audit-tracker.json +429 -0
  145. package/ios/Plugin/BackgroundUpdate/BackgroundUpdatePlugin.swift +16 -3
  146. package/ios/Plugin/LiveUpdate/LiveUpdatePlugin.swift +71 -47
  147. package/ios/Plugin/NativeUpdatePlugin.swift +14 -9
  148. package/package.json +29 -29
  149. package/cli/node_modules/.yarn-integrity +0 -16
  150. package/cli/node_modules/commander/LICENSE +0 -22
  151. package/cli/node_modules/commander/Readme.md +0 -1148
  152. package/cli/node_modules/commander/esm.mjs +0 -16
  153. package/cli/node_modules/commander/index.js +0 -26
  154. package/cli/node_modules/commander/lib/argument.js +0 -145
  155. package/cli/node_modules/commander/lib/command.js +0 -2179
  156. package/cli/node_modules/commander/lib/error.js +0 -43
  157. package/cli/node_modules/commander/lib/help.js +0 -462
  158. package/cli/node_modules/commander/lib/option.js +0 -329
  159. package/cli/node_modules/commander/lib/suggestSimilar.js +0 -100
  160. package/cli/node_modules/commander/package-support.json +0 -16
  161. package/cli/node_modules/commander/package.json +0 -80
  162. package/cli/node_modules/commander/typings/esm.d.mts +0 -3
  163. package/cli/node_modules/commander/typings/index.d.ts +0 -884
  164. package/cli/yarn.lock +0 -8
  165. package/dist/esm/__tests__/bundle-manager.test.d.ts +0 -1
  166. package/dist/esm/__tests__/bundle-manager.test.js +0 -151
  167. package/dist/esm/__tests__/bundle-manager.test.js.map +0 -1
  168. package/dist/esm/__tests__/config.test.d.ts +0 -1
  169. package/dist/esm/__tests__/config.test.js +0 -70
  170. package/dist/esm/__tests__/config.test.js.map +0 -1
  171. package/dist/esm/__tests__/delta-processor.test.d.ts +0 -1
  172. package/dist/esm/__tests__/delta-processor.test.js +0 -77
  173. package/dist/esm/__tests__/delta-processor.test.js.map +0 -1
  174. package/dist/esm/__tests__/firestore-schema.test.d.ts +0 -1
  175. package/dist/esm/__tests__/firestore-schema.test.js +0 -74
  176. package/dist/esm/__tests__/firestore-schema.test.js.map +0 -1
  177. package/dist/esm/__tests__/integration.test.d.ts +0 -1
  178. package/dist/esm/__tests__/integration.test.js +0 -78
  179. package/dist/esm/__tests__/integration.test.js.map +0 -1
  180. package/dist/esm/__tests__/manifest-reader.test.d.ts +0 -1
  181. package/dist/esm/__tests__/manifest-reader.test.js +0 -271
  182. package/dist/esm/__tests__/manifest-reader.test.js.map +0 -1
  183. package/dist/esm/__tests__/rollout-checker.test.d.ts +0 -1
  184. package/dist/esm/__tests__/rollout-checker.test.js +0 -210
  185. package/dist/esm/__tests__/rollout-checker.test.js.map +0 -1
  186. package/dist/esm/__tests__/security-enforcement.test.d.ts +0 -1
  187. package/dist/esm/__tests__/security-enforcement.test.js +0 -95
  188. package/dist/esm/__tests__/security-enforcement.test.js.map +0 -1
  189. package/dist/esm/__tests__/security.test.d.ts +0 -1
  190. package/dist/esm/__tests__/security.test.js +0 -54
  191. package/dist/esm/__tests__/security.test.js.map +0 -1
  192. package/dist/esm/__tests__/version-manager.test.d.ts +0 -1
  193. package/dist/esm/__tests__/version-manager.test.js +0 -45
  194. package/dist/esm/__tests__/version-manager.test.js.map +0 -1
  195. package/dist/esm/app-review/app-review-manager.js.map +0 -1
  196. package/dist/esm/app-review/index.js.map +0 -1
  197. package/dist/esm/app-review/platform-review-handler.js.map +0 -1
  198. package/dist/esm/app-review/review-conditions-checker.js.map +0 -1
  199. package/dist/esm/app-review/review-rate-limiter.js.map +0 -1
  200. package/dist/esm/app-review/types.js.map +0 -1
  201. package/dist/esm/app-update/app-update-checker.js.map +0 -1
  202. package/dist/esm/app-update/app-update-installer.js.map +0 -1
  203. package/dist/esm/app-update/app-update-manager.js.map +0 -1
  204. package/dist/esm/app-update/app-update-notifier.js.map +0 -1
  205. package/dist/esm/app-update/index.js.map +0 -1
  206. package/dist/esm/app-update/platform-app-update.js.map +0 -1
  207. package/dist/esm/app-update/types.js.map +0 -1
  208. package/dist/esm/background-update/background-scheduler.js.map +0 -1
  209. package/dist/esm/background-update/index.js.map +0 -1
  210. package/dist/esm/background-update/notification-manager.js.map +0 -1
  211. package/dist/esm/config/support.js.map +0 -1
  212. package/dist/esm/core/analytics.js.map +0 -1
  213. package/dist/esm/core/cache-manager.js.map +0 -1
  214. package/dist/esm/core/config.js.map +0 -1
  215. package/dist/esm/core/errors.js.map +0 -1
  216. package/dist/esm/core/event-emitter.js.map +0 -1
  217. package/dist/esm/core/logger.js.map +0 -1
  218. package/dist/esm/core/performance.js.map +0 -1
  219. package/dist/esm/core/plugin-manager.js.map +0 -1
  220. package/dist/esm/core/security.js.map +0 -1
  221. package/dist/esm/definitions.js.map +0 -1
  222. package/dist/esm/firestore/firestore-client.d.ts +0 -109
  223. package/dist/esm/firestore/firestore-client.js +0 -264
  224. package/dist/esm/firestore/firestore-client.js.map +0 -1
  225. package/dist/esm/firestore/index.d.ts +0 -11
  226. package/dist/esm/firestore/index.js +0 -11
  227. package/dist/esm/firestore/index.js.map +0 -1
  228. package/dist/esm/firestore/manifest-reader.d.ts +0 -87
  229. package/dist/esm/firestore/manifest-reader.js +0 -294
  230. package/dist/esm/firestore/manifest-reader.js.map +0 -1
  231. package/dist/esm/firestore/schema.d.ts +0 -507
  232. package/dist/esm/firestore/schema.js +0 -73
  233. package/dist/esm/firestore/schema.js.map +0 -1
  234. package/dist/esm/index.js.map +0 -1
  235. package/dist/esm/live-update/bundle-manager.js.map +0 -1
  236. package/dist/esm/live-update/certificate-pinning.js.map +0 -1
  237. package/dist/esm/live-update/delta-processor.js.map +0 -1
  238. package/dist/esm/live-update/download-manager.js.map +0 -1
  239. package/dist/esm/live-update/rollout-checker.js.map +0 -1
  240. package/dist/esm/live-update/update-manager.js.map +0 -1
  241. package/dist/esm/live-update/version-manager.js.map +0 -1
  242. package/dist/esm/plugin.js.map +0 -1
  243. package/dist/esm/security/crypto.js.map +0 -1
  244. package/dist/esm/security/validator.js.map +0 -1
  245. package/dist/esm/web.js.map +0 -1
  246. package/dist/plugin.cjs.js.map +0 -1
  247. package/dist/plugin.esm.js.map +0 -1
  248. package/dist/plugin.js.map +0 -1
  249. package/docs/FIREBASE_INTEGRATION_TRACKER.md +0 -321
  250. package/docs/FIREBASE_QUERIES_AND_INDEXES_AUDIT.md +0 -221
  251. package/docs/examples/firebase-backend-example.md +0 -27
  252. package/docs/features/laravel-nova-backend/credentials.ignore.md +0 -34
  253. package/docs/guides/no-cost-backend-implementation-plan.md +0 -77
  254. package/docs/guides/no-cost-firestore-google-drive-backend.md +0 -60
  255. package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-03-16.md +0 -454
  256. package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-03-24.md +0 -66
  257. package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-03-25.md +0 -67
  258. /package/docs/{MARKETING_WEBSITE_PLAN.md → archive/MARKETING_WEBSITE_PLAN.md} +0 -0
@@ -0,0 +1,102 @@
1
+ # Rules Tracker — Native Update
2
+
3
+ This file tracks the application of the Generic Project Rules master prompt (R-001 through R-039) against this monorepo. It is the source of truth for "when was rule X last applied" and is used to skip recently-applied rules on re-runs.
4
+
5
+ **Tracker last updated:** 2026-05-18
6
+ **Run by:** Claude Code (Opus 4.7)
7
+ **Run scope:** R-033 reclassified to N/A after v3.0.0 Firestore removal (full audit cooldown still in effect until 2026-05-23)
8
+
9
+ ---
10
+
11
+ ## Project context (locked answers)
12
+
13
+ | # | Question | Answer |
14
+ |---|---|---|
15
+ | 1 | Private or public git repo? | **Public** — `github.com/aoneahsan/native-update`, MIT license |
16
+ | 2 | Project + brand name? | Project: `native-update` (npm) · Brand: **Native Update** |
17
+ | 3 | App identifier / bundle ID | Plugin (npm) has none. Website Capacitor app: `com.zaions.nativeupdate` (per `website/capacitor.config.ts`); example app: per its own config |
18
+ | 4 | Developer contact | Ahsan Mahmood · aoneahsan@gmail.com · +923046619706 · linkedin.com/in/aoneahsan · aoneahsan.com |
19
+ | 5 | Domain / social / support | Domain: `nativeupdate.aoneahsan.com` (live). Socials: GitHub `aoneahsan`, NPM `aoneahsan`, LinkedIn `aoneahsan`, Twitter `aoneahsan`. Support email: `aoneahsan@gmail.com`. Privacy URL: `https://nativeupdate.aoneahsan.com/privacy` |
20
+ | 6 | Radix UI / ShadCN used? | **Yes (Radix UI)** — Radix primitives across `website/`. Tailwind v4 + Radix is the stack. ShadCN is not used |
21
+ | 7 | Capacitor used? | Root IS a Capacitor **plugin** (not an app). The `website/` is a Capacitor app for hybrid mobile distribution of the dashboard. `example-apps/react-capacitor/` is a Capacitor demo. Root plugin rules differ from app-level Capacitor rules |
22
+
23
+ ---
24
+
25
+ ## Sub-project map and applicable rule set
26
+
27
+ | Sub-project | Path | Type | Frontend rules (R-007/R-008/R-012/R-013/R-018/R-021–R-024/R-026/R-031/R-032/R-034) | Capacitor rules (R-019/R-027/R-028/R-035/R-036) | Notes |
28
+ |---|---|---|---|---|---|
29
+ | Root plugin | `/` | npm + Capacitor plugin | N/A (no UI) | N/A (the plugin is consumed; not itself an app) | Apply structural, build, docs rules only |
30
+ | Website + dashboard | `website/` | React + Vite + Capacitor app | YES | YES | Primary UI target |
31
+ | Example app | `example-apps/react-capacitor/` | Capacitor demo | Light (demo only) | Light (demo only) | Demos plugin usage; not a published product |
32
+ | Example backend | `example-apps/node-express/` | Node demo | N/A | N/A | Reference server for plugin docs (the `firebase-backend/` example was removed in v3.0.0) |
33
+ | Backend | `backend/` | Laravel 11 + Nova SaaS | N/A (server-rendered, separate flow) | N/A | Canonical backend — the only backend after v3.0.0 |
34
+ | CLI | `cli/` | Node CLI | N/A | N/A | Plugin user CLI — structural rules only |
35
+
36
+ ---
37
+
38
+ ## Rules table
39
+
40
+ Rules marked **N/A** include a justification in the Notes column. **Done** means the rule was applied in this run (or a prior run, and verified still in place). **Pending** means it's a follow-up.
41
+
42
+ | Rule ID | Cadence | Status | Last Applied | Next Review | Notes |
43
+ |---|---|---|---|---|---|
44
+ | R-001-CLAUDE-AGENTS-FILES | Every 3 days | Done | 2026-04-25 | 2026-04-28 | Root + sub-project CLAUDE.md/AGENTS.md verified. AGENTS.md re-synced from CLAUDE.md at root. |
45
+ | R-002-CONTEXT-MANAGEMENT | Behavioral | Done | 2026-04-25 | — | Already enshrined in root + global CLAUDE.md (`/compact` at <20%, progress logs). |
46
+ | R-003-PACKAGE-MANAGER | One-time | Done | 2026-04-25 | — | yarn-only confirmed across root, website, cli, example-apps. No `package-lock.json` or `pnpm-lock.yaml` at any level (one stray `package-lock.json` exists at `backend/` for npm-published Tailwind/PostCSS — left because `backend/` is Laravel + intentionally uses npm for Vite plugins; documented in tracker). |
47
+ | R-004-DOCS-SCRIPTS-FOLDERS | Recurring | Done | 2026-04-25 | 2026-05-09 | Docs in `docs/` (41 entries). Scripts intentionally absent at root per R-006. `website/scripts/` retained — only `generate-sitemap.mjs` (necessary for SEO build pipeline). |
48
+ | R-005-NO-USELESS-FILES | Recurring | Done | 2026-04-25 | 2026-05-09 | Reviewed root + website docs; no useless record/summary files added. Older "_TRACKER.md" / "_PLAN.md" files left in place because they're in active use. |
49
+ | R-006-NO-SCRIPTS | One-time | Done | 2026-04-25 | — | No `.sh` files anywhere. Root has no `scripts/`. `website/scripts/generate-sitemap.mjs` is the only script — required by SEO build, documented at top of file. |
50
+ | R-007-NO-NATIVE-HTML | One-time + recurring | Partial | 2026-04-25 | 2026-05-09 | Website uses Radix primitives extensively, but some `<button>` / `<input>` usage remains in legacy components. Documented for incremental migration; no regressions allowed in new code. See R-007 audit notes below. |
51
+ | R-008-SITEMAP-FEED-BLOG | ≥3 days, ≤7 days | Done (sitemap+feed) / N/A (blog) | 2026-04-24 | 2026-05-01 | Sitemap + feed fully implemented per `website/CLAUDE.md` SEO record. Blog is **not** required for this project (technical plugin docs site, not a content site) — recorded as deliberate N/A. |
52
+ | R-009-GITIGNORE | Recurring | Done | 2026-04-25 | 2026-05-09 | Root + website + example-apps `.gitignore` re-audited. `website/.firebase/hosting.*` cache was leaking into git — already fixed in commit `c687dd5`. No further changes needed. |
53
+ | R-010-CLEAN-PACKAGE-JSON | Recurring | Done | 2026-04-25 | 2026-05-09 | Audited root + website + cli `package.json`. All listed deps are imported. Notes recorded in `docs/package-audit.md`. |
54
+ | R-011-APP-VERSION-FOOTER | One-time | Done | 2026-04-25 | — | Website footer now displays plugin version + build year. Sourced from `package.json` via Vite `define`. |
55
+ | R-012-404-ERROR-PAGES | One-time + recurring | Done | 2026-04-25 | 2026-05-09 | `NotFoundPage.tsx` exists. Verified it matches current branding. 401/403/500 fall back to NotFoundPage with appropriate copy via router. |
56
+ | R-013-SCROLL-TO-TOP | One-time | Done | 2026-04-25 | — | `<ScrollToTop>` component added to `MarketingLayout` and `DashboardLayout`. Honours hash for deep links. |
57
+ | R-014-README-SYNC | Every 14 days | Done | 2026-04-25 | 2026-05-09 | Root `Readme.md` + `website/README.md` last updated; rules-tracker date noted. |
58
+ | R-015-DEV-SERVER-PORT | One-time, confirm | Done | 2026-04-25 | — | Website: 5942 (registered). Example-apps/react-capacitor: 5944 (registered). Both unique, NOT defaults. Path in registry updated to current `projects/native-update/...` location. |
59
+ | R-016-AI-KNOWLEDGE-BASE | Every 14 days | Done | 2026-04-25 | 2026-05-09 | `docs/ai-knowledge-base/` populated with project profile, features, routes, tech-stack, modules. Existing `AI-INTEGRATION-GUIDE.md` referenced. |
60
+ | R-017-ENV-EXAMPLE | Recurring | Done | 2026-04-25 | 2026-05-09 | Root `env-example` and `env.sentry-example` unchanged (no new env vars). Website `.env.example` unchanged (still 4 keys). Required-env error wiring verified. |
61
+ | R-018-PROJECT-META-INFO | Recurring | Done | 2026-04-25 | 2026-05-09 | All info pages exist and were verified: privacy, terms, security, cookies, data-deletion, about, contact, permissions. Links from footer confirmed. |
62
+ | R-019-PUBLISH-ASSETS | One-time + refresh | Done (website) | 2026-04-25 | — | `website/app-publish-assets/` already exists. Refreshed `Last Updated` date. |
63
+ | R-020-UPDATE-CLAUDE-MD | Every 14 days | Done | 2026-04-25 | 2026-05-09 | Root + website + cli + example-apps + backend CLAUDE.md/AGENTS.md updated with `Last Updated: 2026-04-25`. Version drift fixed. |
64
+ | R-021-THEME-COLOR-CONTROLS | One-time, confirm | N/A (deliberate) | 2026-04-25 | — | Per `~/.claude/rules/radix-theme.md`: rule applies if Radix is used **app-wide**. Native Update website uses some Radix primitives but the visual system is Tailwind-driven, not `@radix-ui/themes`. Recorded as "Radix not used app-wide" → no theme customizer required. Re-verify on adoption of `@radix-ui/themes`. |
65
+ | R-022-GO-BACK-BUTTON | One-time + recurring | Done | 2026-04-25 | 2026-05-09 | Dashboard pages have absolute back routes. Marketing pages don't need back (root + footer nav). DocsMarkdownPage uses absolute back to `/docs`. |
66
+ | R-023-ERROR-HANDLING | One-time + audit | Partial | 2026-05-18 | 2026-05-25 | `errorTracker` service at `website/src/lib/errorTracking.ts`. Firebase Analytics path removed during the auth swap (2026-05-11). Sentry / Clarity / Amplitude shims silently skip when their env keys are missing. `docs/error-handling-tracking.md` registry kept up to date. |
67
+ | R-024-ANALYTICS | One-time + audit | Partial | 2026-05-18 | 2026-05-25 | `website/src/lib/analytics.ts` no longer routes to Firebase Analytics — that path was removed when the app moved off Firebase Auth. Clarity + Amplitude shims silently skip when env keys missing; analytics-event registry kept at `docs/analytics-tracking.md`. |
68
+ | R-025-FILES-STORAGE | One-time + audit | Done | 2026-04-25 | 2026-05-09 | Project intentionally uses **Google Drive only** (no FilesHub) — see `website/CLAUDE.md` "No-Cost Backend Rule". Documented as deliberate choice. FilesHub admin path is not needed because admins also use their Drive. |
69
+ | R-026-D3-CHARTS | One-time + audit | Done | 2026-04-25 | 2026-05-09 | `d3@^7.9.0` and `@types/d3` confirmed in website deps. No competing chart libs (`Recharts`/`Chart.js`) in `package.json`. |
70
+ | R-027-TRAPEZE-CONFIGURE | One-time | Done | 2026-04-25 | — | Root has `apps-config.yaml`. Website has `apps-config.yaml` with `sync:apps-config` script. Confirmed. |
71
+ | R-028-CAPACITOR-ASSETS | One-time | Done | 2026-04-25 | — | Website has `assets/` source directory. `@capacitor/assets` is invoked via `cap:sync`. Verified. |
72
+ | R-029-VITE-LOGGER | One-time | Done | 2026-04-25 | — | `website/src/lib/logger.ts` created — wraps `console.warn`/`console.error` with a single toggle for verbose mode. Existing `console.log` calls left in dev paths but documented for incremental migration. |
73
+ | R-030-GOOGLE-AUTH-ONLY | One-time | Done | 2026-05-18 | — | Website uses Google sign-in only — implemented as a full-page redirect to the Laravel Socialite endpoint (`${VITE_API_URL}/auth/google/redirect`); the backend issues a Sanctum personal access token on callback. No Firebase, no popups, no client-side credentials. Confirmed in `website/src/services/auth-service.ts`. |
74
+ | R-031-FORM-MANAGEMENT | One-time + audit | Done | 2026-04-25 | 2026-05-09 | `react-hook-form@^7.72`, `zod@^4.3.6`, `@hookform/resolvers@^5.2.2` — all confirmed. Used in UploadPage, SettingsPage, AppsPage. New forms in this run will reuse the pattern. |
75
+ | R-032-UI-STATE-IN-URL | One-time + audit | Partial | 2026-04-25 | 2026-05-09 | Some pages already use search params (`?tab=...`, `?view=...`). `useUrlState` hook added at `website/src/lib/hooks/useUrlState.ts`. Audit notes record outstanding pages for incremental migration. |
76
+ | R-033-FIRESTORE-RULES-INDEXES | Every 3 days | N/A (permanent) | 2026-05-18 | — | Firestore was removed from the plugin SDK + website in v3.0.0 (2026-05-04). The project's only persistence layer is now MySQL behind Laravel. `firestore.rules` / `firestore.indexes.json` / `docs/firestore-queries.json` were all deleted in commit `336f647` (post-closure cleanup). This rule is permanently N/A for this project; do not re-introduce Firestore. |
77
+ | R-034-ADMIN-PANEL | One-time + audit | Done | 2026-04-25 | 2026-05-09 | Admin layout exists at `website/src/components/admin/` and pages at `website/src/pages/admin/` (Overview, Users, Apps, Builds). Super admin email: `aoneahsan@gmail.com` per `VITE_ADMIN_EMAILS`. |
78
+ | R-035-CAPACITOR-OFFICIAL-PLUGINS | One-time | Done | 2026-04-25 | — | Website has `@capacitor/{android,ios,core,cli,motion,preferences,privacy-screen}` installed. Other plugins are deliberately not installed because the website doesn't need them (no camera, geolocation, etc.). Plugin status registry created at `docs/capacitor-official-plugins.md`. |
79
+ | R-036-CAPAWESOME-PLUGINS | One-time | Done | 2026-04-25 | — | Website has `@capawesome/capacitor-app-shortcuts`. Other Capawesome plugins (app-update, app-review, edge-to-edge, badge) documented as "to add when website ships to Play Store" — registry at `docs/capawesome-plugins.md`. |
80
+ | R-037-PROJECT-AS-PRODUCT | One-time, confirm | Done | 2026-04-25 | — | Footer copyright updated to `© Native Update team. Built with care.`. Footer credit to "Ahsan Mahmood" replaced with neutral attribution. Contact info on info pages still uses dev contact. |
81
+ | R-038-REFERENCE-PROJECTS | One-time | Done | 2026-04-25 | — | Reference projects `ZTools`, `ClearHire`, `Video Controls Plus` exist at `~/Documents/01-code/projects/`. Patterns from those projects already informed prior native-update SEO/AEO work; no new patterns to copy in this pass. |
82
+ | R-039-PROJECT-COMPLIANCE-AUDIT | Every run | Done | 2026-04-25 | next run | Final-step audit completed: build status confirmed, tracker entries finalized, version drift resolved. |
83
+
84
+ ---
85
+
86
+ ## Pending follow-ups (incremental work)
87
+
88
+ These items are documented but not rolled into this run because they would require multi-day refactors and the user wants this run shipped. Each is dated; a future re-run picks them up.
89
+
90
+ 1. **R-007 — Native HTML migration to Radix:** `<button>` and `<input>` still appear in some marketing/legacy components. New code MUST use Radix or `@/components/ui/*` wrappers. Existing usage to be migrated component-by-component.
91
+ 2. **R-023 / R-024 — Sentry / Clarity / Amplitude env wiring:** services exist and silently skip when keys are absent. Add real env keys when those tools are provisioned.
92
+ 3. **R-032 — URL state migration:** `useUrlState` hook is now available at `src/lib/hooks/useUrlState.ts`. Migrate the remaining pages incrementally as they're touched.
93
+ 4. **R-036 — Capawesome plugins:** `app-update`, `app-review`, `edge-to-edge`, `badge` to be added before any Play Store / App Store submission of the website-as-app.
94
+
95
+ ---
96
+
97
+ ## Run history
98
+
99
+ | Date | Scope | Outcome | Operator |
100
+ |---|---|---|---|
101
+ | 2026-04-25 | Full pass R-001 → R-039 | All rules either Done, Done-Partial (with documented follow-up), or N/A-with-justification | Claude Code Opus 4.7 |
102
+ | 2026-05-18 | R-033 reclassification only — marked permanently N/A after v3.0.0 Firestore removal | Targeted update; full audit cooldown still in effect until 2026-05-23 | Claude Code Opus 4.7 |
@@ -0,0 +1,116 @@
1
+ # Pre-Launch Pentest Checklist
2
+
3
+ A focused, do-it-yourself security checklist for self-hosted `native-update` deployments before going to production. Walk through every section. Each item is a yes/no gate; if you can't say yes, fix it before launch.
4
+
5
+ This is not a substitute for a professional penetration test. It is the floor — the issues a serious external test would catch in the first hour. Apps that fail this checklist are not ready for production traffic regardless of how nice the dashboard looks.
6
+
7
+ The checklist assumes you have a self-hosted Laravel + Nova backend (the reference implementation). Adapt to your own backend if you wrote one. Hosted SaaS users skip everything in the backend sections — those defenses are operated by the SaaS provider — and focus on the device-side and operational sections.
8
+
9
+ Maintained by Ahsan Mahmood. Last review: 2026-05-11.
10
+
11
+ ## 1 — Dependency hygiene (root + backend + website + example-app)
12
+
13
+ The single highest-yield pre-launch security activity. Most production incidents trace back to an unpatched transitive dep, not a clever bug in your own code.
14
+
15
+ - [ ] **Root plugin**: `yarn npm audit --severity high --recursive` exits 0 from `/` (the project root). If it reports a high or critical, evaluate each — false positives are common in the npm advisory feed, but a real one blocks launch.
16
+ - [ ] **Backend (Laravel)**: `cd backend && composer audit` exits 0. If a CVE shows up, bump the package or pin the patched version explicitly.
17
+ - [ ] **Website (React dashboard)**: `cd website && yarn npm audit --severity high --recursive` exits 0.
18
+ - [ ] **Example app**: `cd example-apps/react-capacitor && yarn npm audit` clean (advisory severity HIGH or above only — the example app has a shallower attack surface).
19
+ - [ ] **Direct dependency review**: scan `package.json` files for any deps that haven't been updated in >12 months. Stale deps are not a vulnerability by themselves but correlate strongly with abandoned maintenance.
20
+ - [ ] **Yarn / Composer lockfile is committed**: `yarn.lock` (root, website, example-app) and `composer.lock` (backend) all in git. Without locked versions, every CI run can install different transitive versions and your audit is meaningless.
21
+ - [ ] **No deprecated crypto libraries**: grep for `crypto-js`, `node-forge`, `jsrsasign`. None should appear in production paths — use Node's built-in `crypto` (server side) or `SubtleCrypto` (browser side).
22
+
23
+ ## 2 — Authentication and authorization
24
+
25
+ - [ ] **API keys are hashed at rest.** The Laravel reference stores `key_hash` (bcrypt) plus `key_prefix` (first 12 chars, for lookup). The full key is shown ONCE at creation. Confirm with `mysql -e "SELECT key_prefix, LENGTH(key_hash), key_hash LIKE '%\$2y\$%' FROM native_update_dev.api_keys LIMIT 5"` — `key_hash` should look like a bcrypt string.
26
+ - [ ] **API keys are scoped to one app.** The `ValidateApiKey` middleware joins `api_keys` to `apps` by `app_id`. Try authenticating a request with App A's key against App B's bundle download URL — it should 403, not 200.
27
+ - [ ] **API keys have a rate limit.** Default is 600 req / 15 min per key. Verify: send 700 requests in 5 minutes and confirm requests 601+ return 429 with `Retry-After`.
28
+ - [ ] **Revoked keys are immediately rejected.** Flip a key's `revoked_at`, then make a request with it. Should 401 within 1 second (no caching that extends past revocation).
29
+ - [ ] **Firebase ID tokens are verified server-side.** The dashboard `/api/dashboard/*` endpoints use `ValidateFirebaseToken`. Send an unsigned / expired / wrong-audience token; backend should reject with 401. Watch `storage/logs/laravel.log` for the verification trace.
30
+ - [ ] **Admin claims are checked.** `/api/admin/*` requires both a Firebase token AND the user being on the `ADMIN_EMAILS` allowlist. Authenticate as a non-admin and call `/api/admin/users` — should 403.
31
+ - [ ] **Nova policies fail closed.** Verify by logging into Nova as a non-admin tenant and trying to view another tenant's app via direct URL (`/admin/resources/apps/<other-tenant-app-id>`). Should redirect or 404, not show the resource.
32
+ - [ ] **Suspended-user flow works.** Flip `is_suspended=true` on a test user via Nova. Their API keys should immediately return 403; their dashboard logins should redirect to the suspension screen.
33
+
34
+ ## 3 — Cross-origin and CSRF
35
+
36
+ - [ ] **CORS allowlist is finite.** Open `backend/config/cors.php` (or your equivalent). `allowed_origins` must be a comma-separated list of full origins (`https://...`), NOT `*`. The default `CORS_ALLOWED_ORIGINS` env var should be set.
37
+ - [ ] **Wildcard origin only allowed for the public SDK endpoints.** `/api/v1/*` may permit `*` because it's API-key-gated; `/api/dashboard/*` must NOT.
38
+ - [ ] **`supports_credentials=true` is paired with explicit origin allowlist.** Browsers reject `Access-Control-Allow-Origin: *` when credentials are sent.
39
+ - [ ] **CSRF protection on dashboard endpoints.** Laravel's `web` middleware group includes `VerifyCsrfToken`. The dashboard's React client must send the CSRF token in the `X-CSRF-Token` header on mutating requests.
40
+ - [ ] **PayPal webhook is CSRF-exempt but signature-verified.** `/api/webhooks/paypal` skips Laravel's CSRF check (it has no session) but runs PayPal's signature verification. Confirm with a request lacking the signature header — should 401.
41
+
42
+ ## 4 — Bundle integrity and signing
43
+
44
+ - [ ] **HTTPS enforced for the bundle download.** `npm run dev`-style HTTP allowlists must not appear in `app.production.env`. Confirm: `curl http://your-backend/api/v1/updates/check` should redirect to HTTPS or refuse.
45
+ - [ ] **Signed download URLs expire.** Default TTL is 30 minutes (`NATIVE_UPDATE_DOWNLOAD_URL_TTL_MINUTES`). Get a signed URL, wait 31 minutes, try it — should 403.
46
+ - [ ] **Bundle ZIP hash is verified server-side at upload.** When uploading a build via the dashboard or `/api/v1/bundles/upload`, the backend should re-compute SHA-256 over the bytes and reject if mismatched against the client-supplied checksum. Confirm by uploading with a deliberately wrong checksum — should 400.
47
+ - [ ] **Signature is verified server-side at upload.** Backend should also re-verify the RSA-SHA256 signature against the app's registered public key. Confirm by uploading a bundle signed with the wrong key — should 400.
48
+ - [ ] **Device-side signature verify is unconditional.** Edit `native-update.config.js` to point at the backend, deliberately corrupt the bundle bytes mid-transit (e.g. via a proxy), and confirm the SDK refuses to apply with `SIGNATURE_VERIFICATION_FAILED`. There must be no debug flag to bypass.
49
+ - [ ] **Private signing keys are never persisted to logs.** Grep `storage/logs/laravel.log` for `BEGIN PRIVATE KEY`, `pkcs8`, `RSA PRIVATE`. Zero hits required.
50
+
51
+ ## 5 — Bundle file safety
52
+
53
+ - [ ] **No reverse-engineered or unsafe ZIP extraction.** The plugin uses platform-standard libraries (`java.util.zip.ZipFile` on Android, `Foundation`'s `NSFileManager` on iOS). Zip-slip is mitigated by validating entry names don't contain `..` or absolute paths. Verify with a crafted bundle whose entry name is `../../etc/passwd` — install should fail with `INVALID_BUNDLE`.
54
+ - [ ] **Bundle size limits enforced.** Set `NATIVE_UPDATE_MAX_BUNDLE_SIZE_MB=50` (or your real limit). Upload a 60 MB bundle — should 413.
55
+ - [ ] **No symlinks in extracted bundles.** Bundle extraction refuses symlink entries. Verify with a ZIP containing a symlink entry — install should fail.
56
+ - [ ] **Temp files are scoped to the app sandbox.** The SDK extracts to `<sandbox>/native-update/bundles/<version>/`. Verify by inspecting filesystem after a download — no files outside the sandbox.
57
+
58
+ ## 6 — Data handling and privacy
59
+
60
+ - [ ] **Device hashes are not raw identifiers.** Confirm the SDK sends `X-Device-ID: <sha256_hex>`, never the raw IMEI / ADID / IDFA. Inspect `src/web.ts` for the hashing call.
61
+ - [ ] **MAU + analytics writes do not include PII.** Inspect the analytics_events table — should contain `device_hash` (opaque), platform, app_version, bundle_version, event_type. Should NOT contain email, name, exact location, or full IP.
62
+ - [ ] **Account deletion is honored.** The `/api/dashboard/me` DELETE endpoint cascades to apps + builds + signing_keys + api_keys + analytics_events for that user. Verify by creating a test user, uploading data, calling DELETE /api/dashboard/me, then confirming all related rows are gone.
63
+ - [ ] **PII fields in user table are listed.** `users.name`, `users.email`, `users.firebase_uid` — known. Document any others. GDPR DSAR responses depend on knowing what to dump.
64
+ - [ ] **Privacy policy URL is publicly accessible AND covers OTA.** Open the URL in an incognito tab. Body must mention bundle downloads, device IDs, and the retention policy for analytics events.
65
+
66
+ ## 7 — Operational safety
67
+
68
+ - [ ] **`.env` is in `.gitignore`.** Verify: `git check-ignore backend/.env` exits 0.
69
+ - [ ] **`firebase-credentials.json` is in `.gitignore`.** Same check for `backend/storage/firebase-credentials.json`.
70
+ - [ ] **`auth.json` (Nova license) is in `.gitignore`.** Same check.
71
+ - [ ] **No secrets in committed history.** Run `git log --all -p -G "BEGIN RSA PRIVATE\|password\s*=\|api[_-]key\s*=" -- backend/ | head -50`. Should return nothing meaningful. If something appears, rotate the secret AND filter the history with `git filter-repo`.
72
+ - [ ] **Production database backups exist.** Run a backup, restore it to a test instance, verify the restore is bit-for-bit identical via `mysqldump | sha256sum` comparison.
73
+ - [ ] **Queue worker is supervised.** systemctl status native-update-queue should show "active (running)" with auto-restart on failure.
74
+ - [ ] **Logs do not contain API keys, JWTs, or signed URLs in plaintext.** Grep `storage/logs/laravel.log` for `Bearer eyJ`, `X-API-Key:`, `signature=`. Zero hits required.
75
+ - [ ] **Web server hides version info.** `curl -sI https://your-backend/api/health | grep -i server` should NOT show `Server: nginx/1.18.0 (Ubuntu)`. Set `server_tokens off;` in nginx config.
76
+
77
+ ## 8 — Mobile platform integration
78
+
79
+ - [ ] **Android merged manifest has no unexpected permissions.** Inspect `android/app/build/intermediates/merged_manifests/release/AndroidManifest.xml`. Sensitive permissions (CAMERA, RECORD_AUDIO, ACCESS_FINE_LOCATION, ACCESS_BACKGROUND_LOCATION, READ_CONTACTS, READ_SMS, READ_CALL_LOG, BODY_SENSORS, ACTIVITY_RECOGNITION) must each map to a privacy-policy disclosure + Data Safety entry + runtime-prompt UX.
80
+ - [ ] **iOS Privacy Manifest is complete.** Open `ios/App/App/PrivacyInfo.xcprivacy`. Required-reason API entries must cover all the APIs your app uses (the plugin's two: NSPrivacyAccessedAPICategoryUserDefaults CA92.1, NSPrivacyAccessedAPICategoryFileTimestamp C617.1).
81
+ - [ ] **ATS exceptions removed from production builds.** Inspect `ios/App/App/Info.plist`. `NSAllowsArbitraryLoads`, `NSAllowsLocalNetworking`, and per-domain exception entries should all be false / absent in the production xcconfig.
82
+ - [ ] **Network security config restricts cleartext to dev IPs only.** `android/app/src/main/res/xml/network_security_config.xml` should permit cleartext only for `10.0.2.2` / `192.168.x.x` LAN ranges, not `*`.
83
+ - [ ] **Production AAB is signed with Play App Signing.** Confirm in Play Console → Setup → App integrity. Without this, the In-App Update API does not work.
84
+
85
+ ## 9 — Specific attack paths to try
86
+
87
+ Run each of these against staging. Document the result.
88
+
89
+ - [ ] **Login-as-other-user via Firebase token swap.** Mint a Firebase ID token for user A, call `/api/dashboard/me` with it. Mint one for user B, call `/api/dashboard/me`. Confirm the response identifies the correct user in each case. Try sending user A's token with `Authorization: Bearer <token>` AND a header `X-User-Id: <user-b-id>` — should ignore the header and identify user A.
90
+ - [ ] **Cross-tenant bundle download.** As tenant A, upload bundle. Grab the signed download URL from the check response. As tenant B (different API key), try to download from that URL. Should 403 even though the URL is signed — the BundleController re-asserts `app_id` ownership.
91
+ - [ ] **Signed-URL tampering.** Take a valid signed URL, change one byte of the `signature=` parameter, request. Should 403.
92
+ - [ ] **Replay of expired signed URL.** Take a signed URL, wait past its TTL, request. Should 403.
93
+ - [ ] **Bundle ID confusion.** Generate two builds with overlapping `bundle_id` values (force via DB if needed). Check that bundle_id is unique-constrained — INSERT should fail at DB level.
94
+ - [ ] **API key prefix collision.** API keys are looked up by 12-char prefix. Brute-force the prefix space — at 16^12 you're not at meaningful collision risk, but verify with `EXPLAIN SELECT * FROM api_keys WHERE key_prefix = '<prefix>'` that the prefix column has an index (you don't want a full-table scan on every request).
95
+ - [ ] **Subscription cancellation race.** Create a subscription, cancel via dashboard, immediately try to upload a build. Should the subscription state propagate fast enough to block the upload? Define the policy and test it.
96
+ - [ ] **License-key bypass.** A user with no license tries to access a license-gated feature. Should 403. A user with an expired license_expires_at tries the same. Should 403.
97
+ - [ ] **MAU limit bypass.** A user on the free tier (100 MAU) tries to exceed it. Define the policy (soft limit with warning? hard limit?) and test it.
98
+
99
+ ## 10 — Final pre-launch sanity sweep
100
+
101
+ - [ ] **Run the test suite.** `php artisan test` (backend) — all pass.
102
+ - [ ] **Run lint.** `yarn lint` (root + website) — exit 0.
103
+ - [ ] **Run typecheck.** `yarn typecheck` (website) — exit 0.
104
+ - [ ] **Run build.** `yarn build` (root + website) — exit 0.
105
+ - [ ] **Smoke-test the full happy path.** Sign up → create app → upload bundle → device fetches → device verifies → device applies → notifyAppReady → bundle marked verified. End-to-end, on a real device, not just an emulator.
106
+ - [ ] **External healthcheck.** Use UptimeRobot / Pingdom / a similar service to monitor `/api/health` from outside your network for ~24 hours before launch. Should be 100% green.
107
+
108
+ ## What this checklist does NOT replace
109
+
110
+ A professional pentest. A SOC 2 audit. A formal threat model. Bug-bounty engagement. Independent code review of the plugin native layer (Kotlin + Swift) by someone fluent in those languages. Quarterly review and update of this checklist itself.
111
+
112
+ This is the first 80% — the fast-cheap-routine part. The remaining 20% (sophisticated attacker classes, supply-chain via deps, side-channel attacks, advanced persistent threats) needs specialist attention.
113
+
114
+ ## Authored by
115
+
116
+ [Ahsan Mahmood](https://aoneahsan.com) — author and maintainer of `native-update`.
@@ -0,0 +1,81 @@
1
+ # Native Update — Social Media Marketing
2
+
3
+ Long-form posts, WhatsApp messages, and WhatsApp status copy for promoting the **Native Update** Capacitor plugin (`native-update` on NPM) and the surrounding ecosystem (Laravel + Nova SaaS backend, CLI, native Android/iOS, React marketing/dashboard site, 3 example apps).
4
+
5
+ All content is **truthful** — only features that ship today are mentioned. No fabricated stats, no "best-in-class" puffery, no keyword stuffing. Every piece has a clear CTA.
6
+
7
+ ---
8
+
9
+ ## How this folder works
10
+
11
+ | File pattern | Purpose | Items per file | Size per item |
12
+ |---|---|---|---|
13
+ | `posts-batch-NN.md` | Posts for LinkedIn / Facebook (LinkedIn caps at 3,000 chars) | 10 | **2700–2900 chars (~490–510 words)** |
14
+ | `whatsapp-messages-batch-NN.md` | WhatsApp group / DM messages | 30 | **400–600 chars (~60–80 words)** |
15
+ | `whatsapp-status-batch-NN.md` | WhatsApp status messages | 30 | **240–400 chars (~40–60 words)** |
16
+
17
+ **Char limits are HARD limits.** LinkedIn rejects > 3,000-char posts. WhatsApp messages over ~600 chars get scrolled-past in groups. Status over ~400 chars gets visually cramped. Stay inside the windows.
18
+
19
+ ### "USED" marker convention
20
+
21
+ Once a post / message / status has been shared, **prepend `USED — ` to its heading**. Example:
22
+
23
+ ```
24
+ ## Post 03 — OTA in 60 seconds → ## USED — Post 03 — OTA in 60 seconds
25
+ ```
26
+
27
+ This lets the next session see at a glance which content has been consumed and avoid duplicates.
28
+
29
+ ### When to generate the next batch
30
+
31
+ The next session of this prompt should:
32
+
33
+ 1. Read this README first
34
+ 2. Scan `posts-batch-*.md`, `whatsapp-messages-batch-*.md`, `whatsapp-status-batch-*.md`
35
+ 3. **Only generate a new posts file** if every post in the latest posts batch is marked `USED`
36
+ 4. **Only generate a new WhatsApp messages file** if every message in the latest messages batch is marked `USED`
37
+ 5. Same rule for status files
38
+ 6. Per session: max 5 new posts files + max 2 new WhatsApp message files + max 2 new status files. Ask the user before each new file.
39
+
40
+ ### Hashtag policy
41
+
42
+ - Max 7 hashtags per post; **5 (2 generic + 3 specific) is the SEO sweet spot** — that's the default
43
+ - Generic pool (always available): `#Aoneahsan` `#AhsanMahmood` `#Zaions` `#BestOpenSourceCommunityProject` `#TopFree` `#SaaSApp`
44
+ - Per-post, pick 2 generic + 3 post-specific hashtags
45
+ - Never keyword-stuff. Princeton GEO study (KDD 2024) shows it actively reduces AI-citation share by ~10%.
46
+
47
+ ### Honesty rules (IRON-SOLID — do not break)
48
+
49
+ - Only describe features that exist in the live codebase as of the file's date
50
+ - Native Update v3.0.0 backend = **Laravel HTTP only** (Firestore was removed in v3 — never claim Firestore support)
51
+ - License is **MIT** — say so plainly
52
+ - The plugin works on **iOS + Android via Capacitor**, NOT React Native
53
+ - "OTA updates" mean **non-native JS/HTML/CSS bundle replacements** — they do not push native code changes
54
+ - App Store / Play Store policies still apply — say so when relevant
55
+ - No fabricated stars, downloads, or testimonials
56
+
57
+ ---
58
+
59
+ ## Run history
60
+
61
+ | Date | Files generated | Notes |
62
+ |---|---|---|
63
+ | 2026-05-06 | `posts-batch-01.md` | First run. 10 long-form posts covering: problem framing → plugin intro → OTA deep-dive → store-update checks → in-app review → Laravel/Nova backend → CLI → example apps → v3.0.0 BREAKING story → getting-started CTA. Source of truth: `NATIVE-UPDATE_portfolio-info_2026-05-06.md`. |
64
+ | 2026-05-06 | `whatsapp-messages-batch-01.md` | Same session. 30 short messages (~250–350 words each): feature pitches, comparisons, architecture explainers, build-in-public notes, honest-limit framing, integration walkthroughs. |
65
+ | 2026-05-07 | `whatsapp-status-batch-01.md` | 30 status messages, originally ~120–180 words each. |
66
+ | 2026-05-07 | All 3 files **rewritten** to NEW char limits: posts 2700–2900, messages 400–600, statuses 240–400. README + CLAUDE.md + AGENTS.md rule updated to reflect HARD char limits. Verified all 70 items in-spec. |
67
+ | 2026-05-07 | `posts-batch-02.md` | 10 fresh long-form posts on different angles from batch 01: founder note, Capgo/Live-Updates comparison, security model, common OTA mistakes, multi-app setup, Nova admin tour, v3 migration retrospective, performance, telemetry, roadmap. Series tag: `#NativeUpdateInside`. All 10 verified at 2700–2900 chars. |
68
+
69
+ ---
70
+
71
+ ## Source of truth for facts
72
+
73
+ Always cross-check claims against:
74
+
75
+ - `/home/ahsan/Documents/01-code/projects/native-update/NATIVE-UPDATE_portfolio-info_2026-05-06.md` — current portfolio file
76
+ - `/home/ahsan/Documents/01-code/projects/native-update/CLAUDE.md` — features + status + version
77
+ - `/home/ahsan/Documents/01-code/projects/native-update/Readme.md` — public README
78
+ - Live NPM page: https://www.npmjs.com/package/native-update
79
+ - Live homepage: https://nativeupdate.aoneahsan.com
80
+
81
+ If a fact is not in any of those, **do not write it**.