Skip to content
Open

1.8.7 #174

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
207 commits
Select commit Hold shift + click to select a range
c64dc7a
Fix false PETSCII detection in imported messages
awehttam Mar 14, 2026
845a2fd
Show C64 badge in message list for PETSCII messages
awehttam Mar 14, 2026
2501710
Bump service worker cache version for echomail/netmail JS changes
awehttam Mar 14, 2026
965d5ea
Add art_format to all echomail list queries
awehttam Mar 14, 2026
f0932eb
Add message artwork encoding editor for echomail/netmail
awehttam Mar 14, 2026
f4d7f9a
Add advanced message search with date range and trigram indexes
awehttam Mar 14, 2026
9246653
Add database stats page, optional daemon status, and index cleanup
awehttam Mar 14, 2026
e6f0f4d
Add i18n catalog stats tab to database statistics page
awehttam Mar 14, 2026
2bfe7a5
Add 118 missing French translation keys
awehttam Mar 14, 2026
3b32e96
Fix table-warning/danger/secondary contrast on dark themes
awehttam Mar 14, 2026
627837d
Fix striped table-warning rows on dark themes
awehttam Mar 14, 2026
c5c7489
Add FAQ entry explaining sequential scan behaviour in database stats
awehttam Mar 14, 2026
f49baf5
Add configurable file upload/download credits
awehttam Mar 14, 2026
0180d5c
Fix partial binkp frame writes
awehttam Mar 14, 2026
5393c48
Improve binkp handshake diagnostics and socket tuning
awehttam Mar 14, 2026
0f7c7c9
Fix index sizes query using wrong pg_stat_user_indexes column names
awehttam Mar 14, 2026
4c01702
Truncate long index/table names in db stats with tooltip for full name
awehttam Mar 14, 2026
f96d5ff
Add partial index on mrc_outbound to eliminate seq scans
awehttam Mar 14, 2026
36ddd8d
Fix seq scans on users, shared_messages, saved_messages, and chat_mes…
awehttam Mar 14, 2026
48d4beb
Update UPGRADING_1.8.7 with database performance improvements section
awehttam Mar 14, 2026
883124a
Add nodelist map with grouped markers, zone colour coding, and geocod…
awehttam Mar 14, 2026
e69bb8c
Compact nodelist stats box and document nodelist map in upgrade guide
awehttam Mar 14, 2026
7e40ca9
Apply BBS directory dark map styling to nodelist map
awehttam Mar 14, 2026
5838a92
Add geocoding section to CLI.md
awehttam Mar 14, 2026
bb06fa0
Rename geocode cache table and backfill script for shared use
awehttam Mar 14, 2026
cac75de
Switch nodelist map colour coding from zone to network domain
awehttam Mar 14, 2026
d98ee1f
Fix nodelist map domain colours — include domain in map-data API resp…
awehttam Mar 14, 2026
8fac3cd
Move kludge lines toggle to icon button in message reader header
awehttam Mar 14, 2026
9b30525
Add print button and move kludge toggle to message reader header
awehttam Mar 14, 2026
11285ce
Update UPGRADING_1.8.7 with print button and kludge toggle details
awehttam Mar 14, 2026
3f138a5
Update downlink proposal: resolve open questions
awehttam Mar 15, 2026
2929f82
Add Gemini file area browsing and download support
awehttam Mar 15, 2026
4ebca5c
Update UPGRADING_1.8.7 with Gemini file areas section
awehttam Mar 15, 2026
1ba4d83
Update FREQ proposal: resolve open questions, add outbound status tra…
awehttam Mar 15, 2026
1961642
Implement FREQ support: inbound M_GET fulfillment, netmail FREQ inter…
awehttam Mar 15, 2026
ed578dd
Add file area capability badges, nodelist flag filter, and ALLFILES F…
awehttam Mar 15, 2026
fa59393
Fix FREQ response delivery: stable staging and correct routing address
awehttam Mar 15, 2026
570acbc
Deliver FREQ responses via crashmail with freq_outbound pick-up fallback
awehttam Mar 15, 2026
f0f01bb
Fix whitespace in FREQ pickup notification and add freq_pickup.php sc…
awehttam Mar 15, 2026
ee73c9a
Add per-node hold directory delivery for FREQ FILE_ATTACH responses
awehttam Mar 15, 2026
8d724f4
Use closest network AKA when connecting to non-uplink nodes
awehttam Mar 15, 2026
f9bfc1a
Update docs for FREQ delivery, freq_pickup script, and nodelist enhan…
awehttam Mar 15, 2026
7f275ad
Address ALLFILES FREQ to FileFix instead of sysop name
awehttam Mar 15, 2026
2cb023b
Add service name picker to ALLFILES FREQ modal; fix crashmail attachm…
awehttam Mar 15, 2026
c068869
Add filename picker to FREQ modal with common names and free-text option
awehttam Mar 15, 2026
cf09963
Rename 'Request File List (ALLFILES)' button to 'Request File'
awehttam Mar 15, 2026
b681f3c
Add dark Leaflet map to node view page
awehttam Mar 15, 2026
846a560
Fix JS syntax error in node map popup — use json_encode for values
awehttam Mar 15, 2026
9704e5f
Link FTN node addresses to nodelist view page
awehttam Mar 15, 2026
81e05e9
Fix replace_existing blocked by duplicate hash check on same filename
awehttam Mar 15, 2026
8700802
Update UPGRADING_1.8.7 with recent changes
awehttam Mar 15, 2026
56c7426
Fix PETSCII heuristic false positives on text messages with extended …
awehttam Mar 15, 2026
07b65a5
Fix TOC anchor links not rendering in MarkdownRenderer
awehttam Mar 15, 2026
5b27b7c
Trim redundant bullet points from UPGRADING_1.8.7 summary
awehttam Mar 15, 2026
6623dbf
Hide Request File button on nodelist node view page
awehttam Mar 15, 2026
e1da586
Comment out Request File button on nodelist node view page
awehttam Mar 15, 2026
ac7a4a2
Remove FREQ request modal mentions from UPGRADING_1.8.7
awehttam Mar 15, 2026
5fb4ffc
Comment out Request File button on node view page pending .req implem…
awehttam Mar 15, 2026
1013a6e
Gate FREQ UI and fix telnet TLS startup
awehttam Mar 15, 2026
ddf6a9b
Add outbound binkp FREQ support (M_GET) and crashmail option in file …
awehttam Mar 15, 2026
e43f49e
Add tooltip descriptions to nodelist flags on node view page
awehttam Mar 15, 2026
1b09ca9
Add flag descriptions to nodelist flag filter dropdown
awehttam Mar 15, 2026
e1c1024
Add missing flag descriptions: TRACE, V32T, VFC, XW, XX
awehttam Mar 15, 2026
d5cafea
Crashmail logging, packet preservation, FREQ delay and encoding fixes
awehttam Mar 15, 2026
f44c904
Format ALLFILES.TXT columns dynamically and wrap long descriptions
awehttam Mar 15, 2026
555b256
Outbound FREQ fixes, crashmail logging, message reader header, UPGRAD…
awehttam Mar 15, 2026
b552097
Fix anonymous binkp sessions to non-uplink nodes
awehttam Mar 15, 2026
f35f0c7
Echomail reader: end-of-echo prompt and transparent pagination
awehttam Mar 16, 2026
831e6eb
Update UPGRADING_1.8.7 with echomail reader navigation changes
awehttam Mar 16, 2026
f07e718
Add Bark-style .req file FREQ support (send and receive)
awehttam Mar 16, 2026
a0aeda9
FREQ enhancements, file area subfolders, netmail attachment improvements
awehttam Mar 16, 2026
821ee3d
Fix fullscreen modal gap, markdown underscore italics, FREQ compose t…
awehttam Mar 16, 2026
f1bdf45
Fix end-of-echo next unread detection ignoring @domain suffix
awehttam Mar 16, 2026
48eb830
Fix end-of-echo navigation passing bare tag instead of TAG@domain
awehttam Mar 16, 2026
1db5c02
Fix echomail end-of-echo navigation and improve pagination display
awehttam Mar 16, 2026
cd917ec
Disable/re-enable toolbar buttons on end-of-echo prompt
awehttam Mar 16, 2026
339aa25
Add cross-page next/previous navigation to netmail reader
awehttam Mar 16, 2026
c0f669a
Add base padding to message-header-full
awehttam Mar 16, 2026
d5ff31e
Add inline file preview modal for images, video, audio, and text
awehttam Mar 16, 2026
8f13543
Add ISO-backed file areas with subfolder navigation and preview import
awehttam Mar 16, 2026
dc66fc0
Fix fuseiso fd inheritance and stale mount handling
awehttam Mar 16, 2026
c321163
Resolve iso_mounts base path to remove ../ components
awehttam Mar 16, 2026
1faf196
Resolve ISO file path to absolute before mounting
awehttam Mar 16, 2026
595d6cc
Fix undefined \$storage in sendLocalSysopMessage
awehttam Mar 16, 2026
28dcb84
Remove ISO auto-mount; sysop configures mount point manually
awehttam Mar 16, 2026
29b4bf5
Show subfolder short_description in Recent Uploads list
awehttam Mar 16, 2026
72e1253
Fix ISO subfolder navigation for multi-level directory trees
awehttam Mar 16, 2026
b452116
Show subfolders at all depth levels, not just root
awehttam Mar 16, 2026
4c80b9f
Add support for 00_INDEX.TXT (Simtel-style) catalogue format
awehttam Mar 16, 2026
e906685
Fix ISO import skip to allow selecting child dirs without parent
awehttam Mar 16, 2026
6045077
Fix ISO preview modal leaving backdrop after close
awehttam Mar 16, 2026
1b8dcac
Fall through to next catalogue if parsing yields no entries
awehttam Mar 16, 2026
740363d
Fix ISO file areas not showing folders or correct stats
awehttam Mar 16, 2026
8adf206
Fix unreadable breadcrumb in dark/cyberpunk themes
awehttam Mar 16, 2026
18699a1
Show file area tag in breadcrumb instead of generic 'Files'
awehttam Mar 16, 2026
32031cf
Add global file search across all file areas
awehttam Mar 16, 2026
520e12e
Update UPGRADING_1.8.7 for ISO catalogue formats and file search
awehttam Mar 16, 2026
db3b4a4
Remember last-visited page per echo area and netmail inbox
awehttam Mar 16, 2026
bf7be35
Fix netmail sort options being ignored
awehttam Mar 16, 2026
da36815
Show arrow beside active sort option in echomail and netmail dropdowns
awehttam Mar 16, 2026
bf560b7
Fix empty message list when restored page exceeds area's page count
awehttam Mar 16, 2026
5086066
Add 250 and 500 options to messages per page setting
awehttam Mar 16, 2026
6d96738
Fix ZIP file preview not showing FILE_ID.DIZ content
awehttam Mar 16, 2026
7365bc2
Add download button to ZIP FILE_ID.DIZ preview
awehttam Mar 16, 2026
9c0fb43
Add post_file.php CLI script to upload files to a file area
awehttam Mar 16, 2026
29d6312
Document post_file.php in CLI.md
awehttam Mar 16, 2026
c5acad1
Allow getFileAreaByTag and post_file.php to work without a domain
awehttam Mar 16, 2026
7e0804a
Fix FILE_ID.DIZ lookup to find root-level entry and respect existing …
awehttam Mar 16, 2026
2c15eb3
Add access control roles and permission flags proposal
awehttam Mar 16, 2026
cc41d5a
Set autofocus on username field on login page
awehttam Mar 16, 2026
32c1bd3
Fix crashmail AKA selection for multi-network uplinks
awehttam Mar 16, 2026
5b22312
Echomail info bar, subscription toggle, theme accordion/list-group fixes
awehttam Mar 16, 2026
c126b35
Add sortable columns and subscriber count to echo area management table
awehttam Mar 17, 2026
765a256
Add offline-signed Ed25519 licensing system
awehttam Mar 17, 2026
c45fede
Move registered badge inline with Powered by line in footer
awehttam Mar 17, 2026
76f44a7
Add ANSI/PRG file preview, shared file preview, and C64 rendering acc…
awehttam Mar 17, 2026
114c7e0
Add .seq PETSCII stream preview, fix PETSCII bg color, remove low-fid…
awehttam Mar 17, 2026
a41dc6a
Add opt-in page position memory setting (default off)
awehttam Mar 17, 2026
c47c11e
Add D64 preview, fix BinkP spaced filenames, sanitize upload filenames
awehttam Mar 17, 2026
36790ca
Add SEQ-to-PRG API wrapper and inline C64 emulator for .seq files
awehttam Mar 17, 2026
d61dbc3
Fix Run on C64 button to always load emulator inline
awehttam Mar 17, 2026
d0c629f
Strip trailing CR/LF from SEQ data in PRG wrapper
awehttam Mar 17, 2026
c2b3b7a
Fix service worker not activating on update
awehttam Mar 17, 2026
17e29e1
Remove bundled jsc64 game ROMs
awehttam Mar 17, 2026
16a5292
Add C64 WebDoor engine, fix jsc64 joystick, add SEQ preview and inlin…
awehttam Mar 17, 2026
7ba4db3
Fix telnet/SSH file area issues: virtual folders, pagination, ISO ZMO…
awehttam Mar 17, 2026
8d72c14
Add premium features: branding controls, message templates, economy v…
awehttam Mar 17, 2026
2c03e43
Clarify license installation options in REGISTER.md
awehttam Mar 17, 2026
c6859d8
Fix file preview for unauthenticated shared file viewers
awehttam Mar 17, 2026
a9446e3
Fix shared file preview for petscii/prgs endpoint and unauthenticated…
awehttam Mar 17, 2026
327afae
Use actual network domain name in shared file page about text
awehttam Mar 17, 2026
86db7ca
Pass share params through c64emu iframe URL so unauthenticated users …
awehttam Mar 17, 2026
7eed215
Fix referral analytics: use correct table name user_transactions
awehttam Mar 17, 2026
a4111a9
Group Activity Statistics, Economy Viewer, Referral Analytics under A…
awehttam Mar 17, 2026
2813da9
Fix unreadable locked Analytics menu items with explicit gray color
awehttam Mar 17, 2026
ce42b7c
Add 'Registered Feature' tooltip to locked Analytics menu items
awehttam Mar 17, 2026
8197809
Reorganize admin menu: Community submenu, Auto Feed into Area Management
awehttam Mar 17, 2026
53fdac0
Rename admin Chat submenu label from 'Local Chat' to 'Chat'
awehttam Mar 17, 2026
58526a5
Replace 'How to Get a License' box with 'Why Register?' motivations
awehttam Mar 17, 2026
f368ab6
Rephrase perpetual license bullet to avoid 'purchase'
awehttam Mar 17, 2026
8cd09a7
Add 403 error template, premium features docs, and i18n keys
awehttam Mar 17, 2026
9b124de
Fix SW update detection and add premium features: splash pages, netma…
awehttam Mar 17, 2026
a38b242
Add echomail digest: per-user periodic email summary of subscribed ec…
awehttam Mar 17, 2026
b94fa24
Add Register BinktermPHP link to Admin Help menu for unlicensed installs
awehttam Mar 17, 2026
fc3f146
Fix echomail digest: echoareas has description not name
awehttam Mar 17, 2026
de38bc3
Echomail digest: use frequency window for lookback instead of fixed cap
awehttam Mar 17, 2026
1fef583
Update README for 1.8.7 features: registration, file areas, digest, FREQ
awehttam Mar 17, 2026
4bfc45b
Fix echomail digest URL and garbled UTF-8 in email subjects
awehttam Mar 17, 2026
6233bb5
Fix echomail digest URLs: include domain in echoarea slug (TAG@domain)
awehttam Mar 17, 2026
8fffa2c
Add --resend flag to send_echomail_digest: bypass frequency check wit…
awehttam Mar 17, 2026
17d0523
Fix --resend: use frequency window as lookback, not last_sent
awehttam Mar 17, 2026
c490e73
Registration: include BBS name in email subject; fix admin register p…
awehttam Mar 18, 2026
e9f34e7
Fix REGISTER.md: use brackets instead of escaped angle brackets for s…
awehttam Mar 18, 2026
50aa1c0
Fix locked nav/dashboard items: show hover tooltip and correct cursor
awehttam Mar 18, 2026
dd6560c
Call registration.update() on every page load for automatic SW refresh
awehttam Mar 18, 2026
5953615
Add FileAreaComments proposal; update PremiumFeatures
awehttam Mar 18, 2026
678ff3e
Add file area comments, ZIP browser, RIP preview, and legacy ZIP fall…
awehttam Mar 18, 2026
7a8c169
Show download button on all ZIP entries, not just non-previewable ones
awehttam Mar 18, 2026
5bb5bde
Add LovlyNet subscription admin page; update docs and release post
awehttam Mar 18, 2026
3e7b12e
Remove 1.8.7post.txt from git tracking
awehttam Mar 18, 2026
72bbbda
Fix ZIP browser: arrow nav, legacy compression, modal scroll for comm…
awehttam Mar 18, 2026
c234ebe
Fix file comment threading: include full reply chain, add @domain to …
awehttam Mar 18, 2026
57af79a
Add heuristic text detection for unknown file extensions
awehttam Mar 18, 2026
2c6eeaf
Add markdown rendering and left-align text previews; bundle marked.js
awehttam Mar 18, 2026
36275d7
Use MarkdownRenderer for .md file preview instead of marked.js
awehttam Mar 18, 2026
403237b
Fix FILEREF kludge missing from outbound echomail; improve comment ma…
awehttam Mar 18, 2026
89db356
Fix file comment badges not showing for FTN-received comments
awehttam Mar 18, 2026
5d21a28
Improve file comment banner visibility in echomail reader
awehttam Mar 18, 2026
d583308
Remove MOD tracker player, fix TIC password field, bump SW cache
awehttam Mar 18, 2026
7877717
Add network filter to echolist; update UPGRADING_1.8.7
awehttam Mar 18, 2026
2afa186
Add public file areas feature (registered)
awehttam Mar 18, 2026
f7e69fa
Add missing i18n keys for not_found error page
awehttam Mar 18, 2026
fb0788a
Route binkp_poll result output through logger
awehttam Mar 18, 2026
3a6a165
Add log search to binkp status page; fix poll 30s wait
awehttam Mar 18, 2026
9b75ecd
Add kept packets viewer (registered) and packet inspector
awehttam Mar 18, 2026
116d0cd
Show kept packets tab to all users with blur/lock when unlicensed
awehttam Mar 18, 2026
dbdd005
Fix FTS-0001 packet header parsing: password is 8 bytes not 10
awehttam Mar 18, 2026
3bb53e7
Fix kept packets From/To showing net:node instead of zone:net/node
awehttam Mar 18, 2026
ba1f068
Fix FTS-0001 packet product code and node/0 address display
awehttam Mar 18, 2026
a569404
Fix file preview and emulator handling
awehttam Mar 18, 2026
2d3221f
Stop MOD playback when navigating file previews
awehttam Mar 18, 2026
c7c3466
Add LovlyNet request composer help
awehttam Mar 18, 2026
952809d
Update LovlyNet setup guidance and preview cleanup
awehttam Mar 18, 2026
18b430a
Improve LovlyNet request tracking UI
awehttam Mar 18, 2026
b2b5607
Show file area times in user timezone
awehttam Mar 18, 2026
87e6b0f
Add LovlyNet AREAFIX rescan requests
awehttam Mar 18, 2026
bee7898
Improve LovlyNet area sync integration
awehttam Mar 18, 2026
386f433
Sync LovlyNet subscribed areas during setup
awehttam Mar 18, 2026
ce8d9cc
Adjust LovlyNet file area upload defaults
awehttam Mar 18, 2026
e3ddbaf
Add file area network filters
awehttam Mar 19, 2026
178df6c
* Add LSC documents
awehttam Mar 19, 2026
16a261a
Show file share access stats in dialog
awehttam Mar 19, 2026
0a71d98
Add sharing admin page and RIPtermJS previews
awehttam Mar 19, 2026
067b6a2
Add QWK/QWKE offline mail support
awehttam Mar 19, 2026
0fb74e4
Fix QWK reply threading and netmail address resolution; add per-downl…
awehttam Mar 19, 2026
cecfab6
Add REP upload deduplication via per-message content hashes
awehttam Mar 19, 2026
0599681
Update kept packets sorting and downloads
awehttam Mar 19, 2026
c075686
Remove inbound art auto-detection notes
awehttam Mar 19, 2026
2cafed3
Fix RIP previews and improve file uploads
awehttam Mar 19, 2026
602ce08
Update TIC passwords and BinkP debug logging
awehttam Mar 19, 2026
a97c338
Add file notifications and restore RiptermJS previews
awehttam Mar 19, 2026
7e08b6c
Fix QWK download i18n string
awehttam Mar 19, 2026
9045cd3
Trim file comments before tearline
awehttam Mar 19, 2026
6318231
Document rehatch script and gate QWK uploads
awehttam Mar 19, 2026
2353212
Add fail2ban config for telnet ESC challenge
awehttam Mar 19, 2026
64262e4
Plan guest access in access control proposal
awehttam Mar 19, 2026
e6a5448
Track nodelist views and plan ad library
awehttam Mar 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .env.docker.example
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ DOSDOOR_WS_PORT=6001
# Credits System
CREDITS_ENABLED=true

