feat(achievements): answer in the language the client asks for

Achievement names, descriptions and category labels, the secret placeholder and the monthly
challenge are text the server writes and every client shows as is, so they stayed English in a
translated web page and will in the localized iOS app. The routes that return them now read
Accept-Language and answer in that language, with Vary: Accept-Language.

The translations live in the web's catalogs under serverText, so Crowdin, its checks and its
translators handle them through the existing pipeline; the server reads that subtree, and the image
copies the catalogs beside dist. English is never looked up: a request without the header, and
every client that predates it, gets the bytes it got before. A test keeps serverText in en.json
equal to the seed and the constants it mirrors. The web now sends its chosen language on every API
request, and the Accept-Language matcher moved into @bookorbit/types so the client and the server
negotiate the same way.

The iOS app is a consumer the web client does not show: it will send its own interface language.
App Store builds that predate that still send the device language, so on a non-English device they
will start getting translated achievement names inside English screens. That was accepted; the
response shape does not change.

Ref bookorbit/bookorbit-ios-support#79
This commit is contained in:
neon
2026-10-30 02:21:07 +00:00
parent 1beb17d218
commit 199ba687c3
16 changed files with 899 additions and 100 deletions
+2
View File
@@ -71,6 +71,8 @@ ENV PORT=3000
COPY --from=server-builder --chown=node:node /deploy ./
COPY --from=client-builder --chown=node:node /app/client/dist ./public
# The server reads its own translated text (achievements, monthly challenges) from the web's catalogs.
COPY --from=client-builder --chown=node:node /app/client/src/locales ./locales
COPY --from=server-builder --chown=node:node /app/server/entrypoint.sh /app/server/file-env.sh ./
COPY --chown=node:node LICENSE NOTICE ADDITIONAL_TERMS.md ./
COPY --chown=node:node server/bin/kepubify/ ./bin/kepubify/