Skip to content

Latest commit

 

History

History
117 lines (90 loc) · 5.99 KB

File metadata and controls

117 lines (90 loc) · 5.99 KB

Overview

🌐 Language: English · Tiếng Việt · 中文 · 한국어

What Is This?

mobile-boilerplate is a production-ready monorepo scaffold for shipping Flutter mobile applications backed by NestJS APIs on Supabase.

It provides:

  • Frontend: Flutter app with Riverpod state management, Dio HTTP client, go_router navigation, and i18n support (English + Vietnamese ready, extensible to Chinese and Korean).
  • Backend: NestJS API with Prisma ORM, structured logging (Pino), request rate limiting, default-deny authentication, and OpenAPI code generation.
  • DevOps: Docker multi-stage builds, docker-compose for local dev, semantic-release pipeline (main = production, beta = prerelease), GitHub Actions CI/CD gates.
  • Quality: Lefthook pre-commit linting, commitlint message validation, Riverpod/Jest unit tests, e2e tests, strict TypeScript, Dart linting.

Target Audience

  • Mobile teams shipping Flutter apps with a custom backend
  • Startups needing fast onboarding with best practices baked in
  • Enterprises requiring monorepo structure, audit trails (request IDs), and security defaults (default-deny auth)

In Scope

  • Single-tenant SaaS applications
  • Authentication (stub implementation; swap for JWT, OAuth, Supabase Auth)
  • Real-time data sync candidates (skeleton for WebSocket or polling)
  • Multi-flavor builds (dev/staging/prod)
  • Multi-language UI (ARB-based i18n)
  • Docker deployment on Linux (cloud-agnostic)

Out of Scope

  • E-commerce heavy lifting — no cart, inventory, payment integration (you'll add those modules)
  • Real-time protocols — WebSocket plumbing not included; add as a feature module
  • Mobile platform specifics — no iOS-only features, Android-specific native modules (flutter plugins expected)
  • Machine learning — no on-device ML or TFLite integration
  • Offline-first sync — assumes online app with occasional connectivity loss (add Drift if you need local DB)

Stack Overview

Layer Technology Notes
Mobile UI Flutter 3.27+, Material 3 theme go_router for navigation, Riverpod for state
API Client Dio 5.7+ Generated from OpenAPI spec (NestJS → Dart)
State Management Riverpod 2.5+ AsyncNotifierProvider, override pattern for tests
HTTP Server NestJS 10+, Express Structured logging (Pino), rate limiting, guards, interceptors
ORM Prisma 5+ Auto-migrations, type-safe queries
Database PostgreSQL (Supabase) SKIP_DB env flag for hello-only verification
Package Manager pnpm 9+, melos Monorepo workspaces + Dart tooling
CI/CD GitHub Actions Semantic-release, docker push, app signing
Docker Alpine Linux, multi-stage Minimal layers, build-time deps isolated

The Hello Flow (Smoke Test)

Run locally:

# 1. Backend
pnpm --filter @mobile-boilerplate/api dev
# Server runs on http://localhost:3000

# 2. Mobile (same terminal, new session)
cd apps/mobile
fvm flutter run --dart-define=FLAVOR=dev
# App connects to http://localhost:3000 (auto-resolved on emulator)

What happens:

  1. Mobile: User taps "Fetch Hello" button
  2. HTTP: Dio client sends GET /hello (auto-generated from OpenAPI spec)
  3. API: HelloController (public route, no auth needed) calls HelloService
  4. Response: { data: { message: "Hello World", timestamp }, meta: {...}, requestId: "..." }
  5. Mobile: Riverpod provider receives, UI updates with message + time

Verifies:

  • Monorepo bootstrap + codegen working
  • Backend server up, envelope wiring correct
  • Flutter→API connectivity, Dio client generated correctly
  • Riverpod state update → UI render cycle

Key Constraints

Constraint Rationale
Default-deny auth (NotImplementedAuthGuard) Security-first; swap for JwtAuthGuard when ready. Prevents accidental public endpoints.
Global rate limiting (100 req/min per IP) Abuse prevention without complex API tiering. Tunable via env.
Whitelist DTO validation Rejects unknown fields; prevents model injection attacks.
No @Controller() without path argument Explicit routing clarity; prevents accidental nested routes.
@Public() only for /hello, /health, /login Default is "require auth"; public is opt-in.
Feature modules isolated (no cross-feature imports) Loose coupling, easier to delete/reuse features.
Max 200 lines per code file Improves readability, encourages single responsibility.
Conventional commits (feat:, fix:, refactor:) Clear changelog, semantic-release automation.

Development Workflow

  1. Plan — sketch feature scope, database schema
  2. Implement Backend — add NestJS module, DTO, controller, service, test
  3. Regenerate Clientpnpm codegen:api generates Dart api_client
  4. Implement Frontend — add Flutter feature (entity, repository, provider, UI, test)
  5. Test — unit tests (Jest on backend, Riverpod+mocktail on mobile), e2e tests
  6. Commit — conventional message, push to feature branch
  7. CI Gate — GitHub Actions runs linting, tests, codegen check
  8. Merge — PR review, auto-squash merge
  9. Release — semantic-release reads commits, bumps version, tags, pushes to production/prerelease

Success Metrics

  • Onboarding time: New dev reads getting-started.md → full environment running in 15 min
  • Feature velocity: Backend module + Flutter feature + tests + release in 1–2 sprints
  • Code quality: 0 any types, 80%+ test coverage on business logic, 0 lint errors
  • Deployment reliability: Automated releases with zero-downtime schema migrations, rollback via git tag

Next Steps

Local Development Setup to clone and run locally

System Architecture for detailed component breakdown

Code Standards to understand conventions before first commit