Skip to content

real world example, cutting-edge technologies driven, cross-platform app

Notifications You must be signed in to change notification settings

kuubson/online-library

Repository files navigation

πŸ’» js fullstack app, monorepo (web & mobile)

Stack Preview Notes Flow Packages Docs Tools Goals Scripts Env Tips

πŸ”§ Stack Β CircleCI

TypeScript React React Native Redux Styled Components React Hook Form

NodeJS Express.js GraphQL Socket.io JWT Swagger Sequelize

Vite Cypress Turborepo Railway CircleCI Firebase Postgres

Note See the stack for the mobile app

πŸ“Ί App preview

Home Login form Sample error
home login form error
Store Profile Book preview
store profile
v.mp4
Chat Cart Stripe
chat cart cart

Note Preview the mobile app

πŸ“„ Some notes

Note A cutting-edge technologies driven πŸ’―, fullstack, cross-plaftorm app, hosted on πŸ“‘ Railway

Acts as a fake store with possibility to chat πŸ’¬ with other users:

  • account registration, fb / credentials login
  • user support (forgot password, lost activation link)
  • store fulfilled with paid and free books
  • payments with stripe or paypal
  • push notifications to stay up to date with what other writes
  • possibility to send images / videos / files
  • searchbar for books
  • preview of books inside the profile tab
  • targets both web and mobile app users
  • UX: infinite loaders (store, chat), proper error handling, push notifications, fully responsive, jump to the last unread message (chat)

πŸ“Š Flow

graph TD

api-->turborepo

%% --------------------------

turborepo[\Turborepo/]-->apps
turborepo-->lib("@online-library")

%% --------------------------

config(config)-->lib
core(core)-->lib
logic(logic)-->lib

lib-->apps((apps))

%% --------------------------

railway[\Railway/]-->db[("PostgreSQL")]
db[("PostgreSQL")]-->sequelize[\Sequelize/]
sequelize-->server
railway-->server

Cypress[\Cypress/]-->web
apps-->server(server)
apps-->web(web)
apps-->native(native)

Firebase[\Firebase/]-->native
CircleCI-->Cypress
online-library-releases-->native
CircleCI[\CircleCI/]-->online-library-releases{{online-library-releases}}

%% --------------------------

auth("auth (jwt)")-->api{API}

express("express (swagger)")-->api

graphql("graphql (apollo)")-->api

socket("socket.io")-->api
Loading

Note See distribution flow for the mobile app

πŸ“¦ Custom local packages

@online-library/config @online-library/core @online-library/logic
  • yup config
  • constants, urls, global types
  • custom wrapper (api.ts) of an autogenerated swagger.json that exposes useful, strongly typed API variable
  • redux config
  • graphql config
  • simulated i18 config
  • shareable: styles, hooks, helpers, utils, types
  • hooks for both web and mobile apps

πŸ›‘ Documentation

Note Docs are available in the development environment

REST API (OpenAPI) GraphQL API
Swagger.mp4
autogenerated with a few additional comments (common Apollo Studio Explorer)

πŸ†’ Tools

πŸ€– Automation

  • every push to the master branch triggers the autodeployment on Railway + CircleCI build workflow (linting, e2e tests, new release of the mobile app that requires an approval)
  • @trivago/prettier-plugin-sort-imports for keeping a consistent order of imports (custom flow)
  • graphql-codegen for autogenerating the code (hooks & types) from gql schema & documents
  • @graphql-tools/merge for auto merging resolvers & type defs into schema (custom wrapper to detect duplicated resolvers)
  • swagger-autogen for autogenerating the API docs (allow skipping YAML hell 😈)

πŸ”© Side tools

🎯 Future goals

  • CRA ~> Vite
  • add e2e tests (cypress)
  • switch stack graphql + sequelize ~> tRPC + prisma
  • make use of storybook.js
  • run app in a Docker container
  • integrate Sentry for monitoring the app
  • finish setup for i18n
  • add WebRTC for video chat
  • replace errors popup with react-toastify
  • tweak seeding db flow

Note See goals for the mobile app

⌨ Root scripts

Note To run locally, install proper version of nodejs (use nvm / see .nvmrc), fill .env (see Environment variables and .env-example), trigger yarn install and yarn dev

