Skip to content

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.example lists 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 raw DB::select / DB::statement with interpolation.
  • XSS — escape every dynamic value rendered to HTML. In Blade, use {{ }} (auto-escapes) not {!! !!} unless you've already sanitised. In plain PHP use htmlspecialchars(). In JS, avoid innerHTML with 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 bcrypt or argon2id, 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(), no shell_exec / exec / system on anything derived from user input.
  • Dependencies are currentcomposer audit / npm audit / pip-audit should report zero high or critical CVEs. Known-vulnerable versions in composer.lock or package-lock.json trigger 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, $flag are not names. $activeSubscriber, $pendingInvoices, $avatarPath are.
  • 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-fixer before 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 readonly properties and enums over class constants where they fit.
  • For Laravel products: target Laravel 11 or 12, migrations must be reversible (up() and down()), and controllers should be thin (no business logic — use services / actions).

3.2 JavaScript / TypeScript

  • ES2022+ syntax. No var. Prefer const unless reassignment is needed.
  • TypeScript strongly preferred for any project over ~500 LOC. Enable "strict": true in tsconfig.json.
  • Pin dependency versions in package.json. Commit package-lock.json (npm) or pnpm-lock.yaml / yarn.lock.
  • Run eslint and prettier. Zero errors, ideally zero warnings.
  • No innerHTML with dynamic content. Use textContent or 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 ruff and black.
  • Ship either requirements.txt (pinned) or pyproject.toml with 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 via go.mod / go.sum.
  • Ruby/Rails: rubocop, Gemfile.lock committed, Rails 7.1+.
  • .NET: current LTS, SDK + project files committed, dotnet format clean.

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 WHERE clauses 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 — /install should 404 once the app is installed. A flag in the DB or an APP_INSTALLED=true env var is typical.
  • Ship with the production API URL set (https://apptrovo.com). Any APPTROVO_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:

  1. One-paragraph overview — what the product does.
  2. Requirements — PHP/Node/Python version, required extensions, database, server specs.
  3. Installation — exact, copy-pasteable commands from an empty directory to a running app. Include the apptrovo installer flow if applicable.
  4. Configuration — every env/config key your product reads and what it does.
  5. First-run setup — admin account, seeds, how to change the default password.
  6. Upgrade path — how buyers apply a new version.
  7. Troubleshooting — the 5 most common install errors and fixes.
  8. 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 .env plus 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

Last updated April 20, 2026