# Experimental FREQ UI controls
ENABLE_FREQ_EXPERIMENTAL=false

# DOS Door Configuration
DOSDOOR_DEBUG_KEEP_FILES=false
DOSDOOR_WS_BIND_HOST=0.0.0.0
Expand Down
16 changes: 16 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ SMTP_ENABLED=true
# This setting is used by the 'Terminal' web door.
TERMINAL_ENABLED=false

# Experimental FREQ UI controls.
# false = hide file-area FREQ controls and nodelist file-request actions
# true = expose file-area FREQ controls and sysop-only nodelist file requests
ENABLE_FREQ_EXPERIMENTAL=false

# The first host listed will be this host, and could be your BBS or other favourite system
TERMINAL_HOST=your.ssh.server.com
TERMINAL_PORT=22
Expand All @@ -89,6 +94,11 @@ PERF_LOG_SLOW_MS=500
# Use {archive} and {dest} placeholders.
# ARCMAIL_EXTRACTORS=["7z x -y -o{dest} {archive}","unzip -o {archive} -d {dest}"]

# BinkP socket tuning
# Disable Nagle's algorithm by default to reduce latency for small handshake/control frames.
# Set to false only if you need to troubleshoot interoperability with a specific peer/network stack.
# BINKP_TCP_NODELAY=true


