PromptStack

Mobile app with backend

The server side of a mobile product: a versioned API, token authentication, push notifications, offline sync, and an admin view. The mobile client itself is built separately.

You can change every choice once the builder opens.
Core features for the MVP
  • Versioned API with a documented contract
  • Token-based authentication with refresh and revocation
  • Device registration and push notification delivery
  • Sync endpoints returning changes since a client cursor
  • Idempotent writes so a retried request cannot duplicate data
  • Image upload with direct-to-storage presigned URLs
  • Admin view for operators, separate from the mobile API
  • Forced-upgrade signal for app versions no longer supported
Left for later
  • Real-time updates over a persistent connection
  • In-app purchase receipt validation
  • Feature flags targeted by app version
  • Analytics events sent from the client

Recommended stack

SectionRecommended
LanguageTypeScript
Frontend frameworkNext.js
UI and stylingTailwind CSSshadcn/ui
BackendNext.js server
API styleREST
Database enginePostgreSQL
Database providerNeon
ORM and data accessDrizzle
CachingUpstash Redis
AuthenticationClerk
Authorization and rolesRole-based access control
SecurityInput validationRate limitingCORS and CSRF protectionSecurity headers and CSPSecrets managementAudit logs
File storageAWS S3
Background jobs and cronInngest
Email and notificationsResend
Hosting and deploymentVercel
CI/CDGitHub Actions
Monitoring and analyticsSentryBetter Stack
TestingVitestPlaywright
ExtrasDocumentationBackupsInternationalizationAccessibility (WCAG)

Data model draft

User

An app account.

  • id
  • email
  • displayName
  • avatarUrl
  • createdAt
  • deletedAt
  • Has many Devices
  • Has many RefreshTokens
Device

One installation, used for push delivery and sync state.

  • id
  • userId
  • platform
  • pushToken
  • appVersion
  • lastSyncCursor
  • lastSeenAt
  • Belongs to one User
RefreshToken

A rotating token allowing a device to obtain new access tokens.

  • id
  • userId
  • deviceId
  • tokenHash
  • expiresAt
  • revokedAt
  • replacedById
  • Belongs to one User
  • Belongs to one Device
SyncChange

An ordered change feed the client pulls from its last cursor.

  • id
  • userId
  • entityType
  • entityId
  • operation
  • payload
  • sequence
  • Belongs to one User
PushNotification

A message queued for delivery to a device.

  • id
  • userId
  • deviceId
  • title
  • body
  • data
  • status
  • sentAt
  • Belongs to one Device