Chapter 2

Technical architecture

One Express process is the system of record. Clients, Excel ops, and the IMDb preprocess pipeline all converge there. Recommendations are user-to-user (or circle) rows with an optional review and chat thread — not a standalone ML service. The empty recommendation-services repo is not a missing production dependency.

Source: static read of the nine repositories, Sequelize associations, mounted Express routes, and OpenAPI annotations · September 2026.

9Sibling repos
5 liveProduction surfaces
4 stubEmpty or scaffold
~105Sequelize models
Interactive schema 21 tables from Sequelize + migrations. Click a box for columns, keys, validations, and stored procedures. API request / response samples 24 representative endpoints across auth, movies, watchlist, reviews, follow/circles, profile, trailers, search.

Container map

Clients & ops mobile-app-new RN 0.74 · iOS / Android web-app Next.js 14 · App Router data-ingestion Python · Excel → admin aws / imdb_json Lambda · Step Functions Application backend · Express /api JWT · /web · /v2 · admin · cron Socket.IO path /sockets Next 13 in API festival · account Data stores MySQL :3306 ~105 models · Sequelize Redis :6379 optional model cache OpenSearch movie search index S3 IMDb diffs · uploads SaaS Firebase FCM push notifications SendGrid transactional email TMDB · JustWatch trailers · streaming Google · Apple · FB OAuth identity

Live runtime. data-services, recommendation-services, devops, and nokio-batch-job-app are omitted because they do not run in production.

Public hosts

EnvironmentAPIWeb
Productionapp.nokioapp.com · api.nokio.comnokioapp.com
Stagingstaging-app.nokioapp.com · api.staging.nokio.comstaging-webapp.nokioapp.com

Mobile env templates point at staging-app / staging-webapp. Deploy is GitLab CI + PM2; Azure pipeline templates are also present. IMDb Lambdas are operated manually (no in-repo IaC).

Request path

  1. Client Mobile axios or web fetch. Base URL is SERVER_URL/api or NEXT_PUBLIC_API_URL/api.
  2. Header Authorization uses scheme jwt <accessToken> on the API. Web NextAuth stores backend tokens; mobile uses Redux persist plus AsyncStorage. Web HTTP stacks still disagree on Bearer vs JWT vs raw token.
  3. Express morgan → body-parser (50mb) → fileupload → cors → correlationId. Mounted at /api.
  4. Passport JWT Strategy extracts scheme jwt. Payload { id, userType, region } becomes req.user — not reloaded from MySQL.
  5. Handler Legacy fat routes call helpers/models. Newer /web and /v2 use DTOs, services, and a few repositories.
  6. Stores Sequelize/MySQL is the system of record. Redis caches some models. OpenSearch serves movie search. Optional Socket.IO emit or FCM.

Service catalog

UnitStackTalks to
backendExpress, TypeScript ~4.7, Sequelize, node-cron, Socket.IO, small Next 13 in the same repoMySQL, Redis, OpenSearch, S3, FCM, SendGrid, TMDB, JustWatch, OAuth IdPs
web-appNext.js 14 App Router, NextAuth, TanStack Query, CSS Modules, pnpmHTTP /api only
mobile-app-newRN 0.74, React Navigation 6, Redux Persist, React Query, Firebase, Sentry, MixpanelHTTP + Socket.IO /sockets + FCM
data-ingestionPython scripts, JWT to admin/content APIsbackend admin routes
aws / imdb_jsonLambda, Step Functions, EventBridge, S3S3; backend cron pulls diffs

Domains

The core domain is a social graph around movies. Catalog and editorial content (new releases, upcoming, pick of the week, trailers, festivals) is mixed with user-generated reviews, circles, recommendations, stories, and chat.

EntityAnchorsNotes
Userplatforms, circles, sessions, FCM, promptsTypes GU / PPU / GUEST / WEB / admin
Moviegenres, persons, platforms, slugs, festivalsIMDb ingest + TMDB / JustWatch enrichment
Reviewuser, movie, circles, reactions, storiesChat messages hang off reviews
Circleowner, members, reviews, optional festivalGroup feed + group chat room
Recommendationfrom/to user, circle, movie, reviewThumbs-up + chat messages
Watchlistuser, movie, platform, newReleaseRelease notifications target this
FilmFestivalcategories, movies, nominations, circlePublic web + Next pages in the API repo
Story / ReviewStoryuser, reviewHome surface on web and mobile
Notification / ChatMessageusers, circle, review, movie, recHTTP + Socket.IO + FCM

Cross-client coverage

