Skip to content
Open

1.8.6 #172

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
179 commits
Select commit Hold shift + click to select a range
1b4e6a2
Bump to 1.8.6 and update PWA/upgrade docs
awehttam Mar 5, 2026
943bae3
Add i18n phase 0 foundation and API error_code migration
awehttam Mar 5, 2026
61ac948
Phase 3: migrate API/admin errors to specific error_code taxonomy
awehttam Mar 5, 2026
778fa76
Phase 3: eliminate generic API/admin errors with domain error codes
awehttam Mar 5, 2026
88bb373
Phase 4: migrate frontend/admin error handling to error_code-aware paths
awehttam Mar 5, 2026
2457a9e
Harden apiError termination and address-book error_code responses
awehttam Mar 5, 2026
4ea1eed
Normalize remaining route error responses to apiError
awehttam Mar 5, 2026
0825a0c
Add i18n error-key coverage check and sync missing EN keys
awehttam Mar 5, 2026
f3bce9d
Add i18n hardcoded-string regression check
awehttam Mar 5, 2026
01d6955
Add i18n missing-key runtime logging in Translator
awehttam Mar 5, 2026
494bc35
Add Spanish locale scaffold catalogs
awehttam Mar 5, 2026
152d86a
Translate Spanish i18n common and error catalogs
awehttam Mar 5, 2026
abd8a75
Migrate high-traffic UI script literals to i18n keys
awehttam Mar 5, 2026
b7d4325
Show address book form errors inside modal
awehttam Mar 5, 2026
09c407c
Refresh i18n hardcoded-string allowlist baseline
awehttam Mar 5, 2026
64e1d50
Localize static Netmail and Echomail Twig UI text
awehttam Mar 5, 2026
5e431c1
Localize static Compose and Settings Twig UI text
awehttam Mar 5, 2026
23f2084
Localize Polls and Shoutbox templates and scripts
awehttam Mar 5, 2026
da4cd04
docs: document i18n workflow and contributor guidance
awehttam Mar 5, 2026
8d54e51
docs: refresh translation proposal phase status
awehttam Mar 5, 2026
a195c49
Continue i18n migration and update translation phase status
awehttam Mar 5, 2026
d46a345
Complete admin i18n migration for appearance and binkp config
awehttam Mar 5, 2026
06ba98e
Fix i18n CI checks to run without Composer autoload
awehttam Mar 5, 2026
c2e7eed
Continue i18n UI localization across admin and nodelist templates
awehttam Mar 5, 2026
b118e66
Complete Twig i18n migration and refresh translation status
awehttam Mar 5, 2026
29f7db8
Fix i18n: translate BBS menu labels and remove dead t() elseif branch
awehttam Mar 5, 2026
af2e2f9
i18n: normalize controller API errors for address book, auth reset, a…
awehttam Mar 5, 2026
a7fbbc5
i18n: normalize webdoor API errors with error_code payloads
awehttam Mar 5, 2026
9783999
i18n: normalize API error payloads and key web error pages
awehttam Mar 6, 2026
8e6651d
i18n: expand API message_code coverage across admin and user flows
awehttam Mar 6, 2026
6babdfa
Add automated test suite and fix Template false type error
awehttam Mar 6, 2026
d4f0b20
Add functional test suite (30 tests across 7 feature areas)
awehttam Mar 6, 2026
c1ac00e
i18n: localize route errors and web fallback flows
awehttam Mar 6, 2026
ca4b278
feat: anonymous native door access, PubTerm door, guest doors page
awehttam Mar 6, 2026
2c088f2
feat: pubterm icon, guest doors page nav link, upgrade doc updates
awehttam Mar 6, 2026
81cbccd
Merge branch 'xlate' into claudesbbs
awehttam Mar 6, 2026
b0e50c0
Merge pull request #169 from awehttam/claudesbbs
awehttam Mar 6, 2026
bfa4b50
i18n: localize guest doors page, login pubterm button, and bbs_settin…
awehttam Mar 6, 2026
9922984
Merge pull request #170 from awehttam/xlate
awehttam Mar 6, 2026
bac040b
Add Localization.md, fix echomail/netmail identity timing bug, update…
awehttam Mar 6, 2026
83960eb
Fix guest doors nav visibility and subtitle text
awehttam Mar 6, 2026
4cdc93b
docs: update file structure diagrams and add Apache WebSocket proxy e…
awehttam Mar 6, 2026
80c6f1d
docs: use binkterm-php as root in file structure diagrams, add Native…
awehttam Mar 6, 2026
1cbd739
docs: add NativeDoors.md file structure link in Doors.md
awehttam Mar 6, 2026
3477436
feat: resolve X-Forwarded-For client IP in multiplexing server for tr…
awehttam Mar 6, 2026
183a86b
Localize settings date-format labels and user profile transaction types
awehttam Mar 6, 2026
123ec46
fix: wire up ?locale= query param override in Template locale resolution
awehttam Mar 6, 2026
898806d
fix: resolve password reset email locale via LocaleResolver instead o…
awehttam Mar 6, 2026
3e6ffdc
fix: i18n timing on init-loaded JS pages; fix insecure node boolean p…
awehttam Mar 6, 2026
4004460
fix: defer echoareas table load until i18n catalog ready
awehttam Mar 6, 2026
6f3fdbd
fix: defer activity stats load until i18n catalog ready
awehttam Mar 6, 2026
b58ba02
i18n: defer JS init loads until catalog ready; cache catalog in SW; l…
awehttam Mar 6, 2026
000e58a
i18n: translate telnet server UI strings
awehttam Mar 6, 2026
9bba6db
docs: note telnet daemon localization support in UPGRADING_1.8.6
awehttam Mar 6, 2026
7277870
fix: switch service worker to cache-first strategy for CSS/JS
awehttam Mar 6, 2026
003bb63
fix: activate new SW immediately and reduce fetch handler latency
awehttam Mar 6, 2026
9819218
fix: prevent SW reinstall on every page load
awehttam Mar 6, 2026
9cea606
fix: serve fonts from SW cache (extend fetch handler to woff2/woff/tt…
awehttam Mar 6, 2026
40d1b45
fix: remove skipWaiting() from install event to stop reinstall loop
awehttam Mar 6, 2026
0c7ad43
docs: add service worker caching fix to UPGRADING_1.8.6
awehttam Mar 6, 2026
42e09a5
feat: add per-session logger to multiplexing server for log correlation
awehttam Mar 6, 2026
387c510
fix: use full session ID in session logger prefix
awehttam Mar 6, 2026
785978f
fix: include session log label in [DB] and [DROPFILE] log lines
awehttam Mar 6, 2026
bd1cc92
multiplexing-server: propagate session logger into emulator adapters
awehttam Mar 6, 2026
454f646
multiplexing-server: shorten session log label; restore timestamps
awehttam Mar 6, 2026
e545689
feat: language phrase overlay editor for sysops
awehttam Mar 7, 2026
2fffab6
fix: exclude non-locale directories from auto-discovery in Translator
awehttam Mar 7, 2026
48a037f
feat: show English source value in key column of i18n overrides editor
awehttam Mar 7, 2026
2723717
fix: use double-fork in spawnCommand to properly daemonize binkp_poll
awehttam Mar 7, 2026
078b146
fix: capture binkp_poll stdout/stderr in log file via proc_open
awehttam Mar 7, 2026
a217e7a
fix: use absolute project root as cwd for spawned binkp_poll
awehttam Mar 7, 2026
a689b1d
fix: pass --no-console to spawned binkp_poll to prevent duplicate log…
awehttam Mar 7, 2026
a3ddfc5
feat: add TLS encryption support to telnet daemon (experimental)
awehttam Mar 7, 2026
4d8fbc7
fix: do TLS handshake in child process, not before fork
awehttam Mar 7, 2026
5b4c0fc
docs: remove SyncTERM compat note from TLS telnet entry
awehttam Mar 7, 2026
cc2b22b
feat: pure-PHP SSH-2 server with shared BBS session logic
awehttam Mar 7, 2026
2f5087e
docs: add SSH server and TLS fix entries to UPGRADING_1.8.6
awehttam Mar 7, 2026
a8fe14a
* First failed native SSH authentication now fall through to BBS lo…
awehttam Mar 7, 2026
44855a5
update README
awehttam Mar 7, 2026
918547b
feat: server.log via admin daemon; FSC-0032 quote formatting
awehttam Mar 7, 2026
455e0e3
* update UPGRADING_1.8.6.md
awehttam Mar 7, 2026
3b895f8
Fix ZMODEM transfer reliability and closeout handling
awehttam Mar 8, 2026
2f62bf9
Consolidate terminal docs and fix telnet CR/LF stream warning
awehttam Mar 8, 2026
7c54b02
Update UPGRADING_1.8.6 and restart_daemons for SSH/terminal server
awehttam Mar 8, 2026
434b9a9
feat: file areas in terminal server (telnet + SSH)
awehttam Mar 8, 2026
019e034
* remove reference to FileAreas and Doors from TerminalServer.md
awehttam Mar 8, 2026
8124c8a
fix: file area loops forever on idle timeout disconnect
awehttam Mar 8, 2026
c785f32
Rename terminal i18n namespace from ui.telnet to ui.terminalserver
awehttam Mar 8, 2026
b6abc1e
Use external sz/rz on non-Windows and gate terminal transfers
awehttam Mar 8, 2026
00cb6b5
Disable terminal transfers by default and document zmodem caveats
awehttam Mar 8, 2026
1fc11a5
Localize SSH pre-auth banner using terminalserver catalog
awehttam Mar 8, 2026
26ddd21
don't mention zmodem in UPGRADING_1.8.6.md because it's flakey
awehttam Mar 8, 2026
37108ca
Improve Z-modem reliability and daemon restart tooling
awehttam Mar 8, 2026
66199fd
Add --stop flag and stop_service() to restart_daemons.sh
awehttam Mar 8, 2026
a7e5660
Add --start flag and start_service() to restart_daemons.sh
awehttam Mar 8, 2026
09fe5f0
Fix sz blocking deadlock on Linux PTY path
awehttam Mar 8, 2026
f54bf7b
Fix sz relay: restore $conn blocking mode and harden rawWrite
awehttam Mar 8, 2026
b61025d
Document TELNET_ZMODEM_FORCE_PHP and clarify file transfer env vars
awehttam Mar 8, 2026
7609ce3
Handle ZFIN after ZEOF in PHP ZMODEM sender
awehttam Mar 8, 2026
bd18a2f
Add Gemini home network stats and label public echo areas
awehttam Mar 8, 2026
beb8907
Show Gemini network stats across all active echo areas
awehttam Mar 8, 2026
cebbd50
Move Gemini echo area stats below public echo area list
awehttam Mar 8, 2026
9d826c9
Fix SIGPIPE and EINTR crashes in SSH daemon during file transfers
awehttam Mar 8, 2026
321a24c
Add env switch for echomail date ordering
awehttam Mar 8, 2026
f36e672
Document network ports in README
awehttam Mar 8, 2026
c0cf3b5
Fix ZMODEM 'Garbage count exceeded' errors in ZOC terminal
awehttam Mar 8, 2026
6f8f697
Refine README BinkP and port table entries
awehttam Mar 8, 2026
473898f
Add file detail view to telnet file area
awehttam Mar 8, 2026
7ec2bd5
Clarify web-based configuration recommended in README
awehttam Mar 8, 2026
1ba43b6
Add docs/CONFIGURATION.md and trim README configuration section
awehttam Mar 8, 2026
08b38c4
Restore network ports to README; link weather.json to README_weather.…
awehttam Mar 8, 2026
3abd48f
Move Credits System docs to docs/CreditSystem.md; leave blurb and lin…
awehttam Mar 8, 2026
45d2db3
Update 1.8.5 release date; add CreditSystem.md link to features list
awehttam Mar 8, 2026
54199d8
Fix multi-level echomail quote leading space per FSC-0032
awehttam Mar 8, 2026
f184dbd
Add file rename feature to web interface
awehttam Mar 8, 2026
3835760
Select basename only when opening file rename dialog
awehttam Mar 8, 2026
0530cc3
Fix telnet IAC/binary-mode issues, ZMODEM drain, CR+LF handling, and …
awehttam Mar 8, 2026
c2015a1
Fix ZMODEM upload perf, netmail quoting, and attachment upload error …
awehttam Mar 8, 2026
0039f3f
Support netmail attachments to local users and fix inbox visibility
awehttam Mar 8, 2026
15c4f7d
Allow netmail attachment senders to download files from recipient's p…
awehttam Mar 8, 2026
9491590
Fix echomail/netmail quoting: blank lines, 75-char wrap, attribution …
awehttam Mar 8, 2026
28c6137
Cap thread indentation at 3 levels in netmail list view
awehttam Mar 8, 2026
dd54328
Fix thread reply big box caused by ::before on table rows
awehttam Mar 8, 2026
2201fa6
Fix thread sender name wrapping in netmail list
awehttam Mar 8, 2026
23edaa0
Use stepped indent capped at 2 levels in netmail thread list
awehttam Mar 8, 2026
48074e4
Fix echomail thread indent: replace flat 2em CSS rule with stepped in…
awehttam Mar 8, 2026
733afc2
Increase thread indent to 0.75rem per level (max 1.5rem at level 2+)
awehttam Mar 8, 2026
b9b26e8
Fix reply template inserting blank line before attribution
awehttam Mar 8, 2026
2060353
Bump service worker cache to v193
awehttam Mar 8, 2026
11fb8f1
Fix BBS menu right-border misalignment with multibyte localized strings
awehttam Mar 9, 2026
c3ebe86
Add BinktermPHP logo SVGs
awehttam Mar 9, 2026
bca2a33
rearrange mypoint vs. claudes
awehttam Mar 9, 2026
27b731c
Show paperclip indicator in netmail list for messages with attachments
awehttam Mar 9, 2026
8541ec0
Download netmail attachments directly without opening a new tab
awehttam Mar 9, 2026
af3c3aa
Drain client OO bytes after ZMODEM upload to prevent BBS prompt pollu…
awehttam Mar 9, 2026
4e970c9
Improve terminal menu rendering and per-client text handling
awehttam Mar 9, 2026
6eae8b6
remove some unnecessary entries from UPGRADING_1.8.6.md since they w…
awehttam Mar 9, 2026
eecb7c7
Add French (fr) locale and expand translation catalog script
awehttam Mar 9, 2026
3532b58
Color file area listing columns in terminal server
awehttam Mar 9, 2026
75914b4
Add terminal markup rendering and page up/down to message reader
awehttam Mar 9, 2026
cc22a7e
Refactor message reader into shared TelnetUtils::runMessageViewer()
awehttam Mar 9, 2026
a79d0fe
Refactor message list browser into shared TelnetUtils::runMessageList()
awehttam Mar 9, 2026
1f2489c
Fix misrouted echomail landing in sysop netmail inbox; preserve undel…
awehttam Mar 9, 2026
2fd8496
Improve terminal markup rendering and message list navigation
awehttam Mar 9, 2026
fd6ff62
Fix garbled text in SyncTERM by removing dim ANSI attribute
awehttam Mar 9, 2026
2ea1413
Add terminal mail-state persistence and netmail ZMODEM attachment dow…
awehttam Mar 9, 2026
659920a
Wire terminal settings into BBS main menu
awehttam Mar 9, 2026
e026f54
Add French terminal settings strings and markup renderer ANSI reset f…
awehttam Mar 9, 2026
ff8351b
Load TerminalSettingsHandler in SSH daemon bootstrap
awehttam Mar 9, 2026
7c40711
Use charset-aware line drawing in terminal frames
awehttam Mar 9, 2026
566c30c
Honor terminal ANSI color setting across shared rendering
awehttam Mar 9, 2026
89a9a36
Force ASCII line framing when ANSI color is disabled
awehttam Mar 9, 2026
c258750
Always show ANSI color sample during terminal detection wizard
awehttam Mar 9, 2026
eb3bac1
Add ASCII fallback step to terminal detection wizard
awehttam Mar 9, 2026
d135c42
Unify file rename/edit and add admin move-to-area
awehttam Mar 9, 2026
227653a
Fix edit/delete button visibility for unowned files
awehttam Mar 9, 2026
d08e5e2
Fix isAdmin/currentUserId and show owner username in file details
awehttam Mar 9, 2026
15fbf7f
Add prev/next navigation to file details modal
awehttam Mar 9, 2026
c789c56
Add H key kludge/header viewer to terminal message reader
awehttam Mar 10, 2026
fe9722d
Add spacing between nav arrows and filename in file details modal
awehttam Mar 10, 2026
c1fae4c
Fix PostgreSQL encoding error when TIC FILE_ID.DIZ contains CP437 cha…
awehttam Mar 10, 2026
31e6320
Update UPGRADING_1.8.6 with TIC CP437 encoding fix
awehttam Mar 10, 2026
4912dab
Surface real exception message in TIC processing error output
awehttam Mar 10, 2026
08e0dcf
Fix TIC data files lost when bundled inside day-of-week archives
awehttam Mar 10, 2026
8029401
Fix bundle extraction for archives with subdirectories; add path guards
awehttam Mar 10, 2026
7abfda0
Add ClamAV documentation, on-demand virus scan button, and CLAMAV_ALL…
awehttam Mar 10, 2026
c7c2fcb
Log virus detection in uploaded files to server log via admin daemon
awehttam Mar 10, 2026
9e95468
Surface virus detection error on file upload with server log entry
awehttam Mar 10, 2026
20143aa
Update UPGRADING_1.8.6 with file area and TIC improvements
awehttam Mar 10, 2026
43ee5ec
Show scan result toast after manual virus scan completes
awehttam Mar 10, 2026
5739777
clamav is a resource hog
awehttam Mar 10, 2026
5f2f83c
Limit file area list height with scrolling, matching echomail reader …
awehttam Mar 10, 2026
8161de4
Rename 'Files' to 'File Areas' in page title, heading, and sidebar
awehttam Mar 10, 2026
5babdfc
Add search filter to file areas sidebar list
awehttam Mar 10, 2026
9f1c1c7
Update UPGRADING_1.8.6 with file areas UI improvements
awehttam Mar 10, 2026
2c1692d
Merge branch 'main' into claudesbbs
awehttam Mar 10, 2026
88847dd
Move Localization section to top of UPGRADING_1.8.6 changes summary
awehttam Mar 10, 2026
3b38d82
Move ASCII terminal bullet to Terminal Server section in UPGRADING_1.8.6
awehttam Mar 10, 2026
ffb9fa0
Add ANSI auto-detection, styled message headers, scroll optimization,…
awehttam Mar 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@ ADMIN_DAEMON_SOCKET=tcp://127.0.0.1:9065
# Telnet Daemon Configuration
# TELNET_BIND_HOST=0.0.0.0
# TELNET_PORT=2323
# TLS is enabled by default on port 8023 with an auto-generated self-signed cert.
# Set TELNET_TLS=false to disable TLS entirely.
# TELNET_TLS=true
# TELNET_TLS_PORT=8023
# TELNET_TLS_CERT=/etc/ssl/certs/your-cert.pem
# TELNET_TLS_KEY=/etc/ssl/private/your-key.pem

# PubTerm Native Door Configuration
# Host and port the PubTerm door connects to via telnet (defaults to BBS localhost telnet port)
# PUBTERM_HOST=127.0.0.1
# PUBTERM_PORT=2323
# Path to telnet binary if not on PATH (Linux)
# PUBTERM_TELNET_BIN=/usr/bin/telnet
# Windows: PubTerm uses PuTTY plink in telnet mode (no escape character trap).
# Install PuTTY: winget install PuTTY.PuTTY
# PUBTERM_PLINK_BIN=C:\Program Files\PuTTY\plink.exe

# Gemini Capsule Server Configuration (optional — only needed if running the daemon)
# GEMINI_BIND_HOST=0.0.0.0
Expand Down Expand Up @@ -87,6 +103,16 @@ FILEAREA_RULE_ACTION_LOG=data/logs/filearea_rules.log
# File action debugging (writes data/logs/file_action_debug.log)
# FILE_ACTION_DEBUG=true

# Echomail message date ordering field used by backend sorting and echomail UI date display.
# received = use date_received (default), written = use date_written
# ECHOMAIL_ORDER_DATE=received

# i18n missing key logging (QA hardening)
# Set to true to log translation keys that are missing from catalogs.
# I18N_LOG_MISSING_KEYS=false
# Optional explicit log file path. If unset, messages go to PHP error_log.
# I18N_MISSING_KEYS_LOG_FILE=data/logs/i18n_missing_keys.log


# DOS Emulator Selection (defaults to DOSBox)
# dosbox = DOSBox (default, reliable, ~180MB RAM, works on Windows and Linux) - RECOMMENDED
Expand Down
25 changes: 25 additions & 0 deletions .github/workflows/i18n-error-keys.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: i18n Coverage Checks

on:
push:
branches:
- '**'
pull_request:

jobs:
check-i18n:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'

- name: i18n error key coverage
run: php scripts/check_i18n_error_keys.php

- name: i18n hardcoded UI strings
run: php scripts/check_i18n_hardcoded_strings.php
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
composer.lock
config/*.json
!config/*.example
config/i18n/overrides/
config/*.json.*
config/taglines.txt
config/welcome.txt
Expand Down Expand Up @@ -28,12 +29,17 @@ backups/*
*~
.env
.env.local
tests/.env.test
bbs_ads/*
!bbs_ads/claudes1.ans

# Windows utility scripts
delnul.cmd
node_modules/
tests/playwright/.auth-state.json
tests/playwright/.csrf-token.json
tests/playwright-report/
test-results/
scripts/dosbox-bridge/package-lock.json

# DOS Door files - only track manifests
Expand Down
74 changes: 73 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ A modern web interface and mailer tool that receives and sends Fidonet message p
- **IMPORTANT**: CLI scripts must include `src/functions.php` after autoload to access global functions like `generateTzutc()`: `require_once __DIR__ . '/../src/functions.php';`
- Scripts should be made executable with `chmod +x` and marked as executable in git with `git update-index --chmod=+x scripts/filename.php`
- templates/ - html templates
- **IMPORTANT**: Template resolution order is `templates/custom/` → `templates/shells/<activeShell>/` → `templates/`. The active shell (`web` or `bbs-menu`) has its own `base.twig` at `templates/shells/web/base.twig` and `templates/shells/bbs-menu/base.twig` which take priority over `templates/base.twig`. When adding nav links or modifying shared layout, you must update **both** `templates/base.twig` AND `templates/shells/web/base.twig` (and `bbs-menu` if applicable).
- public_html/ - the web site files, static assets
- tests/ - test scripts used in debugging and troubleshooting
- vendor/ - 3rd party libraries managed by composer and should not be touched by Claude
- data/ - runtime data (binkp.json, nodelists.json, logs, inbound/outbound packets)
- telnet/ - the telnet BBS server (separate from the web interface)

## Important Notes
- User authentication is simple username and password with long lived cookie
Expand Down Expand Up @@ -127,9 +129,79 @@ return function($db) {
- Avoid duplicating code. Whenever possible centralize methods using a class.
- **Git Workflow**: Do NOT stage or commit changes until explicitly instructed. Changes should be tested first before committing to git.
- When writing out a proposal document state in the preamble that the proposal is a draft, was generated by AI and may not have been reviewed for accuracy.
- **Service Worker Cache**: When making changes to CSS or JavaScript files, increment the CACHE_NAME version in public_html/sw.js (e.g., 'binkcache-v2' to 'binkcache-v3') to force clients to download fresh copies. The service worker handles all static asset caching to bypass aggressive browser caching on mobile devices.
- **Service Worker Cache**: When making changes to CSS or JavaScript files, or when updating i18n language strings in `config/i18n/`, increment the CACHE_NAME version in public_html/sw.js (e.g., 'binkcache-v2' to 'binkcache-v3') to force clients to download fresh copies. The service worker caches static assets and the i18n catalog (`/api/i18n/catalog`) to bypass aggressive browser caching on mobile devices.
- Write phpDoc blocks when possible

## Localization (i18n) Workflow

The project uses key-based localization for both Twig and JavaScript. Translation catalogs live in:
- `config/i18n/<locale>/common.php`
- `config/i18n/<locale>/errors.php`

Current baseline locales are `en` and `es`.

### Core Rules
- Never hardcode new user-facing UI text in templates/JS when adding or changing features.
- Add a translation key first, then use it from Twig/JS.
- Keep `en` and `es` in sync for every new key in normal feature work.
- Prefer stable key names by page/feature area, e.g. `ui.settings.*`, `ui.polls.*`, `errors.polls.*`.
- Do not change existing key names unless required (avoid breaking references).

### Twig Translation
- Use the global Twig function: `t(key, params, namespace)`.
- Default namespace is `common`; pass `'errors'` when needed.
- Example:
```twig
{{ t('ui.settings.title', {}, 'common') }}
{{ t('ui.polls.create.submit', {'cost': poll_cost}, 'common') }}
```

### JavaScript Translation
- Use `window.t(key, params, fallback)` (or a local wrapper like `uiT`).
- Use placeholders in strings and pass params object:
```js
window.t('ui.polls.create.submit', { cost: 25 }, 'Create Poll ({cost} credits)')
```
- `window.i18n` supports lazy namespace loading via:
- `loadI18nNamespaces([...])`
- endpoint: `GET /api/i18n/catalog?ns=common,errors&locale=<locale>`
- JS should always include a fallback string for resilience.

### API Errors and `error_code`
- API responses should use structured errors via `apiError(error_code, message, status, extra)` and return:
- `error_code` (translation key)
- `error` (human fallback)
- Frontend should resolve display text with `window.getApiErrorMessage(payload, fallback)`.
- Do not rely on matching raw error message text in frontend logic.
- For new API errors:
1. Add/choose `errors.*` key in route code.
2. Add that key to `config/i18n/en/errors.php` (and `es/errors.php`).
3. Use `getApiErrorMessage` in UI handling.

### Locale Resolution / Config
- Locale is resolved server-side through `LocaleResolver`/`Translator`.
- Supported locales are exposed to Twig as `supported_locales`.
- Environment settings used by i18n:
- `I18N_DEFAULT_LOCALE`
- `I18N_SUPPORTED_LOCALES` (optional; auto-discovers locale folders if unset)
- `I18N_LOG_MISSING_KEYS`
- `I18N_MISSING_KEYS_LOG_FILE`

### Required Validation After i18n Changes
- Run:
- `php scripts/check_i18n_hardcoded_strings.php`
- `php scripts/check_i18n_error_keys.php`
- Goal:
- no new hardcoded string violations
- no missing `errors.*` catalog keys used by `apiError(...)`

### Practical Checklist for New UI/API Work
1. Add new `ui.*`/`errors.*` keys to `en` and `es`.
2. Replace literals in Twig with `t(...)`.
3. Replace JS literals with `window.t(...)` (or `uiT(...)`) fallbacks.
4. Ensure API errors return `error_code`.
5. Run both i18n check scripts before commit.

## URL Construction
When constructing full URLs for the application (e.g., share links, reset password links, meta tags), **always** use the centralized `Config::getSiteUrl()` method:

Expand Down
9 changes: 9 additions & 0 deletions FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,15 @@ When sending netmail, check the "Crash" option to attempt direct delivery.
4. Run `php cli/binkp_poll.php --domain=<domain>` to poll your uplink
5. Check `data/logs/packets.log` and `data/logs/binkp_poll.log` for errors

### Q: If a packet contains multiple messages and one fails, are other messages affected?
**A:** It depends on the failure type:

- **Single message exception** (e.g. database error, malformed message data): Only that message is skipped. Processing continues normally for all remaining messages in the packet.
- **Undeliverable netmail** (no matching local user found by address or name): The message is dropped with a detailed log entry (from/to/subject/date/MSGID) and processing continues. The original `.pkt` file is also preserved to `data/undeliverable/` for manual inspection.
- **Echomail from an insecure session** (security rejection): Processing stops immediately — the rest of the packet is abandoned and moved to the error directory.

In the first two cases the packet is still considered successfully processed even if individual messages were skipped.

---

## Binkp Server & Polling
Expand Down
Loading