Development¶
Source layout¶
The service is procedural PHP with shared functions loaded by lib/bootstrap.php. UI entry points live at the root and in reports/; JSON endpoints live in api/ and action/. The report engine is an externally supplied WAR. The lone ReportServlet.java is not accompanied by its referenced classes or a Java build manifest.
No Composer/npm/Maven/Gradle manifest, lockfile, automated test suite, test configuration, linter configuration, or CI definition exists in the service directory.
Observed coding standards¶
- Files use
declare(strict_types=1)where modernized and proceduraljrs_*helpers loaded fromlib/bootstrap.php. - Database values use
pg_query_params(); dynamic application table names go throughjrs_table(). - Report keys must pass
jrs_report_key()/jrs_is_valid_report_key(). - HTML output must use
jrs_html()and JSON endpoints set an explicit content type. - Apply service-level and report-level ACL helpers before protected operations.
- Keep report definitions backward-compatible with accepted aliases (
parameters/params,datasource/datasourceName) where existing readers support them. - Treat SQL-backed parameter definitions as trusted code and use read-only report datasource roles.
No formal formatter, PHP style guide, static-analysis baseline, or enforced lint policy was found.
Local setup¶
- Create the application database and apply
database/schema.sql. - Replace the hardcoded secret in
config.php; do not rely on legacyJRS_DB_*variables. - Run Tomcat/Compose and ensure the service can reach
127.0.0.1:9099. - Start PHP:
- Visit
/reports/index.php.
With no resolvable Central DSN, auth code enters local-development mode and grants an administrator identity. Never use that configuration to validate production authorization.
Manual verification¶
There is no automated test command. A proportionate source-backed smoke test is:
php -l config.php
php -l lib/bootstrap.php
php -l reports/execute_report.php
php -l scripts/run_schedule.php
docker compose -f docker/report-server/docker-compose.yml config
Then verify:
- App DB connectivity and all five tables.
- Datasource save and
context.xmlgeneration. - Tomcat startup and JNDI lookup.
- Report publish, JSON/JRXML persistence, HTML render, PDF and XLSX export.
- Central login, service permission, report permission, and anonymous
Publicbehavior. - Manual schedule run, output file, execution history, and email path.
- On Linux, timer creation, symlinks, enablement, execution, and cleanup.
Debugging¶
- PHP/auth/resource/scheduler errors use the PHP error log.
JRS_AUTH_DEBUG=1orJRS_AUTH_LOGIN_TRACE=1enables[jrs-auth]logs.JRS_RESOURCE_SYNC_VERBOSE=1logs existing Central resources.- Schedule runs append to
schedules/logs/schedule-<id>.logand emit CLI output to systemd journal/its configured append target. - Tomcat logs servlet report paths and stack traces.
debug/session.phpreturns a limited auth probe only when debug is enabled.
debug.php exposes a raw session cookie/hash, hardcoded database credential, and user/session records. debug/param_pipeline_php.php reflects request values. Remove or block both in any non-isolated environment.
Useful runtime checks:
systemctl status jrs-schedule-<id>.timer
systemctl cat jrs-schedule-<id>.service
journalctl -u jrs-schedule-<id>.service
docker compose -f docker/report-server/docker-compose.yml logs report-server
Report development¶
Report definitions live in reports/json/*.report.json; JRXML/compiled files live in docker/report-server/reports/. Report keys are normalized to lowercase letters, digits, _, and -.
SQL-backed select parameters use a source beginning with sql: and execute directly against the selected report datasource. The SQL is trusted definition content and is not parameterized. Use a read-only datasource role, review report definitions as code, and do not incorporate user input into those queries.
The viewer forwards non-reserved parameters to Jasper. The servlet source treats repeated values as collections and has an explicit collection override only for p_boro.
Adding an endpoint¶
- Add the PHP entry point under
api/for a public JSON integration route,action/for an existing UI form contract, orreports/for report runtime/management behavior. - Load
lib/bootstrap.php, enforce an explicit request method, and set response content types. - Choose the required gate: Central login, platform admin,
service:jasper_reports, and/orjasper_report:<key>. - Validate and normalize all path/query/form values; use parameterized SQL and safe filesystem path helpers.
- Define stable success and error status codes. Avoid the current legacy pattern of
200withsuccess:falsefor new APIs. - Add focused tests or, until a test harness exists, a repeatable curl smoke test covering success, method rejection, invalid input, missing auth, denied ACL, and dependency failure.
- Update
docs/api.md,docs/openapi.yaml, examples, CLI mapping, and configuration documentation.
Adding a database table or column¶
- Design explicit types, nullability, defaults, checks, foreign keys/delete behavior, and indexes.
- Add an upgrade migration before changing runtime queries.
database/schema.sqlalone cannot upgrade existing tables, and no migration runner currently exists. - Update
database/schema.sqlso fresh installs reach the same final schema. - Use
jrs_table()for application-schema qualification and parameterized queries for values. - Test both a fresh database and every supported prior schema; include backup and rollback instructions for operators.
- Document the model, relationships, indexes, initialization, and compatibility behavior in
docs/database.md.
Change and release process¶
The Git history for this service begins in May 2026. There are no release tags, release manifest, packaged artifact procedure, or version constant. Before a release:
- Review PHP syntax and manual smoke tests.
- Validate schema compatibility, especially scheduler columns.
- Rotate/remove secrets and regenerate Tomcat context.
- Pin and record the WAR/JDBC/container artifacts actually deployed.
- Back up PostgreSQL and filesystem state.
- Record user-visible changes in
docs/changelog.md. - Create a version tag only through the repository's agreed release process.
The 1.0.0 changelog entry is a documentation baseline requested for this repository, not evidence of an existing product release or tag.