DomainWebMobileBackend home
Home / catalogRegion home, new-releases, trailersHome tab/web, /newrelease, /upcomingMovie
Movie detailmovie/[slug]Movie stack (incl. Movie_DEPRECATED leftovers)/movies, /web/movie, /movie-slugs
Circlescircles/*Circles tab + SingleCircle/circles, /v2/circles, /web/circles
Recommendationsmy-recommendations, profile recsLibrary + RecommendMovie/users/recommendations*, /web/recommendations
ChatRecommendations-with-chat HTTPSocket.IO + CommentThread/chat + /sockets
Festivalsfestivals/*FestivalList, Festival, PanelDiscussion/film-festival* + Next src/app/festival
StoriesHome Stories carousel onlyCreate, view, react, comment/stories
Auth / profileNextAuth + my-profile / edit-profileSignIn/Up + Settings/, /users, /v2, /users/profile

Data stores and pipelines

StoreConfigUsed for
MySQLdialect mysql, :3306 — README still says PostgresSystem of record · ~269 migrations
Redisioredis :6379 lazyConnectOptional model/app cache — API still runs without it
OpenSearchMovie search indexTitle search
S3IMDb diffs and uploadsPreprocess output; cron ingest

IMDb pipeline

Large IMDb JSON is split, diffed, and merged in Lambdas, then stored on S3. Backend cron pulls diffs. Streaming gzip/readline design is the strongest engineering in the workspace. No IaC in-repo.

Editorial Excel

Operators run Python against excels/ and POST to admin APIs: new releases, upcoming, pick of the week, trailers, streaming info. This is how catalog rails stay current between IMDb dumps.

Core schema

About 105 Sequelize models. The diagram is the social-movie core. Click a box to open columns, keys, relations, validations, and any MySQL procedures. The full 21-table catalog is on Schema.

Users id · userType · region GU / PPU / GUEST / WEB Movies imdbId PK · slugs genres · platforms · trailers Circles owner · members optional festival Reviews user + movie reactions · stories · chat Recommendations from / to / circle movie · optional review Watchlists user + movie platform · release ping ChatMessages review or rec thread Socket.IO + FCM Notifications 12+ event types mobile inbox · FCM

Accent boxes are the two write-heavy social objects. Click a box for the detail panel. Junction tables and procedures are on Schema.

Notable schema facts

API surface

Express mounts a large OpenAPI-documented surface at /api. Live docs: express-swagger-generator (/api-docs.json). Clients regenerate TypeScript from that contract, then apply local schema.ts overrides. Dual auth generations exist: v1 opaque refresh on User, v2 session + hashed refresh. Request and response samples for 24 representative endpoints are on API.

GroupAuth mixWhat it covers
AuthPublic + v2email/password, Google, Apple, Facebook, refresh, forgot/reset, email confirm, app-version gate, account delete
UsersJWT / v2register, profile, onboarding, platforms, languages, PPU convert, FCM token, favorites, review reactions
MoviesJWTsearch, slug lookup, homepage rails, reviews CRUD, threads, reactions, recommend, trailers, seasons
SocialJWTcontacts, circles, followers, recommendations-with-chat, mute notifications
ChatJWT + socketsHTTP chat plus Socket.IO open/close/post/react; offline peers get FCM
CatalogJWT / adminnewrelease, upcomingMovie, pick-of-the-week, trailers, streaming-info
FestivalJWT + publictypes, programs, nominations, schedule, panel; public web routes
Web publicMostly public + cacheNewer /web/* DTO layer used by the Next.js app
v2Session tokenslogin/refresh/logout, register, PPU, homepage filters
AdminRole-gatedcontent ops, Excel landing endpoints, god-file admin.ts

Representative endpoints

MethodPathAuthNote
POST/loginPublicemail/password → access + v1 refresh
POST/v2/loginV2session + hashed refresh
POST/google-login · /apple-login · /facebook-loginPublicIdP tokens
POST/usersPublicregister
GET/PATCH/users/profileJWTown profile
POST/v2/users/ppuV2create public-profile user — web has no UI
GET/movies/v2/{slug}JWTweb movie page
POST/movies/{id}/reviewJWTcreate/update review
POST/movies/{id}/recommendationsJWTrecommend a title
GET/users/contactsJWTnetwork
GET/web/movie/{slug}Web publicEra B DTO movie
POST/account/delete-userPublic*account deletion — web has no UI

The OpenAPI schema already exposes notifications, PPU registration, account delete, circle mutes, and push schedule. Mobile consumes them. Web does not. Closing those gaps is UI work, not a new backend.

Architectural risk Dual API generations (v1 and v2), dual auth header schemes on web, JWT identity without DB revalidation, and a Next 13 surface living inside the API repo for festivals/account. New endpoints should go to /web or /v2 with DTOs — not into movies.ts or admin.ts.
Previous Codebase Next User journeys