Warning Remember to bump release tag version (config.yml) when pushing to the master branch othwerise CircleCI will fail

command description
yarn start triggers start script in /server ~> runs server production build
yarn start:testing triggers start:testing script in /server ~> runs server production build for CircleCI + Cypress purposes
yarn dev triggers dev pipeline ~> launches apps, bundles all packages (watchmode)
yarn lib:dev triggers filtered dev pipeline ~> bundles only packages (watchmode)
yarn lint triggers lint pipeline ~> ts & eslint & stylelint check through all apps and packages
yarn test triggers test pipeline ~> runs tests for mobile app
yarn test:e2e triggers test:e2e script in /web ~> runs e2e tests for web app
yarn cypress triggers cypress script in /web ~> runs e2e tests for web app
yarn build triggers build pipeline ~> build all apps, bundles all packages
yarn postbuild triggers yarn lib script ~> makes sure that all packages are built on top of the newest docs
yarn lib triggers lib:build pipeline ~> bundles all packages and updates API (OpenAPI) docs (must keep certain order of scripts)
yarn android triggers android script in /native ~> runs the android app
yarn metro triggers metro script in /native ~> runs the metro server
yarn server triggers dev script in /server ~> runs the express server
yarn codegen triggers graphql codegen ~> generates hooks & types from graphql schema
yarn postinstall triggers yarn lib script ~> makes sure that build pipeline runs without any errors

πŸ”Ž Detailed scripts

command server web each package
yarn start runs the server production build (serves also the web app) ❌ ❌
yarn start:testing runs the server production build with NODE_ENV set to testing (needed for CircleCI + Cypress) ❌ ❌
yarn dev runs express server with NODE_ENV set to development runs the react app bundles the package (watchmode)
yarn lint lint & ts check lint & ts & stylelint check lint & ts check
yarn test:e2e ❌ runs e2e tests ❌
yarn build builds the express server & copies (copyfiles) gql related files to /dist builds the react app bundles the package

Note See scripts for the mobile app

πŸ”’ Environment variables

details server web
cloudinary API credentials CLOUDINARY_API_KEY CLOUDINARY_API_SECRET CLOUDINARY_NAME ❌
PostgreSQL credentials DATABASE_HOST DATABASE_NAME DATABASE_PASSWORD DATABASE_USERNAME ❌
secret key for jsonwebtoken JWT_KEY ❌
email address for the email sender (eg. no-reply@online-library.com) NODEMAILER_USERNAME ❌
nodemailer testing credentials (nodemailer.createTestAccount) NODEMAILER_TEST_USER NODEMAILER_TEST_PASSWORD ❌
SMTP provider (nodemailer credentials) MAILJET_USER MAILJET_PASSWORD ❌
paypal API credentials PAYPAL_CLIENT_ID PAYPAL_CLIENT_SECRET ❌
web-push package credentials (web-push generate-vapid-keys) PRIVATE_VAPID_KEY VITE_PUBLIC_VAPID_KEY VITE_PUBLIC_VAPID_KEY
fb app credentials FACEBOOK_APP_SECRET VITE_FACEBOOK_APP_ID VITE_FACEBOOK_APP_ID
stripe API credentials STRIPE_SECRET_KEY VITE_STRIPE_PUBLISHABLE_KEY
set to true to re-autogenerate db models from existing tables (generates all methods for associations) SEQUELIZE_AUTO ❌
set to true to seed db with some random books SEED_BOOKS ❌
set to true to seed db with a test user SEED_USER ❌

Note See envs for the mobile app

πŸ” CircleCI variables (+ all envs for the server)

Note To be able to run e2e tests, all server env variables are also required on the CircleCI

variable details
GITHUB_TOKEN personal access token for Github CLI orb
RELEASE_KEYSTORE_BASE64 release keystore converted to base64 (more info)
RELEASE_KEYSTORE RELEASE_KEY_ALIAS RELEASE_KEY_PASSWORD RELEASE_STORE_PASSWORD keystore related details (more info)

πŸ“™ Tips

  • Remember to update the HOST variable in @online-library\config\src\utils\urls.ts when changing a target domain