Skip to main content

Build and Production

This document describes how to build each part of the Qprint project, what options to pass (including --dart-define and environment variables), and the difference between debug, profile, and release builds.


Build types (Flutter apps)

Flutter supports three build modes:

ModeCommandUse caseOptimizationsAssertions
Debugflutter run (default) or flutter run --debugDevelopment, hot reloadNoneEnabled
Profileflutter run --profile or flutter build apk --profilePerformance profilingYes (no debug symbols)Disabled
Releaseflutter run --release or flutter build apk / flutter build windowsProduction, distributionFull (minified, tree-shaken)Disabled
  • Debug: Slower, larger binary; assertions and kDebugMode == true; certificate pinning is disabled in the apps for easier dev.
  • Profile: Like release but with profiling tools; use for measuring performance.
  • Release: Smallest, fastest; certificate pinning enabled; use for production and store builds.

Backend (Go API)

Location: backend/

How to run (development)

cd backend
go run cmd/api/main.go

How to build (production)

cd backend
go build -o bin/api ./cmd/api
./bin/api

Configuration

The backend has no --dart-define. All configuration is via environment variables, typically from a .env file or host (e.g. Render).

VariableRequiredDescription
PORTYes (production)Server port (e.g. 8080 local, 10000 on Render)
DATABASE_URLYesPostgreSQL connection string
JWT_SECRETYesAt least 32 characters
ALLOWED_ORIGINSYes (production)Comma-separated CORS origins
ENVIRONMENTRecommendeddevelopment or production
USE_LOCAL_STORAGEOptionaltrue for local uploads dir
AWS_S3_BUCKET, AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYOptionalS3 file storage
RAZORPAY_*, RESEND_API_KEY, etc.OptionalSee Environment Variables

See Environment Variables and Deployment for full lists.


Frontend (Next.js)

Location: frontend/

How to run (development)

cd frontend
npm run dev

How to build (production)

cd frontend
npm run build
npm run start # optional: serve built app

Configuration

The frontend uses build-time env vars. Values are baked in at next build.

