Files
huntingclubroster/MAINTENANCE-REPAIRS.md
T

107 lines
5.9 KiB
Markdown

# Maintenance and backup repairs — October 20, 2026
This follow-up addresses the three code findings in
[the production review](PRODUCTION-REVIEW-2026-10-20.md).
No schema migration is needed. Tests use disposable local databases, not the
development or production database. Deployment and production-host acceptance
work in that review still applies.
## Editor replacement
- Removed the CKEditor 24 bundle and its references from all four alert/popover
add/edit forms. Replaced it with locally hosted **SunEditor 3.3.3**.
- Current CKEditor requires a commercial license key or GPL-compatible usage;
neither was established for this project. The review allowed a maintained
replacement. SunEditor uses the MIT license, included verbatim in
`THIRD-PARTY-NOTICES.md`. No commercial key or runtime CDN is required.
- Kept headings, bold, italic, underline, links, lists, font family/size/color,
indentation, alignment, horizontal rules, tables, undo and redo. Upload and
remote media tools are not enabled.
- Added the shared `js/rich-text.js` adapter. Save buttons stay disabled until
initialization completes. Initialization failure or timeout produces a visible
message. Saving copies editor HTML into the original form field; an empty
editor remains an empty optional field.
- Added versioned JavaScript/CSS, archive integrity and individual asset hashes
to `browser-dependencies.json`. Source checks verify the installed asset hashes
and removal of the old bundle. The release builder includes the replacement,
its license and dependency metadata. `Base::VERSION` changed to `1.01` to refresh
cached form scripts.
- Browser coverage exercises actual add/save/reopen/edit flows for both forms,
including legacy table markup, fonts, lists, links and text formatting; formatted
paste; filtering scripts, event attributes and unsafe links; failed asset
loading; and the existing content security policy.
- SunEditor 3 targets modern browsers (Chrome/Edge 119+, Firefox 125+,
Safari 17.2+). Unusual legacy HTML may be normalized by its content model;
arbitrary HTML is not promised to round-trip byte for byte. Existing server
output protections remain necessary; client filtering is not a server trust
boundary.
Upstream sources:
[SunEditor release](https://github.com/JiHong88/suneditor/releases/tag/v3.3.3),
[installation and license](https://github.com/JiHong88/suneditor),
[CKEditor licensing](https://ckeditor.com/docs/ckeditor5/latest/getting-started/installation/self-hosted/quick-start.html).
## Server-side maintenance validation
- Added `classes/MaintenanceValidation.php`, shared by create and edit handlers
in `Alerts.php` and `Popovers.php`.
- Alert titles and popover names/titles are required and limited to 100 Unicode
characters. Optional popover placeholders allow 100 characters. Optional alert
messages and popover HTML allow 1,000 characters, matching existing columns.
- Rejects malformed text, null bytes, and control characters in single-line
fields. Required fields reject Unicode whitespace-only values. Limits count
characters rather than UTF-8 bytes.
- Alert dates and times must be present and use exact `YYYY-MM-DD` and `HH:MM`
formats. Rejects invalid calendar dates, impossible times, nonexistent local
daylight-saving times, years outside the database range, and expiration before
the start. Equal start/expiration remains allowed.
- Invalid requests return HTTP 422 with a specific error before any write.
Title-only alerts and popovers without optional body text remain supported.
- Alert/popover lookup, update and deletion IDs now use strict integer validation.
The popover uniqueness lookup still allows its create form's zero exclusion ID.
- Added direct HTTP tests that verify both rejection and unchanged table
fingerprints. Fixed the isolated test fixture connection to use UTF-8 so
Unicode assertions read the stored text correctly.
## Backup memory usage and failure cleanup
- Added `classes/BackupValidation.php`. Completion validation reads at most the
final **8 KiB** of the dump instead of loading the whole file into PHP memory.
- Requires the completion comment at the end, rejects missing/truncated dumps,
and accepts Windows or Unix line endings. Existing process exit-status,
streaming checksum, atomic completion and protected output handling remain.
- Moved temporary output/credential creation into the cleanup-protected block
and handles credential-file creation failure safely.
- Added a 64 MiB file test under a **16 MiB PHP memory limit**, including checksum
generation and measured peak-memory assertion. Additional tests cover missing,
tiny and incomplete files and a completion comment before unfinished data.
- Deployment tests exercise a real scratch-database dump and a failed dump
process, checking nonzero failure status and removal of temporary credentials,
partial output and success metadata. Release tests verify the new files.
## Verification
The full regression entry point is `tests/run.py`; it now includes the new
maintenance HTTP and bounded-memory backup suites. It also runs source validation,
authentication, authorization, club/ledger, concurrency, browser and deployment
checks. The complete run passed **374 checks plus five concurrency scenarios**:
| Suite | Passed |
| --- | ---: |
| Authentication service/templates | 49 |
| Maintenance unit checks | 52 |
| Authentication HTTP | 27 |
| Project HTTP | 99 |
| New maintenance HTTP | 47 |
| Production security and ledger | 42 |
| Restricted database privileges | 5 |
| Browser flows | 28 |
| Backup validation | 9 |
| Deployment tools/release packaging | 16 |
Source validation also passed for 44 PHP files, 56 JavaScript files and 39 XSL
stylesheets, including jQuery and SunEditor integrity checks. The isolated
loopback database server was stopped after the disposable databases were removed.
No development database records, real passwords, production services or email
recipients were changed by this work.