Code Standards
These are the coding baselines AppTrovo's automated pipeline enforces and our reviewers look for. Following them reduces soft rejections, lowers your post-sale support load, and correlates strongly with higher ratings and repeat sales.
1. Non-negotiable baseline
If any of these is missing, expect a rejection:
- No hardcoded secrets. API keys, DB passwords, Stripe keys, signing secrets — all read from
.env/ environment variables. A.env.examplelists every key with placeholder values. - SQL injection — use parameterised queries or an ORM. Never concatenate user input into an SQL string. Our scanner flags concatenations next to
mysql_*,mysqli_query,PDO::query, or rawDB::select/DB::statementwith interpolation. - XSS — escape every dynamic value rendered to HTML. In Blade, use
{{ }}(auto-escapes) not{!! !!}unless you've already sanitised. In plain PHP usehtmlspecialchars(). In JS, avoidinnerHTMLwith untrusted values. - CSRF — every state-changing endpoint (POST/PUT/PATCH/DELETE) validates a CSRF token. In Laravel this is automatic via
@csrf; in plain PHP you must implement it. - Authentication — passwords stored with
bcryptorargon2id, never plain text, never MD5/SHA1. No custom crypto. - File uploads — validate MIME type, cap file size, strip executable extensions, and store outside the webroot (or serve via a controller that enforces auth).
- No remote code execution paths — no
eval(), noshell_exec/exec/systemon anything derived from user input. - Dependencies are current —
composer audit/npm audit/pip-auditshould report zero high or critical CVEs. Known-vulnerable versions incomposer.lockorpackage-lock.jsontrigger a Dependency Audit failure.
2. General principles
- Single Responsibility — each function / class does one thing, does it well, and its name reflects that.
- Meaningful names —
$u,$data,$temp,$flagare not names.$activeSubscriber,$pendingInvoices,$avatarPathare. - Error handling — every external call (network, DB, filesystem, subprocess) has a try/catch or checked return. Never swallow exceptions silently.
- No debug code — no
var_dump,print_r,dd(),console.log,debugger, or commented-out blocks left in the submission. - Consistent formatting — pick one style per language and apply it to every file. Automated formatters are fine.
- Comments explain why, not what. The code already says what. Comments should point out non-obvious constraints, gotchas, or workarounds for specific bugs.
3. Language-specific standards
3.1 PHP
- Minimum PHP 8.1. Prefer 8.2+.
- Follow PSR-12 (coding style) and PSR-4 (autoloading). Run
php-cs-fixerbefore you submit. - Use type hints on every parameter, return, and property. Missing return types are flagged by static analysis.
- Use namespaces; no global functions or global classes outside
src//app/. - Prefer
readonlyproperties andenums over class constants where they fit. - For Laravel products: target Laravel 11 or 12, migrations must be reversible (
up()anddown()), and controllers should be thin (no business logic — use services / actions).
3.2 JavaScript / TypeScript
- ES2022+ syntax. No
var. Preferconstunless reassignment is needed. - TypeScript strongly preferred for any project over ~500 LOC. Enable
"strict": trueintsconfig.json. - Pin dependency versions in
package.json. Commitpackage-lock.json(npm) orpnpm-lock.yaml/yarn.lock. - Run
eslintandprettier. Zero errors, ideally zero warnings. - No
innerHTMLwith dynamic content. UsetextContentor framework-templated rendering. - For React/Vue products: no direct DOM manipulation outside effect hooks; no inline
onClick-string handlers; keep components under ~300 lines.
3.3 Python
- Minimum Python 3.10. Use type hints throughout.
- Follow PEP 8. Run
ruffandblack. - Ship either
requirements.txt(pinned) orpyproject.tomlwith a lockfile. - Use virtual environments — don't install into the system Python.
- For Django/Flask products: settings read from env, secrets never in
settings.py.
3.4 Other stacks
- Go:
gofmt,golangci-lint, pinned modules viago.mod/go.sum. - Ruby/Rails:
rubocop,Gemfile.lockcommitted, Rails 7.1+. - .NET: current LTS, SDK + project files committed,
dotnet formatclean.
4. Database
- Ship migrations for schema, not raw SQL dumps. Migrations must run cleanly on an empty database.
- Seeders create sensible demo data; document default admin credentials and remind the buyer to change them.
- Support at least one of MySQL 8 or PostgreSQL 14+. Products that support both rank higher.
- Add indexes on foreign keys and any column used in
WHEREclauses that fire on common requests. - Use transactions for multi-statement writes (order + order items, user + profile, etc.).
- No destructive migrations without a clear warning in the changelog — if a migration drops a column, say so loudly.
5. Frontend
- Accessibility — every form input has a label, every image has alt text, focus order is logical, colour contrast passes WCAG AA.
- Responsive — usable at 375px width (mobile) and 1280px (desktop). No horizontal scroll.
- No mixed content — all assets loaded over HTTPS.
- CSP-friendly — avoid inline event handlers and inline styles where you can; they force buyers to weaken their Content Security Policy.
- Bundle size — if you ship a compiled frontend, the default bundle should be under ~500 KB gzipped for home/landing routes. Code-split heavy admin views.
6. Installer & license integration
For paid products, your installer is the buyer's first impression. It must:
- Run from a clean environment to first login in under 5 minutes.
- Validate the AppTrovo license key via
GET /api/v1/licenses/verify(the Laravel Installer SDK handles this for Laravel products). - Cache the license locally so the app works offline; re-verify periodically (we recommend every 7 days).
- Handle the failure modes clearly: invalid key, expired license, exhausted domain slots, network failure. Never leave the buyer on a white screen.
- Remove or gate the installer routes after setup —
/installshould 404 once the app is installed. A flag in the DB or anAPP_INSTALLED=trueenv var is typical. - Ship with the production API URL set (
https://apptrovo.com). AnyAPPTROVO_DEV_BYPASS-style flag you added while testing must be removed before submission.
Before submitting, use your free developer test license (generated from the product edit page) and run the 6 pre-submit verification scenarios. This catches roughly half of all installer-related rejections.
7. Testing & quality
- Ship at least smoke tests covering the install path and the 3–5 core user flows of your product.
- Document how to run the test suite in your README.
- Products with meaningful test coverage get priority in manual review and rank higher in search.
- No test fixtures with real PII, real payment credentials, or real API keys.
8. Documentation baseline
Your README.md at minimum covers:
- One-paragraph overview — what the product does.
- Requirements — PHP/Node/Python version, required extensions, database, server specs.
- Installation — exact, copy-pasteable commands from an empty directory to a running app. Include the
apptrovoinstaller flow if applicable. - Configuration — every env/config key your product reads and what it does.
- First-run setup — admin account, seeds, how to change the default password.
- Upgrade path — how buyers apply a new version.
- Troubleshooting — the 5 most common install errors and fixes.
- Support & contact — link to AppTrovo support; do not include personal email or external links.
9. Changelog
Use Keep-a-Changelog format:
## [1.2.0] - 2026-03-15
### Added
- Multi-tenant support behind MULTI_TENANT flag
### Changed
- Upgraded to Laravel 12
### Fixed
- Race condition in the invoice generator under high load
### Security
- Patched CVE-2026-1234 in phpmailer dependency
Every Upgrade submission that changes behaviour must include a matching CHANGELOG.md entry.
10. What "high quality" looks like on AppTrovo
Products that consistently rank, convert, and retain buyers share these traits:
- One-command install that works the first time on a stock server.
- A README a new buyer can follow without asking a single question.
- Clear separation between "core product" and "optional integrations" — no hard dependency on paid third-party services.
- Sensible defaults — the product does the right thing with an empty
.envplus the 3–4 required values. - Graceful failure everywhere — network down, DB restarting, disk full: the product logs and recovers, not 500s.
- Consistent visual and API design — buyers can learn the whole product in an hour.
Related pages
- Submission Guidelines — the submission workflow and what gets checked.
- License Integration Guide — wire your installer to AppTrovo's license API.
Last updated April 20, 2026