Chapter 5
Recommendations and sequenced plan
Four tracks, in order. Security is a production incident, not a backlog item. UX truth is making the live site match the FAQ. Architecture is stopping Era A from growing. Parity is letting a signed-in web user finish the social loop without installing the app — only after the first three tracks have a foothold.
Track A — Security and hygiene (P0)
| Action | Owner repo | |
|---|---|---|
| P0 | Rotate and purge committed secrets (backend env file, mobile APNs .p8). Scrub git history with the ops owner. Confirm nothing in this report’s appendix is still live. | backend, mobile-app-new |
| P0 | Replace PBKDF2 with 1 SHA-1 iteration. Use bcrypt, Argon2, or high-cost PBKDF2. Plan a password rehash on next login. | backend |
| P0 | Revalidate JWT users from DB. Fix the public festival route that reads req.user without passport. | backend |
| P1 | Remove NEXTAUTH_SECRET || "your-secret" fallback. Unify Authorization header scheme (Bearer vs raw vs JWT) across web HTTP stacks and the API. | web-app, backend |
| P1 | Await/catch all in-process cron jobs. Add tsc to backend CI (SWC build is not a typecheck). | backend |
Track B — UX truth on web (P0 / P1)
These are the changes that make the live site stop contradicting the product story. Ordered by how much they unblock a first-time or newly signed-in user.
| Change | Unlocks | |
|---|---|---|
| P0 | Search page: put the field on the page. Empty /movies should prompt “type a title” or show a default catalog — not sort chips over a blank pattern. | Find a title |
| P0 | One breakpoint map. CSS custom-media = JS useBreakpoints. Drop DEFAULT_WIDTH 1600 for layout. Hide desktop Nav below 960. 44px min hit area. Search min-width 0. | Every page, especially tablet |
| P0 | Home: wait for session before painting the rail. Empty recs/watchlist get honest copy, not clipped grey cards. Lead with the trailer; collapse Filters; preferred languages only. | Signed-in home |
| P0 | Star rating: a click without prior pointermove must register. Trailer thumbs play, they do not apply a platform filter. | Write a review; watch a trailer |
| P1 | Hide store FAB when signed in. Put Get the App in the hamburger. Restore Sign In (or a bottom-bar equivalent) on phone browsers. | Phone web usable |
| P1 | About us: header, one paragraph, Sign in / Get the app / Home. FAQ accordion; align copy with what home actually shows until home is social. | Marketing not a dead end |
| P1 | Auth-gated empty shells (watchlist, followers, edit profile when signed out) must prompt sign-in, not a blank pattern. | Guest → member |
| P1 | App Router error.tsx / global-error.tsx. Stop return null on query isError (~28 contexts). | Failures visible |
| P1 | Stack home columns at 960, not only 640. Profile grid minmax(0, 1fr). Stack edit-profile SidePanel under 960. Drop CreateReview 25rem min-width. | Tablet + phone movie/profile |
Track C — Architecture (P1 / P2)
| Action | Why | |
|---|---|---|
| P1 | New API work only under routes/web or /v2 with DTOs and validators. Freeze growth of movies.ts / admin.ts. | Era B is already the better island |
| P2 | Deduplicate mobile useContactActionMutation (8 copies). Finish Movie_DEPRECATED removal. | Change risk on every contact/movie fix |
| P2 | Route/integration tests around auth, movies, admin hotspots. Grow Detox past auth into Home / Movie / Circles. | Gates that currently pass without catching domain bugs |
| P2 | Correct README Postgres → MySQL. Package data-ingestion (requirements.txt, shared client). IaC for IMDb Lambdas. | Ops drift |
| P3 | Do not staff data-services, recommendation-services, or nokio-batch-job-app until there is a concrete job those repos must do. Recommendations are already user-to-user rows in MySQL. | Empty repos invite parallel incomplete systems |
Track D — Web/mobile parity (P1 / P2)
Ordered by how much they unblock the same user staying on web after sign-in — not by engineering size. Backend already exposes several of these.
| Order | Work | Unblocks |
|---|---|---|
| 1 | Notification inbox (read, open, accept/decline) | Friend requests and recs without leaving web |
| 2 | Create/manage group circles | The Circles model the FAQ already describes |
| 3 | PPU registration + profile switch | Creator path without the app |
| 4 | Account delete + Contact Us + theme | Settings parity and trust |
| 5 | Story player (view/react) then create | Home Stories matching mobile |
| 6 | Circle chat | Largest remaining social gap; needs sockets on web |
Guest browse, SEO URLs, and the install funnel can stay web-only. Push notifications can stay mobile-first. Chat is the expensive item; do not start it until the inbox and groups exist.
Suggested 90-day shape
Days 1–14
- P0 secret rotation and hashing
- JWT revalidation
- Search field on /movies
- Star-rating click + trailer-thumb play
- One breakpoint map + header hit targets
Days 15–45
- Signed-in home empty states
- Hide FAB when signed in; restore phone Sign In
- error.tsx; stop return-null on isError
- About / FAQ honesty
- Notification inbox on web
- tsc in backend CI; cron await/catch
Days 46–90
- Group circles on web
- Account delete + Contact Us
- Tablet home stack + profile grid
- Shared mobile mutation hooks; Movie_DEPRECATED removal
- Auth + movie route tests
- Decide explicitly: web is discovery+movie, or web is the full social product. Staff Track D only if the answer is the latter.
Decision the customer should make
Option 1 — Web as discovery
Keep web as browse, movie page, follow public profiles, and an install funnel. Fix search, tablet, About, and signed-in empty states. Do not build chat or groups on web. Mobile remains the social product. Smaller engineering surface; FAQ and Circles nav must be rewritten to match.
Option 2 — Web as full product
Staff Track D. Inbox first, then groups, then PPU create, then stories, then sockets. Same user can finish the loop in a browser. Larger cost; matches current FAQ and Circles IA. Do not do this while P0 secrets and hashing are open.
Onboarding the next engineer
- Read this report, then
web-app/CONTRIBUTING.mdandaws/imdb_json/README.md. - Run the P0 security checklist with the ops owner — do not copy secrets into tickets.
- Backend tour:
src/app.ts→routes/index.ts→ oneroutes/webflow → contrast withroutes/movies.ts. - Client tour: one web query hook + model class; mobile navigation + one React Query screen.
- Only then take feature work — using Era B patterns.
Document control
| Field | Value |
|---|---|
| Title | Nokio platform technical assessment |
| Date | 3–4 September 2026 |
| Classification | Confidential — customer deliverable |
| Method | Static codebase review of nine sibling GitLab repos; Playwright against production web (signed-out, signed-in, device agents, multiple viewports) |
| Not in scope | Penetration test, load test, full CVE scan, App Store / Play build review, production traffic analytics |
| How to submit | Zip the customer-assessment-report folder and send. Recipient opens index.html in a browser. Each page prints to PDF. |