native-update 1.3.1 → 1.3.3
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 +2 -2
- package/cli/index.js +3 -3
- package/cli/node_modules/.yarn-integrity +16 -0
- package/cli/node_modules/commander/LICENSE +22 -0
- package/cli/node_modules/commander/Readme.md +1148 -0
- package/cli/node_modules/commander/esm.mjs +16 -0
- package/cli/node_modules/commander/index.js +26 -0
- package/cli/node_modules/commander/lib/argument.js +145 -0
- package/cli/node_modules/commander/lib/command.js +2179 -0
- package/cli/node_modules/commander/lib/error.js +43 -0
- package/cli/node_modules/commander/lib/help.js +462 -0
- package/cli/node_modules/commander/lib/option.js +329 -0
- package/cli/node_modules/commander/lib/suggestSimilar.js +100 -0
- package/cli/node_modules/commander/package-support.json +16 -0
- package/cli/node_modules/commander/package.json +80 -0
- package/cli/node_modules/commander/typings/esm.d.mts +3 -0
- package/cli/node_modules/commander/typings/index.d.ts +884 -0
- package/cli/package.json +1 -1
- package/cli/yarn.lock +8 -0
- package/dist/esm/__tests__/delta-processor.test.d.ts +1 -0
- package/dist/esm/__tests__/delta-processor.test.js +77 -0
- package/dist/esm/__tests__/delta-processor.test.js.map +1 -0
- package/dist/esm/__tests__/firestore-schema.test.d.ts +1 -0
- package/dist/esm/__tests__/firestore-schema.test.js +74 -0
- package/dist/esm/__tests__/firestore-schema.test.js.map +1 -0
- package/dist/esm/__tests__/manifest-reader.test.d.ts +1 -0
- package/dist/esm/__tests__/manifest-reader.test.js +271 -0
- package/dist/esm/__tests__/manifest-reader.test.js.map +1 -0
- package/dist/esm/__tests__/rollout-checker.test.d.ts +1 -0
- package/dist/esm/__tests__/rollout-checker.test.js +210 -0
- package/dist/esm/__tests__/rollout-checker.test.js.map +1 -0
- package/dist/esm/core/config.d.ts +26 -0
- package/dist/esm/core/config.js +6 -0
- package/dist/esm/core/config.js.map +1 -1
- package/dist/esm/firestore/firestore-client.d.ts +109 -0
- package/dist/esm/firestore/firestore-client.js +260 -0
- package/dist/esm/firestore/firestore-client.js.map +1 -0
- package/dist/esm/firestore/index.d.ts +11 -0
- package/dist/esm/firestore/index.js +11 -0
- package/dist/esm/firestore/index.js.map +1 -0
- package/dist/esm/firestore/manifest-reader.d.ts +87 -0
- package/dist/esm/firestore/manifest-reader.js +294 -0
- package/dist/esm/firestore/manifest-reader.js.map +1 -0
- package/dist/esm/firestore/schema.d.ts +504 -0
- package/dist/esm/firestore/schema.js +69 -0
- package/dist/esm/firestore/schema.js.map +1 -0
- package/dist/esm/live-update/delta-processor.d.ts +94 -0
- package/dist/esm/live-update/delta-processor.js +212 -0
- package/dist/esm/live-update/delta-processor.js.map +1 -0
- package/dist/esm/live-update/rollout-checker.d.ts +86 -0
- package/dist/esm/live-update/rollout-checker.js +305 -0
- package/dist/esm/live-update/rollout-checker.js.map +1 -0
- package/dist/esm/live-update/version-manager.d.ts +12 -0
- package/dist/esm/live-update/version-manager.js +67 -0
- package/dist/esm/live-update/version-manager.js.map +1 -1
- package/dist/plugin.cjs.js +1 -1
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.esm.js +1 -1
- package/dist/plugin.esm.js.map +1 -1
- package/dist/plugin.js +1 -1
- package/dist/plugin.js.map +1 -1
- package/docs/FIREBASE_QUERIES_AND_INDEXES_AUDIT.md +221 -0
- package/docs/QUICK_START.md +1 -1
- package/docs/README.md +1 -1
- package/docs/REMAINING_FEATURES.md +130 -125
- package/docs/ROADMAP.md +156 -100
- package/docs/TESTING_REQUIREMENTS.md +226 -0
- package/docs/api/API.md +1 -1
- package/docs/getting-started/installation.md +1 -1
- package/docs/guides/BACKEND_TEMPLATES_GUIDE.md +183 -0
- package/docs/play-console-rejection-rules.json +428 -0
- package/docs/reports/COMPLETE_VERIFICATION.md +1 -1
- package/docs/reports/PRODUCTION_STATUS.md +1 -1
- package/package.json +22 -20
- package/cli/cap-update.js +0 -45
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Backend Templates Guide
|
|
2
|
+
|
|
3
|
+
This guide explains the backend templates provided by the native-update CLI and how to customize them for your production environment.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `npx native-update backend create <type>` command generates backend templates for managing OTA updates. These templates are **starting points** that require customization for your specific infrastructure.
|
|
8
|
+
|
|
9
|
+
## Available Templates
|
|
10
|
+
|
|
11
|
+
| Template | Command | Use Case |
|
|
12
|
+
|----------|---------|----------|
|
|
13
|
+
| Express.js | `npx native-update backend create express` | Self-hosted Node.js server |
|
|
14
|
+
| Firebase | `npx native-update backend create firebase` | Serverless with Firebase Functions |
|
|
15
|
+
| Vercel | `npx native-update backend create vercel` | Serverless with Vercel Edge Functions |
|
|
16
|
+
|
|
17
|
+
## Template Structure
|
|
18
|
+
|
|
19
|
+
Each template includes:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
native-update-backend/
|
|
23
|
+
├── src/
|
|
24
|
+
│ ├── routes/
|
|
25
|
+
│ │ ├── updates.js # Update check/download endpoints
|
|
26
|
+
│ │ └── admin.js # Admin dashboard routes (if --with-admin)
|
|
27
|
+
│ ├── services/
|
|
28
|
+
│ │ ├── storage.js # Bundle storage service (CUSTOMIZE THIS)
|
|
29
|
+
│ │ └── database.js # Metadata storage (CUSTOMIZE THIS)
|
|
30
|
+
│ └── index.js # Entry point
|
|
31
|
+
├── package.json
|
|
32
|
+
└── README.md
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Understanding Placeholder Code
|
|
36
|
+
|
|
37
|
+
The generated templates contain placeholder implementations marked with comments explaining what you need to implement. These are **intentional customization points**, not incomplete code.
|
|
38
|
+
|
|
39
|
+
### Example: Storage Service
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
// storage.js - CUSTOMIZE FOR YOUR INFRASTRUCTURE
|
|
43
|
+
export async function storeBundle(bundleId, file) {
|
|
44
|
+
// Implement your storage logic here
|
|
45
|
+
// Options:
|
|
46
|
+
// - AWS S3: Use @aws-sdk/client-s3
|
|
47
|
+
// - Google Cloud Storage: Use @google-cloud/storage
|
|
48
|
+
// - Azure Blob: Use @azure/storage-blob
|
|
49
|
+
// - Local filesystem: Use fs/promises
|
|
50
|
+
throw new Error('Storage not configured - implement storeBundle()');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function getBundle(bundleId) {
|
|
54
|
+
// Implement your retrieval logic here
|
|
55
|
+
throw new Error('Storage not configured - implement getBundle()');
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Example: Database Service
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
// database.js - CUSTOMIZE FOR YOUR INFRASTRUCTURE
|
|
63
|
+
export async function saveBundleMetadata(metadata) {
|
|
64
|
+
// Implement your database logic here
|
|
65
|
+
// Options:
|
|
66
|
+
// - PostgreSQL: Use pg or prisma
|
|
67
|
+
// - MongoDB: Use mongoose
|
|
68
|
+
// - Firebase Firestore: Use firebase-admin
|
|
69
|
+
// - MySQL: Use mysql2
|
|
70
|
+
throw new Error('Database not configured - implement saveBundleMetadata()');
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Customization Guide
|
|
75
|
+
|
|
76
|
+
### Step 1: Choose Your Storage
|
|
77
|
+
|
|
78
|
+
| Storage Option | Package | Best For |
|
|
79
|
+
|----------------|---------|----------|
|
|
80
|
+
| AWS S3 | `@aws-sdk/client-s3` | Production, scalable |
|
|
81
|
+
| Google Cloud Storage | `@google-cloud/storage` | GCP infrastructure |
|
|
82
|
+
| Azure Blob | `@azure/storage-blob` | Azure infrastructure |
|
|
83
|
+
| Local Filesystem | `fs/promises` | Development only |
|
|
84
|
+
| Cloudflare R2 | `@aws-sdk/client-s3` | Cost-effective |
|
|
85
|
+
|
|
86
|
+
### Step 2: Choose Your Database
|
|
87
|
+
|
|
88
|
+
| Database Option | Package | Best For |
|
|
89
|
+
|----------------|---------|----------|
|
|
90
|
+
| PostgreSQL | `pg`, `prisma` | Production, relational |
|
|
91
|
+
| MongoDB | `mongoose` | Document-based |
|
|
92
|
+
| Firebase Firestore | `firebase-admin` | Serverless |
|
|
93
|
+
| SQLite | `better-sqlite3` | Small deployments |
|
|
94
|
+
| Redis | `ioredis` | Caching, fast reads |
|
|
95
|
+
|
|
96
|
+
### Step 3: Implement the Services
|
|
97
|
+
|
|
98
|
+
Replace the placeholder functions with your actual implementations:
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
// Example: AWS S3 implementation
|
|
102
|
+
import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
103
|
+
|
|
104
|
+
const s3 = new S3Client({ region: process.env.AWS_REGION });
|
|
105
|
+
|
|
106
|
+
export async function storeBundle(bundleId, file) {
|
|
107
|
+
await s3.send(new PutObjectCommand({
|
|
108
|
+
Bucket: process.env.S3_BUCKET,
|
|
109
|
+
Key: `bundles/${bundleId}.zip`,
|
|
110
|
+
Body: file,
|
|
111
|
+
}));
|
|
112
|
+
return `bundles/${bundleId}.zip`;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export async function getBundle(bundleId) {
|
|
116
|
+
const response = await s3.send(new GetObjectCommand({
|
|
117
|
+
Bucket: process.env.S3_BUCKET,
|
|
118
|
+
Key: `bundles/${bundleId}.zip`,
|
|
119
|
+
}));
|
|
120
|
+
return response.Body;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Template Options
|
|
125
|
+
|
|
126
|
+
### --with-admin
|
|
127
|
+
|
|
128
|
+
Adds an admin dashboard for:
|
|
129
|
+
- Viewing deployed bundles
|
|
130
|
+
- Monitoring update adoption
|
|
131
|
+
- Managing channels
|
|
132
|
+
- Viewing device statistics
|
|
133
|
+
|
|
134
|
+
### --with-monitoring
|
|
135
|
+
|
|
136
|
+
Adds monitoring endpoints for:
|
|
137
|
+
- Health checks
|
|
138
|
+
- Prometheus metrics
|
|
139
|
+
- Update success/failure rates
|
|
140
|
+
- Download statistics
|
|
141
|
+
|
|
142
|
+
## Production Checklist
|
|
143
|
+
|
|
144
|
+
Before deploying to production:
|
|
145
|
+
|
|
146
|
+
- [ ] Implement storage service for your cloud provider
|
|
147
|
+
- [ ] Implement database service for metadata
|
|
148
|
+
- [ ] Configure environment variables
|
|
149
|
+
- [ ] Set up authentication for admin endpoints
|
|
150
|
+
- [ ] Configure HTTPS/TLS
|
|
151
|
+
- [ ] Set up rate limiting
|
|
152
|
+
- [ ] Configure logging (Winston, Pino, etc.)
|
|
153
|
+
- [ ] Set up error tracking (Sentry, etc.)
|
|
154
|
+
- [ ] Configure backup strategy for bundles
|
|
155
|
+
|
|
156
|
+
## Environment Variables
|
|
157
|
+
|
|
158
|
+
Templates expect these environment variables:
|
|
159
|
+
|
|
160
|
+
```env
|
|
161
|
+
# Server
|
|
162
|
+
PORT=3000
|
|
163
|
+
NODE_ENV=production
|
|
164
|
+
|
|
165
|
+
# Storage (example for S3)
|
|
166
|
+
AWS_REGION=us-east-1
|
|
167
|
+
S3_BUCKET=my-update-bundles
|
|
168
|
+
AWS_ACCESS_KEY_ID=xxx
|
|
169
|
+
AWS_SECRET_ACCESS_KEY=xxx
|
|
170
|
+
|
|
171
|
+
# Database (example for PostgreSQL)
|
|
172
|
+
DATABASE_URL=postgres://user:pass@host:5432/dbname
|
|
173
|
+
|
|
174
|
+
# Security
|
|
175
|
+
API_KEY=your-admin-api-key
|
|
176
|
+
SIGNING_PUBLIC_KEY_PATH=./keys/public.pem
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Related Documentation
|
|
180
|
+
|
|
181
|
+
- [Deployment Guide](./deployment-guide.md) - Full deployment instructions
|
|
182
|
+
- [Security Best Practices](./security-best-practices.md) - Security recommendations
|
|
183
|
+
- [Key Management](./key-management.md) - Managing signing keys
|
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "play-console-rejection-rules-v1",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"lastUpdated": "2026-01-07",
|
|
5
|
+
"description": "Google Play Console rejection patterns and compliance rules based on real rejection experiences",
|
|
6
|
+
"sourceProjects": ["ClearHire"],
|
|
7
|
+
|
|
8
|
+
"rejectionReasons": [
|
|
9
|
+
{
|
|
10
|
+
"id": 1,
|
|
11
|
+
"app": "TaxRight",
|
|
12
|
+
"packageName": "com.aoneahsan.taxright",
|
|
13
|
+
"category": "metadata",
|
|
14
|
+
"policy": "Metadata Policy",
|
|
15
|
+
"issue": "Featured graphic violates policy",
|
|
16
|
+
"details": "Featured graphic contained promotional content or text not allowed by Google Play policies",
|
|
17
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9898842",
|
|
18
|
+
"fix": "Remove promotional text, rankings, testimonials from featured graphic"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": 2,
|
|
22
|
+
"app": "TaxRight",
|
|
23
|
+
"packageName": "com.aoneahsan.taxright",
|
|
24
|
+
"category": "metadata",
|
|
25
|
+
"policy": "Metadata Policy",
|
|
26
|
+
"issue": "User testimonials in description",
|
|
27
|
+
"details": "Description contained 'Trusted by 5000+ Clients' which violates metadata policy against user testimonials and user counts",
|
|
28
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9898842",
|
|
29
|
+
"fix": "Remove all user counts, testimonials, and social proof claims from description"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": 3,
|
|
33
|
+
"app": "TaxRight",
|
|
34
|
+
"packageName": "com.aoneahsan.taxright",
|
|
35
|
+
"category": "misleading_claims",
|
|
36
|
+
"policy": "Misleading Claims Policy",
|
|
37
|
+
"issue": "Missing government source links",
|
|
38
|
+
"details": "App provides government information (tax filing) but lacks clear URL links to original government sources (.gov domains)",
|
|
39
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/16680223",
|
|
40
|
+
"fix": "Add source links to official government websites and include disclaimer that app doesn't represent government entity"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": 4,
|
|
44
|
+
"app": "PregnancyPal",
|
|
45
|
+
"packageName": "com.aoneahsan.pregnancypal",
|
|
46
|
+
"category": "health_apps",
|
|
47
|
+
"policy": "Health Content and Services Policy",
|
|
48
|
+
"issue": "Inaccurate Health Apps Declaration",
|
|
49
|
+
"details": "Health features in app don't match information provided in health declaration. Must declare all applicable categories: Reproductive/Sexual Health, Activity/Fitness, Nutrition, Period Tracking, Stress Management, Diseases Management, Healthcare Services, Medical Reference, Medication Management",
|
|
50
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/16679511",
|
|
51
|
+
"fix": "Update Health apps declaration form to select ALL applicable health feature categories"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": 7,
|
|
55
|
+
"app": "PregnancyPal",
|
|
56
|
+
"packageName": "com.aoneahsan.pregnancypal",
|
|
57
|
+
"category": "broken_functionality",
|
|
58
|
+
"policy": "Broken Functionality Policy",
|
|
59
|
+
"issue": "App crashes",
|
|
60
|
+
"details": "App exhibited crashes or broken functionality during review",
|
|
61
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9888074",
|
|
62
|
+
"fix": "Test app thoroughly on multiple devices, check Android vitals, fix all crash issues"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": 8,
|
|
66
|
+
"app": "Zeact Native",
|
|
67
|
+
"packageName": "com.aoneahsan.zeactnative",
|
|
68
|
+
"category": "data_safety",
|
|
69
|
+
"policy": "Data Safety Policy",
|
|
70
|
+
"issue": "Missing Data safety form (app removed)",
|
|
71
|
+
"details": "App was removed from Play Store due to missing Data safety form",
|
|
72
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/10787469",
|
|
73
|
+
"fix": "Complete Data safety form in Play Console before submission"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"id": 9,
|
|
77
|
+
"app": "Mawinga",
|
|
78
|
+
"packageName": "com.aoneahsan.mawinga",
|
|
79
|
+
"category": "metadata",
|
|
80
|
+
"policy": "Metadata Policy",
|
|
81
|
+
"issue": "Title/description don't match app",
|
|
82
|
+
"details": "App title and/or description don't accurately reflect app functionality",
|
|
83
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9898842",
|
|
84
|
+
"fix": "Update title and description to accurately describe current app functionality"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"id": 10,
|
|
88
|
+
"app": "Trizlink",
|
|
89
|
+
"packageName": "com.aoneahsan.trizlink",
|
|
90
|
+
"category": "data_safety",
|
|
91
|
+
"policy": "Privacy Policy",
|
|
92
|
+
"issue": "Invalid Privacy policy URL",
|
|
93
|
+
"details": "Privacy policy URL doesn't link to a valid, accessible privacy policy. Must be active, publicly accessible, non-geofenced URL (no PDFs)",
|
|
94
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9859455",
|
|
95
|
+
"fix": "Ensure privacy policy URL is accessible globally, not a PDF, and contains comprehensive privacy information"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"id": 11,
|
|
99
|
+
"app": "Zeact Native",
|
|
100
|
+
"packageName": "com.aoneahsan.zeactnative",
|
|
101
|
+
"category": "data_safety",
|
|
102
|
+
"policy": "Data Safety Policy",
|
|
103
|
+
"issue": "Missing Data safety form",
|
|
104
|
+
"details": "Data safety form not completed in Play Console",
|
|
105
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/10787469",
|
|
106
|
+
"fix": "Complete Data safety form with ALL data types collected by app"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"id": 12,
|
|
110
|
+
"app": "Mawinga",
|
|
111
|
+
"packageName": "com.aoneahsan.mawinga",
|
|
112
|
+
"category": "metadata",
|
|
113
|
+
"policy": "Metadata Policy",
|
|
114
|
+
"issue": "Screenshots don't accurately describe app",
|
|
115
|
+
"details": "Screenshots shown in store listing don't accurately represent current app functionality",
|
|
116
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9898842",
|
|
117
|
+
"fix": "Update screenshots to show actual current app screens and features"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": 13,
|
|
121
|
+
"app": "Mawinga",
|
|
122
|
+
"packageName": "com.aoneahsan.mawinga",
|
|
123
|
+
"category": "user_data",
|
|
124
|
+
"policy": "User Data Policy",
|
|
125
|
+
"issue": "Image upload without prominent disclosure",
|
|
126
|
+
"details": "App requests access to photos/images without prominent disclosure explaining why access is needed",
|
|
127
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9888076",
|
|
128
|
+
"fix": "Add prominent in-app disclosure before requesting photo/camera permissions explaining purpose"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"id": 14,
|
|
132
|
+
"app": "Mawinga",
|
|
133
|
+
"packageName": "com.aoneahsan.mawinga",
|
|
134
|
+
"category": "misleading_claims",
|
|
135
|
+
"policy": "Misleading Claims Policy",
|
|
136
|
+
"issue": "Screenshots don't match app",
|
|
137
|
+
"details": "Screenshots shown in store listing don't match actual app UI/functionality",
|
|
138
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/16680223",
|
|
139
|
+
"fix": "Replace screenshots with actual current app screens"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"id": 15,
|
|
143
|
+
"app": "Mawinga",
|
|
144
|
+
"packageName": "com.aoneahsan.mawinga",
|
|
145
|
+
"category": "news_apps",
|
|
146
|
+
"policy": "News Policy",
|
|
147
|
+
"issue": "News app without contact info",
|
|
148
|
+
"details": "News/magazine app lacks accessible contact information required by policy",
|
|
149
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9935858",
|
|
150
|
+
"fix": "Add accessible contact information (email, website, phone) in app and store listing"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"id": 16,
|
|
154
|
+
"app": "Mawinga",
|
|
155
|
+
"packageName": "com.aoneahsan.mawinga",
|
|
156
|
+
"category": "misleading_claims",
|
|
157
|
+
"policy": "Misleading Claims Policy",
|
|
158
|
+
"issue": "Screenshots don't match app functionality",
|
|
159
|
+
"details": "Store listing screenshots show features or UI that don't exist in app",
|
|
160
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/16680223",
|
|
161
|
+
"fix": "Update screenshots to reflect only actual implemented features"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"id": 17,
|
|
165
|
+
"app": "NukNukApp",
|
|
166
|
+
"packageName": "com.aoneahsan.nuknukapp",
|
|
167
|
+
"category": "broken_functionality",
|
|
168
|
+
"policy": "Broken Functionality Policy",
|
|
169
|
+
"issue": "App installs but doesn't load",
|
|
170
|
+
"details": "App installed successfully but failed to load or display content",
|
|
171
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9888074",
|
|
172
|
+
"fix": "Test app startup on multiple devices, ensure app loads and responds within reasonable time"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"id": 18,
|
|
176
|
+
"app": "NukNukApp",
|
|
177
|
+
"packageName": "com.aoneahsan.nuknukapp",
|
|
178
|
+
"category": "data_safety",
|
|
179
|
+
"policy": "Data Safety Form",
|
|
180
|
+
"issue": "Device IDs not disclosed in data safety",
|
|
181
|
+
"details": "App collects device IDs but this was not disclosed in Data safety form",
|
|
182
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/10787469",
|
|
183
|
+
"fix": "Update Data safety form to include device identifiers in data collection disclosure"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"id": 19,
|
|
187
|
+
"app": "Mawinga",
|
|
188
|
+
"packageName": "com.aoneahsan.mawinga",
|
|
189
|
+
"category": "data_safety",
|
|
190
|
+
"policy": "Data Safety Form",
|
|
191
|
+
"issue": "Device IDs not disclosed in data safety",
|
|
192
|
+
"details": "App collects device IDs but this was not disclosed in Data safety form",
|
|
193
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/10787469",
|
|
194
|
+
"fix": "Update Data safety form to include device identifiers in data collection disclosure"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"id": 20,
|
|
198
|
+
"app": "Mawinga",
|
|
199
|
+
"packageName": "com.aoneahsan.mawinga",
|
|
200
|
+
"category": "broken_functionality",
|
|
201
|
+
"policy": "Broken Functionality Policy",
|
|
202
|
+
"issue": "App installs but doesn't load",
|
|
203
|
+
"details": "App installed successfully but failed to load or display content",
|
|
204
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9888074",
|
|
205
|
+
"fix": "Test app startup on multiple devices, ensure app loads within 5 seconds"
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
|
|
209
|
+
"categories": {
|
|
210
|
+
"broken_functionality": {
|
|
211
|
+
"name": "Broken Functionality",
|
|
212
|
+
"description": "App crashes, doesn't load, or functions abnormally",
|
|
213
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9888074",
|
|
214
|
+
"rules": [
|
|
215
|
+
"Test app on 3+ real devices before submission",
|
|
216
|
+
"Ensure app loads within 5 seconds",
|
|
217
|
+
"Test all user flows end-to-end",
|
|
218
|
+
"Check Android vitals for crash reports",
|
|
219
|
+
"Test on minimum supported Android version",
|
|
220
|
+
"Verify network connectivity handling",
|
|
221
|
+
"Test offline functionality if applicable"
|
|
222
|
+
],
|
|
223
|
+
"rejectionCount": 3
|
|
224
|
+
},
|
|
225
|
+
"data_safety": {
|
|
226
|
+
"name": "Data Safety & Privacy",
|
|
227
|
+
"description": "Data safety form, privacy policy, and user data handling",
|
|
228
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/10787469",
|
|
229
|
+
"rules": [
|
|
230
|
+
"Complete Data safety form in Play Console BEFORE submission",
|
|
231
|
+
"Disclose ALL data types including device IDs and analytics",
|
|
232
|
+
"Privacy policy URL must be accessible globally (not geofenced)",
|
|
233
|
+
"Privacy policy CANNOT be a PDF file",
|
|
234
|
+
"Add prominent disclosure for sensitive data access",
|
|
235
|
+
"Request runtime permissions before accessing data",
|
|
236
|
+
"Include device identifiers if using Firebase/analytics"
|
|
237
|
+
],
|
|
238
|
+
"rejectionCount": 6
|
|
239
|
+
},
|
|
240
|
+
"metadata": {
|
|
241
|
+
"name": "Metadata Policy",
|
|
242
|
+
"description": "App title, description, screenshots, icons, and graphics",
|
|
243
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9898842",
|
|
244
|
+
"rules": [
|
|
245
|
+
"Screenshots MUST match current app version exactly",
|
|
246
|
+
"NO user testimonials or user counts in description",
|
|
247
|
+
"NO store performance claims (Best, #1, Top, Leading)",
|
|
248
|
+
"NO promotional language (Free, Discount, Sale, New)",
|
|
249
|
+
"Title must be 30 characters or less",
|
|
250
|
+
"NO emojis in title, icon, or developer name",
|
|
251
|
+
"Description must accurately describe app functionality",
|
|
252
|
+
"Feature graphic must not contain promotional text"
|
|
253
|
+
],
|
|
254
|
+
"rejectionCount": 4
|
|
255
|
+
},
|
|
256
|
+
"misleading_claims": {
|
|
257
|
+
"name": "Misleading Claims",
|
|
258
|
+
"description": "False claims about app functionality or affiliations",
|
|
259
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/16680223",
|
|
260
|
+
"rules": [
|
|
261
|
+
"Provide source links for ALL government information",
|
|
262
|
+
"Include disclaimer if not government-affiliated",
|
|
263
|
+
"Screenshots must match actual current app UI",
|
|
264
|
+
"Don't claim features that don't exist",
|
|
265
|
+
"Don't claim affiliation without proper authorization",
|
|
266
|
+
"Update screenshots after every app update"
|
|
267
|
+
],
|
|
268
|
+
"rejectionCount": 4
|
|
269
|
+
},
|
|
270
|
+
"health_apps": {
|
|
271
|
+
"name": "Health Content & Services",
|
|
272
|
+
"description": "Health app declarations and content",
|
|
273
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/16679511",
|
|
274
|
+
"rules": [
|
|
275
|
+
"Complete Health apps declaration accurately in Play Console",
|
|
276
|
+
"Select ALL applicable health categories",
|
|
277
|
+
"Include medical disclaimer if not a medical device",
|
|
278
|
+
"App must NOT diagnose/treat/cure without authorization",
|
|
279
|
+
"Provide comprehensive health data privacy policy",
|
|
280
|
+
"Categories: Reproductive, Activity, Nutrition, Period Tracking, Stress, Diseases, Healthcare Services, Medical Reference, Medication Management"
|
|
281
|
+
],
|
|
282
|
+
"rejectionCount": 1
|
|
283
|
+
},
|
|
284
|
+
"news_apps": {
|
|
285
|
+
"name": "News & Magazine Apps",
|
|
286
|
+
"description": "Requirements for news/magazine category apps",
|
|
287
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9935858",
|
|
288
|
+
"rules": [
|
|
289
|
+
"Provide accessible contact information in app AND store listing",
|
|
290
|
+
"Include source attribution for all articles",
|
|
291
|
+
"Disclose if news is aggregated from third parties",
|
|
292
|
+
"Update content regularly"
|
|
293
|
+
],
|
|
294
|
+
"rejectionCount": 1
|
|
295
|
+
},
|
|
296
|
+
"user_data": {
|
|
297
|
+
"name": "User Data Policy",
|
|
298
|
+
"description": "Collection and handling of user data",
|
|
299
|
+
"policyUrl": "https://support.google.com/googleplay/android-developer/answer/9888076",
|
|
300
|
+
"rules": [
|
|
301
|
+
"Prominent disclosure BEFORE accessing photos/camera/files",
|
|
302
|
+
"Runtime permission request before data access",
|
|
303
|
+
"Clear explanation of WHY data is needed",
|
|
304
|
+
"User consent required before collection",
|
|
305
|
+
"Disclosure must be visible and not hidden in settings"
|
|
306
|
+
],
|
|
307
|
+
"rejectionCount": 1
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
|
|
311
|
+
"quickChecklist": {
|
|
312
|
+
"beforeSubmission": [
|
|
313
|
+
"App tested on 3+ real devices without crashes",
|
|
314
|
+
"App loads and responds within 5 seconds",
|
|
315
|
+
"Data safety form complete with ALL data types",
|
|
316
|
+
"Device IDs disclosed if using Firebase/analytics",
|
|
317
|
+
"Privacy policy URL accessible globally (not PDF)",
|
|
318
|
+
"Screenshots match current app version EXACTLY",
|
|
319
|
+
"No promotional/testimonial language in metadata",
|
|
320
|
+
"Title is 30 characters or less, no emojis",
|
|
321
|
+
"Feature graphic has no promotional text",
|
|
322
|
+
"Health declaration matches features (if applicable)",
|
|
323
|
+
"Government sources linked with disclaimer (if applicable)",
|
|
324
|
+
"Contact info provided (if news/magazine app)"
|
|
325
|
+
],
|
|
326
|
+
"metadataCheck": [
|
|
327
|
+
"Title ≤30 characters, no emojis",
|
|
328
|
+
"No user counts ('5000+ users', 'Million downloads')",
|
|
329
|
+
"No ranking claims ('Best', '#1', 'Top', 'Leading')",
|
|
330
|
+
"No promotional words ('Free', 'Sale', 'New', 'Discount')",
|
|
331
|
+
"No testimonials ('Users love', '5-star rated')",
|
|
332
|
+
"Screenshots reflect actual current app",
|
|
333
|
+
"Feature graphic clean (no promo text)",
|
|
334
|
+
"Description accurately describes functionality"
|
|
335
|
+
],
|
|
336
|
+
"privacyCheck": [
|
|
337
|
+
"Privacy policy URL works and loads globally",
|
|
338
|
+
"Privacy policy is NOT a PDF",
|
|
339
|
+
"Privacy policy is NOT geofenced",
|
|
340
|
+
"Data safety form complete in Play Console",
|
|
341
|
+
"ALL data types disclosed (including device IDs)",
|
|
342
|
+
"Prominent disclosure for sensitive data access"
|
|
343
|
+
],
|
|
344
|
+
"healthAppsCheck": [
|
|
345
|
+
"Health apps declaration completed",
|
|
346
|
+
"ALL health categories selected that apply",
|
|
347
|
+
"Medical disclaimer included if not a medical device",
|
|
348
|
+
"Health data handling disclosed in privacy policy"
|
|
349
|
+
]
|
|
350
|
+
},
|
|
351
|
+
|
|
352
|
+
"prohibitedWords": {
|
|
353
|
+
"rankings": [
|
|
354
|
+
"Best",
|
|
355
|
+
"#1",
|
|
356
|
+
"Top",
|
|
357
|
+
"Leading",
|
|
358
|
+
"Premium",
|
|
359
|
+
"Ultimate",
|
|
360
|
+
"Superior",
|
|
361
|
+
"Number 1",
|
|
362
|
+
"Highest rated"
|
|
363
|
+
],
|
|
364
|
+
"promotional": [
|
|
365
|
+
"Free",
|
|
366
|
+
"Discount",
|
|
367
|
+
"Sale",
|
|
368
|
+
"New",
|
|
369
|
+
"Cheap",
|
|
370
|
+
"Deal",
|
|
371
|
+
"Limited time",
|
|
372
|
+
"Exclusive",
|
|
373
|
+
"Special offer"
|
|
374
|
+
],
|
|
375
|
+
"testimonials": [
|
|
376
|
+
"users love",
|
|
377
|
+
"5-star",
|
|
378
|
+
"rated",
|
|
379
|
+
"trusted by",
|
|
380
|
+
"downloads",
|
|
381
|
+
"users worldwide",
|
|
382
|
+
"million users",
|
|
383
|
+
"satisfied customers",
|
|
384
|
+
"people use"
|
|
385
|
+
],
|
|
386
|
+
"performance": [
|
|
387
|
+
"Fastest",
|
|
388
|
+
"Most downloaded",
|
|
389
|
+
"Award-winning",
|
|
390
|
+
"Featured",
|
|
391
|
+
"Editor's choice",
|
|
392
|
+
"Staff pick"
|
|
393
|
+
]
|
|
394
|
+
},
|
|
395
|
+
|
|
396
|
+
"policyReferences": {
|
|
397
|
+
"metadata": "https://support.google.com/googleplay/android-developer/answer/9898842",
|
|
398
|
+
"misleadingClaims": "https://support.google.com/googleplay/android-developer/answer/16680223",
|
|
399
|
+
"dataSafety": "https://support.google.com/googleplay/android-developer/answer/10787469",
|
|
400
|
+
"privacyPolicy": "https://support.google.com/googleplay/android-developer/answer/9859455",
|
|
401
|
+
"brokenFunctionality": "https://support.google.com/googleplay/android-developer/answer/9888074",
|
|
402
|
+
"healthApps": "https://support.google.com/googleplay/android-developer/answer/16679511",
|
|
403
|
+
"newsApps": "https://support.google.com/googleplay/android-developer/answer/9935858",
|
|
404
|
+
"userData": "https://support.google.com/googleplay/android-developer/answer/9888076",
|
|
405
|
+
"deceptiveBehavior": "https://support.google.com/googleplay/android-developer/answer/16680223"
|
|
406
|
+
},
|
|
407
|
+
|
|
408
|
+
"statistics": {
|
|
409
|
+
"totalRejections": 18,
|
|
410
|
+
"byCategory": {
|
|
411
|
+
"data_safety": 6,
|
|
412
|
+
"metadata": 4,
|
|
413
|
+
"misleading_claims": 4,
|
|
414
|
+
"broken_functionality": 3,
|
|
415
|
+
"health_apps": 1,
|
|
416
|
+
"news_apps": 1,
|
|
417
|
+
"user_data": 1
|
|
418
|
+
},
|
|
419
|
+
"byApp": {
|
|
420
|
+
"Mawinga": 8,
|
|
421
|
+
"TaxRight": 3,
|
|
422
|
+
"NukNukApp": 2,
|
|
423
|
+
"Zeact Native": 2,
|
|
424
|
+
"PregnancyPal": 2,
|
|
425
|
+
"Trizlink": 1
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
2. **Development Tools** ✅
|
|
18
18
|
- Bundle creation utility (`tools/bundle-creator.js`)
|
|
19
19
|
- Bundle signing tool (`tools/bundle-signer.js`)
|
|
20
|
-
- CLI tool (`cli/
|
|
20
|
+
- CLI tool (`cli/index.js`)
|
|
21
21
|
- Testing framework with Vitest
|
|
22
22
|
- Unit and integration tests
|
|
23
23
|
|
|
@@ -20,7 +20,7 @@ This document summarizes the current production readiness status of the capacito
|
|
|
20
20
|
- Bundle creation utility (`tools/bundle-creator.js`)
|
|
21
21
|
- Bundle signing tool (`tools/bundle-signer.js`)
|
|
22
22
|
- Minimal backend server template (`backend-template/`)
|
|
23
|
-
- CLI tool for easier usage (`cli/
|
|
23
|
+
- CLI tool for easier usage (`cli/index.js`)
|
|
24
24
|
|
|
25
25
|
### Core Features ✅
|
|
26
26
|
- Client-side signature verification using Web Crypto API
|