Application reference. This is an illustrative architecture and scope checklist, not a verified customer project or measured deployment. Technologies, integration scope and delivery items are agreed for the actual brief.
Scenario and Constraints
A service product where iOS and Android share the same workflows and a small team has to maintain both. Three constraints shape the design: unreliable mobile networks, app-store review cycles that make hotfixes slow, and the need to change business rules without shipping a new build.
Architecture
Layers and responsibilities
| Layer | Technology | What it is responsible for |
|---|---|---|
| App | Flutter (Dart), layered into UI / state / repository | Screens and interaction. The repository layer is the only thing that knows whether data came from the network or the local cache, which keeps offline handling out of the UI code. |
| Local store | SQLite (drift) + platform secure storage | Cached entities, an outbox of pending writes, and tokens in secure storage rather than shared preferences. |
| API | Go + Gin, versioned routes | Business rules, validation, authorisation. Versioned from day one because old app builds stay in users' hands long after release. |
| Storage | PostgreSQL | Transactional data; JSONB used for genuinely variable attributes instead of endlessly widening tables. |
| Cache / queue | Redis | Sessions, rate limiting, idempotency keys and background job queue. |
| Push | FCM and APNs behind one notification service | A single internal API for notifications; platform differences are handled server-side, not in the app. |
| Admin | Vue admin panel | User, content and order management, plus the remote-config values that change app behaviour without a release. |
Data Model
The tables below carry the rules that everything else depends on. Getting these wrong is what turns a working demo into a system that cannot be extended.
Core entities
| Entity | Key fields, relations and rules |
|---|---|
| user / auth_identity | One user may hold several identities (phone, Apple, Google, WeChat). Separating identity from user is what makes adding a login method later a migration-free change. |
| device | Push token, platform, app version and locale per device. Notification targeting and staged rollouts both read from here. |
| order / booking | The domain entity with an explicit state column plus a transition log, so 'how did it reach this state' is answerable in support. |
| outbox (client-side) | Queued local writes with a client-generated UUID. That UUID becomes the idempotency key on the server, which is what makes retry-after-timeout safe. |
| sync_cursor | Per-user updated_at watermark driving incremental sync, so the app pulls deltas instead of refetching whole collections. |
| remote_config | Key-value configuration by app version and platform, letting rules and feature flags change without an app-store submission. |
Key Interfaces
Endpoints that carry the business rules
| Endpoint | Purpose and concurrency notes |
|---|---|
| POST /api/v1/auth/token | Issues a short-lived access token plus a rotating refresh token. Refresh rotation limits the damage from a stolen token on a device you cannot reach. |
| GET /api/v1/sync?since= | Incremental pull of records changed since a cursor, paginated and capped, so a user returning after weeks offline cannot pull an unbounded response. |
| POST /api/v1/orders | Accepts the client UUID as an idempotency key; a retry after a network timeout returns the original order instead of creating a duplicate. |
| POST /api/v1/devices | Registers or refreshes the push token, tied to user and app version for targeted and staged notifications. |
| GET /api/v1/config | Returns remote configuration for the requesting app version — the mechanism that avoids shipping a build for a rule change. |
Technical Decisions
- Flutter over two native codebases. The workflows are shared and the team is small, so shared application code can reduce duplicated maintenance where the workflows overlap; platform integrations, device checks and releases still require separate work. Where platforms genuinely differ — payment, push, biometrics — the difference is isolated behind a platform channel rather than allowed to leak into shared code.
- Offline-tolerant, not offline-first. Reads are cached and writes are queued in an outbox, but the server stays authoritative. Full offline-first with conflict resolution costs considerably more and is only worth it when users genuinely work disconnected for long periods.
- Client-generated UUIDs as idempotency keys. Mobile networks time out mid-request routinely. Without this, timeout retries can create duplicate-order risk that must be tested.
- API versioned from the first release. Users postpone updates, so the server must keep serving old builds. Retrofitting versioning after launch is far more expensive than starting with it.
- Remote config for business rules. Client releases depend on platform review and user adoption. Supported thresholds, copy and feature flags may be managed server-side where platform rules allow; changes requiring a new app build retain that dependency.
Hypothetical Design Targets
The figures below are hypothetical capacity-planning examples, not measured client results, a validated sizing recommendation or an SLA. Set project-specific acceptance targets after defining the workload, devices, data, hardware and third-party dependencies; verify them through a pilot and load tests before committing to a production target.
Capacity and performance targets
| Target | Value and assumption |
|---|---|
| Cold start to first meaningful screen | Under 2 seconds on a mid-range Android device, assuming cached data renders while the network refresh runs behind it. |
| Incremental sync | Delta payload under 200 KB for a typical returning user, with page size capped so a long-absent user degrades gracefully rather than timing out. |
| API latency | p95 under 300 ms for standard reads, excluding third-party calls whose latency we do not control. |
| Push delivery | Define and measure application enqueue and provider-acknowledgement timing. Final delivery timing belongs to the platform and is not guaranteed by this reference. |
What Delivery Includes
- Flutter app source, Go backend source and Vue admin source in your repository
- Build and signing configuration for both platforms, plus store listing preparation
- API documentation, database schema and migration history
- Deployment notes, monitoring and log access, backup and restore procedure
- App Store and Google Play submission support; review outcome and timing remain with Apple and Google
Planning This for Your Business
The modules above are a starting point, not a fixed package. We normally cut the first release to one core workflow plus one admin workflow, then extend once real usage shows where the load and the edge cases actually are. Send a scoped brief and we will map it against this architecture and tell you which parts you do not need yet.