# PID File locations (defaults to data/run)
# ADMIN_DAEMON_PID_FILE=data/run/admin_daemon.pid
Expand Down Expand Up @@ -117,6 +127,12 @@ FILEAREA_RULE_ACTION_LOG=data/logs/filearea_rules.log
# received = use date_received (default), written = use date_written
# ECHOMAIL_ORDER_DATE=received

# Licensing
# Path to the license file (default: data/license.json)
# LICENSE_FILE=data/license.json
# Log invalid license states to PHP error_log (useful for troubleshooting)
# LICENSE_LOG_INVALID=false

# i18n missing key logging (QA hardening)
# Set to true to log translation keys that are missing from catalogs.
# I18N_LOG_MISSING_KEYS=false
Expand Down
8 changes: 8 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,26 @@ A modern web interface and mailer tool that receives and sends Fidonet message p
- data/ - runtime data (binkp.json, nodelists.json, logs, inbound/outbound packets)
- telnet/ - the telnet BBS server (separate from the web interface)

## Credits

- **CREDITS.md must be kept up to date**: When merging commits from a new contributor, add them to the Contributors table. When adding a new vendor library via composer, add it to the Third-Party Libraries section with its license and authors.

## Important Notes
- User authentication is simple username and password with long lived cookie
- Both usernames and Real Names are considered unique. Two users cannot have the same username or real name
- The web interface should use ajax requests by api for queries
- This is for FTN style networks and forums
- Always write out schema changes. A database will need to be created from scratch and schema/migrations are how it needs to be done. Migration scripts follow the naming convention v<VERSION>_<description>.sql, eg: v1.7.5_description.sql
- When adding features to netmail and echomail, keep in mind feature parity. Ask for clarification about whether a feature is appropriate to both
- **Premium features**: When implementing a feature that requires a valid license (`License::isValid()` or `License::hasFeature()`), update the "Currently Implemented Premium Features" table in `docs/proposals/PremiumFeatures.md` and remove it from the future ideas list if it was listed there.
- Leave the vendor directory alone. It's managed by composer only
- **Composer Dependencies**: When adding a new required package to composer.json, the UPGRADING_x.x.x.md document for that version MUST include instructions to run `composer install` before `php scripts/setup.php`. Without this, the upgrade will fail because `vendor/autoload.php` is loaded before setup.php runs.
- **Upgrade docs TOC**: When creating or maintaining an `UPGRADING_x.y.z.md` document, always add or update its table of contents so the headings in that file remain navigable and in sync with the document.
- When updating style.css, also update the theme stylesheets: amber.css, dark.css, greenterm.css, and cyberpunk.css
- Database migrations are handled through scripts/setup.php. setup.php will also call upgrade.php which handles other upgrade related tasks.
- Migrations can be SQL or PHP. Use the naming convention vX.Y.Z_description (e.g., v1.9.1.6_migrate_file_area_dirs.sql or .php).
- **Migration version numbers**: Before creating a new migration, always check the highest existing version in `database/migrations/` (e.g., `ls database/migrations/ | sort -V | tail -5`). The new migration must be one increment higher than the highest version found — do NOT guess or use a version from a different branch of the version tree. For example, if the latest is `v1.11.0.5_*`, the next is `v1.11.0.6_*`, not `v1.10.19_*`.
- **No duplicate indexes**: Do NOT create an explicit `CREATE INDEX` on a column that already has a `UNIQUE` constraint — PostgreSQL automatically creates a unique index for every `UNIQUE` constraint, which serves lookups identically to a plain index. Adding a second index on the same column wastes disk space and doubles write overhead with no benefit.
- setup.php must be called when upgrading - this is to ensure certain things like file permissions are correct.