VariableRequiredDescription
NEXT_PUBLIC_API_URLYes (production)Backend API base URL (e.g. https://qprint-72wr.onrender.com)

Where to set:

  • Local: frontend/.env.local
    NEXT_PUBLIC_API_URL=http://localhost:8080
  • Production (e.g. Vercel): Project settings → Environment Variables → add NEXT_PUBLIC_API_URL for Production.

Note: Only variables prefixed with NEXT_PUBLIC_ are available in the browser. The app uses process.env.NEXT_PUBLIC_API_URL (see frontend/lib/api.ts); default fallback is http://localhost:8080.


Shopkeeper app (Flutter – Windows)

Location: shopkeeper_app/

How to run (development)

cd shopkeeper_app
flutter pub get
flutter run -d windows

With a specific API URL:

flutter run -d windows --dart-define=BASE_URL=http://localhost:8080

How to build (production / release)

Option 1 – Use the provided script (recommended for Windows):

cd shopkeeper_app
.\build_windows.bat

This script:

  1. Ensures SumatraPDF (and optionally LibreOffice) is in windows/runner/bin/
  2. Runs flutter clean and flutter pub get
  3. Runs flutter run -d windows --release --dart-define=BASE_URL=https://qprint-72wr.onrender.com

Option 2 – Manual build:

cd shopkeeper_app
flutter clean
flutter pub get
flutter build windows --dart-define=BASE_URL=https://qprint-72wr.onrender.com

Output: build/windows/x64/runner/Release/ (e.g. shopkeeper_app.exe).

Dart-defines and config

DefineRequiredDescription
BASE_URLYes (production)Backend API base URL (e.g. https://qprint-72wr.onrender.com)

Default: If BASE_URL is not passed, the app uses https://qprint-72wr.onrender.com (see shopkeeper_app/lib/config/app_config.dart).

Examples:

# Production (or use build_windows.bat which already passes this)
flutter run -d windows --release --dart-define=BASE_URL=https://qprint-72wr.onrender.com
flutter build windows --dart-define=BASE_URL=https://qprint-72wr.onrender.com

# Local backend
flutter run -d windows --dart-define=BASE_URL=http://localhost:8080

Customer app (Flutter – Android)

Location: customer_app/

How to run (development)

cd customer_app
flutter pub get
flutter run -d android

With API URL and optional Maps key:

flutter run -d android --dart-define=BASE_URL=http://10.0.2.2:8080 --dart-define=MAPS_API_KEY=your_key

(Use 10.0.2.2 for Android emulator to reach host localhost.)

How to build (production / release)

APK (installable file):

cd customer_app
flutter build apk --dart-define=BASE_URL=https://qprint-72wr.onrender.com --dart-define=MAPS_API_KEY=your_key

App Bundle (for Play Store):

flutter build appbundle --dart-define=BASE_URL=https://qprint-72wr.onrender.com --dart-define=MAPS_API_KEY=your_key

Output: build/app/outputs/ (e.g. app-release.apk or app-release.aab).

Dart-defines and config

DefineRequiredDescription
BASE_URLYes (production)Backend API base URL
MAPS_API_KEYOptionalGoogle Maps API key (can also be set in android/local.properties as MAPS_API_KEY=...)
CERT_PINSOptionalComma-separated SHA-256 certificate fingerprints for leaf pinning; if unset, app uses intermediate CA pinning

Defaults: If BASE_URL is not set, the app uses https://qprint-72wr.onrender.com. See customer_app/lib/config/app_config.dart.

Examples:

# Production
flutter build apk --dart-define=BASE_URL=https://qprint-72wr.onrender.com --dart-define=MAPS_API_KEY=your_key

# Optional: certificate pinning (leaf fingerprints)
flutter build apk --dart-define=BASE_URL=https://... --dart-define=CERT_PINS="AA:BB:CC:..."

# Emulator (local backend)
flutter run -d android --dart-define=BASE_URL=http://10.0.2.2:8080

Android-specific: MAPS_API_KEY can be set in customer_app/android/local.properties instead of --dart-define; the build injects it into the manifest (see customer_app/android/app/build.gradle.kts).


Summary: options by target

TargetBuild / runKey options
Backendgo run cmd/api/main.go or go build -o bin/api ./cmd/apiEnv only (.env): PORT, DATABASE_URL, JWT_SECRET, ALLOWED_ORIGINS, ENVIRONMENT
Frontendnpm run build (or npm run dev)NEXT_PUBLIC_API_URL in .env.local or Vercel env
Shopkeeper (Windows).\build_windows.bat or flutter build windows--dart-define=BASE_URL=https://qprint-72wr.onrender.com
Customer (Android)flutter build apk or flutter build appbundle--dart-define=BASE_URL=... and optionally --dart-define=MAPS_API_KEY=..., --dart-define=CERT_PINS=...

Scripts reference

ScriptPurpose
shopkeeper_app/build_windows.batOne-shot: SumatraPDF/LibreOffice setup, flutter clean, flutter pub get, then flutter run -d windows --release --dart-define=BASE_URL=https://qprint-72wr.onrender.com
run_shopkeeper_release.bat (repo root)Starts already-built shopkeeper exe: shopkeeper_app\build\windows\x64\runner\Release\shopkeeper_app.exe (run build_windows.bat or flutter build windows first)
buildscript.bat (repo root)Sets BACKEND_URL and FRONTEND_URL, updates frontend/.env.local and (legacy) shopkeeper api_service.dart, then offers to build Frontend / Windows app / Android. Note: Shopkeeper app now uses AppConfig.baseUrl from --dart-define=BASE_URL, not a hardcoded value in api_service.dart.
buildscript.sh (repo root)Linux/macOS equivalent of buildscript.bat; updates frontend env and (legacy) shopkeeper file, then builds Frontend / Linux app / Android.
startlocal.batStarts backend and frontend; can patch backend copy of customer app API URL (see script).

Production checklist

  • Backend: ENVIRONMENT=production, JWT_SECRET 32+ chars, ALLOWED_ORIGINS set to your frontend URL(s), no TEST_MODE=true.
  • Frontend: NEXT_PUBLIC_API_URL set to your production backend URL (e.g. https://qprint-72wr.onrender.com).
  • Shopkeeper Windows: Build with --dart-define=BASE_URL=https://qprint-72wr.onrender.com (or your API URL); use build_windows.bat or equivalent.
  • Customer Android: Build with --dart-define=BASE_URL=https://qprint-72wr.onrender.com (and MAPS_API_KEY if using maps); use release signing for Play Store.

For full deployment steps, see Deployment and Environment Variables.