In a nutshell, this is a simple app that allows you to upload photos and view them in a gallery.
live on https://spahi4.me | development on https://dev.spahi4.me/?login=true (user upload enabled here)
- Focused on fancy UI and animations as it's a portfolio project
- PC-first design
- Photos upload (resize, compress, convert, focused primarily on HDR images)
- Photos gallery by location
- Photo details page with HQ image, exif data, likes and comments
- Admin panel with basic CRUD operations
- Email notifications on new comments and likes
- Authentication with Google
- Production ready infrastructure with AWS and Cloudflare
- Production ready graphql API with Postgraphile
- Production ready security with JWT
- CI/CD with Github Actions; linting
SSR, tests (TBD), wide browser support (TBD)
It's a pnpm
monorepo with the following structure:
workspaces:
- client - React app with vite, react-router, apollo, material-ui
- server - Node.js app with fastify and postgraphile
- worker - Node.js app with graphile-worker, ffmpeg, nodemailer
- db - graphile-migrate migrations and seeds
- config - common environment variables loader and public .env files
Workspaces feature is one of the main selling points of pnpm
as it's really fast and allows to share dependencies between packages.
infrastructure:
- terraform - Terraform configuration for AWS and Cloudflare
To speed up tsc
compilation, every package has its own tsconfig.json with composite
option enabled, and root tsconfig.json has references
to all packages.
Dependencies between packages are resolved with pnpm
workspace:*
protocol and nodejs --conditions
flag to distinguish between dev
and prod
environments.
- nodejs >= 20.5.0 (server is running locally instead of docker-compose to speed up development)
- docker
- ffmpeg (if worker is running locally instead of docker-compose)
corepack enable; # enable pnpm
pnpm install; # install dependencies, setup git hooks
docker-compose up -d; # start postgres
pnpm run gm:migrate --filter db; # run migrations
pnpm run dev; # start server, client and worker in watch mode, stream logs from all services
Industrially proven eslint and prettier are used for linting and formatting, nothing special here.
Lint-staged is used to run linters and formatters on husky hook for typescript, json, sql, terraform and other files.
Simple diagram of google oauth flow:
JWT flow:
More details in server/README.md and client/README.md
Tests with jest added for db, server
In progress:
- e2e tests with cypress (test runner is ready, but tests are not)
- client tests with react-testing-library (test runner is ready, some tests are written)
- worker tests with jest
- fix performance on low-end PCs
- #24: react-router scroll bug