### PHP Migration Patterns
Expand Down Expand Up @@ -131,6 +138,7 @@ return function($db) {
- **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, 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.
- **Timezone Display**: Dates and times are generally stored as UTC in the database. When presenting them to users, translate them to the user's own timezone unless there is a specific reason to show raw UTC.
- Write phpDoc blocks when possible

## Localization (i18n) Workflow
Expand Down
42 changes: 42 additions & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Credits

## Project Author

**Matthew Asham** — creator and primary developer of BinktermPHP.

## Contributors

| Contributor | Contribution |
|-------------|-------------|
| Agent 57951 | QWK/QWKE offline mail support |
| Errol Casey | Extensive testing |

## Third-Party Libraries

### pecee/simple-router
- **License:** MIT
- **Author:** Simon Sessingø
- PHP router library used for all web and API routing.

### twig/twig
- **License:** BSD 3-Clause
- **Authors:** Fabien Potencier, Twig Team, Armin Ronacher
- Template engine used for all HTML rendering.

### phpmailer/phpmailer
- **License:** LGPL 2.1
- **Authors:** Marcus Bointon, Jim Jagielski, Andy Prevost, Brent R. Matzelle
- Email library used for password reset and notification emails.

### phpunit/phpunit *(dev)*
- **License:** BSD 3-Clause
- **Author:** Sebastian Bergmann
- Unit testing framework.

## AI Tooling

BinktermPHP was developed with the assistance of AI language models. We gratefully acknowledge:

- **Anthropic** — Claude (claude.ai / Claude Code)
- **OpenAI** — ChatGPT / GPT-4
- **Google** — Gemini
65 changes: 65 additions & 0 deletions FAQ.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,45 @@
# BinktermPHP Frequently Asked Questions

## Troubleshooting

### Q: The page looks broken after an upgrade — missing features, broken menus, or "loadI18nNamespaces is not defined" errors

**A:** This is a stale service worker cache issue. The old service worker is still serving cached JavaScript and CSS from before the upgrade. You need to unregister the service worker so the browser fetches fresh files.

**Desktop browsers (Chrome / Edge)**

1. Open DevTools — press `F12` or right-click → Inspect
2. Go to **Application** → **Service Workers**
3. Click **Unregister** next to the BinktermPHP service worker
4. Reload the page (`F5`)

**Desktop browsers (Firefox)**

1. Open `about:debugging#/runtime/this-firefox` in the address bar
2. Find the BinktermPHP worker and click **Unregister**
3. Reload the page

**Desktop — quick alternative (all browsers)**

A hard refresh bypasses the cache without unregistering the service worker:
- Windows/Linux: `Ctrl + Shift + R`
- Mac: `Cmd + Shift + R`

**Mobile (Chrome on Android)**

1. Open Chrome's menu (three dots) → **Settings** → **Privacy and security** → **Clear browsing data**
2. Select **Cached images and files** and **Cookies and site data** for the BinktermPHP site
3. Tap **Clear data**, then reload

**Mobile (Safari on iOS)**

1. Go to **Settings** → **Safari** → **Clear History and Website Data**
2. Reload the BinktermPHP site

**Note:** After clearing, you will be logged out and will need to sign in again. This is normal.

---

## Support

### Q: Where can I get support?
Expand Down Expand Up @@ -436,6 +476,31 @@ Public nodes can also poll as a fallback, though the hub will deliver mail direc

---

## Database

### Q: The database stats page shows high sequential scan counts on some tables. Is this a problem?
**A:** Not necessarily. PostgreSQL uses sequential scans when they are more efficient than index scans, which is often the case for small tables or queries where a large fraction of rows would be returned. Here are the common cases you may see in BinktermPHP:

**Small tables (users_meta, user_settings, mrc_state)**
For tables with only a few hundred or thousand rows, PostgreSQL's query planner will almost always prefer a sequential scan — the overhead of walking an index is greater than simply reading the table directly. High seq scan counts here are expected and correct behaviour, not an indexing gap.

**High-frequency daemon tables (mrc_outbound, mrc_state)**
The MRC daemon polls these tables continuously (multiple times per second). Because these tables are very small, every poll results in a sequential scan. The counts look alarming but reflect normal operation.

**OR-condition queries (chat_messages, shared_messages)**
Queries that filter on `col_a = ? OR col_b = ?` cannot use a single B-tree index to satisfy both conditions simultaneously. PostgreSQL must either do a seq scan or merge two separate index scans (bitmap OR). For moderate table sizes or if the planner estimates a large result set, it will choose a seq scan even when indexes exist on both columns individually. This is a structural query pattern — adding more indexes will not change the planner's decision.

**When to investigate further**
A high seq scan ratio is worth investigating when:
- The table is large (tens of thousands of rows or more)
- The query is selecting a small, specific subset of rows (highly selective filter)
- You can see a long-running or slow query in the Query Performance tab that targets that table
- `pg_stat_user_tables.seq_tup_read` is very large relative to `idx_tup_fetch`

In those cases, review the actual queries and consider adding a targeted index. For the tables listed above, no additional indexing is needed.

---

## WebDoors

### Q: How do I add a connection to my text-based BBS?
Expand Down
Loading
Loading