# Technical documentation — quantivia

Evidence date: 2026-10-05. Source: `git@bitbucket.org:overdrive/quantivia.git`, `master` at `c567977` (2019-05-21, "#87 Lines to all dashboard tables").

Credential values, password hashes, the Excel protection password, the mcrypt initialisation vector, and debug IP addresses that appear in source are omitted. Their presence is noted.

`development` (`ba5f6c5`, 2019-08-07) was not checked out.

## Architecture

Monolithic PHP application. One tree serves:

1. eGroupWare 1.8 as the account, group, session, and companion-app platform.
2. Quantivia as a SmartAdmin PHP application under `quantivia/`, using its own MySQL database and the eGroupWare session cookie.
3. Optional Windows worker launchers under `QFD/`.
4. AWS CodeDeploy hooks that do not match the Windows paths in the Quantivia settings file.

Request path for Quantivia:

```text
login.php or loginextra.php
  → eGroupWare session cookies (sessionid, last_loginid)
quantivia/main.php
  → include quantivia/setup/quantivia_setings.php
  → SmartAdmin header, nav, ribbon
  → browser calls forms/, dashboard/, services/, view/
  → inc/common_functions.inc.php loads SO then BO
  → PDO to Quantivia DB; eGroupWare DB for accounts and groups
```

`quantivia/index.php` only checks `sessionid` and redirects to `main.php`.

There is no `quantivia/setup/setup.inc.php`. Quantivia is not in the eGroupWare application registry. Provenance: **Implemented**.

## Application structure

| Path | Role |
|---|---|
| `phpgwapi/` | eGroupWare API 1.8.004 |
| `login.php`, `loginextra.php`, `logout.php`, `index.php` | eGroupWare entry |
| `setup/` | eGroupWare setup UI and CLI (`setup-cli.php`) |
| `header.inc.php` | eGroupWare domain config. `header.inc.php.template` and `header.inc.php-old` are also present |
| `quantivia/inc/class.quantivia_so.inc.php` | Data access. `so_version` 216. Also defines `egw_addressbook` |
| `quantivia/inc/class.quantivia_bo.inc.php` | Business logic. `bo_version` 276. About 12 800 lines |
| `quantivia/inc/common_functions.inc.php` | License check, timezone, changelog, version string |
| `quantivia/inc/common_pageSetup.php` | Role flags and `checkCurrentUserAutherization()` |
| `quantivia/inc/worker.php`, `ofload.php`, `TaskMaster.php`, `TaskMasterLoop.bat` | Background work |
| `quantivia/inc/class.quantivia_notifier.inc.php` | PHPMailer SMTP |
| `quantivia/inc/broker.php`, `brokerv2.php`, `class.filecache.inc.php` | Cache / broker |
| `quantivia/forms/` | Page endpoints |
| `quantivia/dashboard/` | Dashboard widgets |
| `quantivia/services/` | Menu, filters, chart JSON, including `Lines.json.php` |
| `quantivia/view/` | DataTables Editor PHP |
| `quantivia/templates_*` | Seventeen client packs |
| `quantivia/smartadmin/` | SmartAdmin theme |
| `quantivia/jpgraph/`, `quantivia/lib/` | Graphing, PHPExcel, TCPDF, FancyTree, PHPMailer |
| `quantivia/api/qvaapi.php`, `quantivia/services/qvaapi.php` | API entry names. Contract not fully read |
| `QFD/union.bat`, `QFD/worker.vbs` | Windows worker launcher |
| `actions`, `ncr`, `permit`, `risk`, `smt`, `womt` | Custom eGroupWare trackers |
| `organogram/`, `origramy.swf` | Flash organogram |
| `custom/` | Untangle Captive Portal sample. Not part of Quantivia |
| `doc/`, `phpgwapi/doc/` | Upstream eGroupWare documentation |

Top-level apps also include addressbook, admin, bookmarks, calendar, emailadmin, etemplate, felamimail, filemanager, home, importexport, infolog, manual, news_admin, notifications, phpbrain, phpfreechat, phpsysinfo, polls, preferences, projectmanager, registration, resources, sambaadmin, sitemgr, syncml, timesheet, tracker, and wiki.

`projectmanager/$SERVER_TEMP/jpgraph_cache/` contains generated chart images with very long filenames. One of them prevents a default Windows checkout unless long paths are enabled. Provenance: **Implemented** as committed cache artefacts. They are not source.

## Languages and frameworks

| Item | Evidence |
|---|---|
| PHP | All application code. Pipeline image `php:5.4.45`. A commented changelog line (`1.2.093`) says "Upgraded : PHP 7 Compatibility". Commit `7cd336e1` is "Test old php". Supported version: **Unknown / Requires Confirmation** |
| JavaScript / CSS | SmartAdmin, jQuery-style UI, DataTables |
| SQL | MySQL via PDO and the eGroupWare DB layer. `db_type` is `mysql` |
| VBScript / batch | `QFD/`, `TaskMasterLoop.bat` |
| Python | `codedeploy_deploy.py`, `codedeploy_deploy_develop.py` (boto3). Not part of the runtime app |
| Flash | `origramy.swf` |

No `composer.json`. Vendored libraries are committed under `quantivia/lib` and `quantivia/jpgraph`.

## Databases

Two MySQL databases are named in committed config. No schema dump is in git.

| Config | Host | Port | Database | User |
|---|---|---|---|---|
| eGroupWare `header.inc.php` domain `default` | `localhost` | `3306` | `demo` | `root` |
| Quantivia `quantivia_setings.php` | `localhost` | `3306` | `demoppr` | `root` |
| Quantivia copy of the eGroupWare DB | `localhost` | `3306` | `demo` | `root` |

The password fields in both files are empty strings. A setup admin password hash is stored in `header.inc.php` (`header_admin_password` and `config_passwd`). Values omitted.

eGroupWare sessions use `egw_session_files`. `db_persistent` is true. Domain select box is false. Login template set is `idots`. `mcrypt_enabled` is false. `DEBUG_API` and `DEBUG_APP` are false.

Quantivia settings also set:

| Key | Value | Note |
|---|---|---|
| `version` | `1.2.000` | Overwritten with changelog tip `2.0.013` once `common_functions.inc.php` loads |
| `csv_symb` | comma | |
| `report_period` | `4` | Comment: weeks |
| `time_report_period` | `4` | Comment: weeks |
| `cpu_cores` | `30` | Comment: sockets times cores |
| `cpu_speed` | `30` | Comment: VM power factor |
| `ofload_location` | `https://online.quantivia.com/quantivia/inc/ofload.php` | Hard-coded remote URL |
| `file_storage` | `C:\wamp64\www\html` | Windows path |
| `broker_cache` | `C:\Windows\temp\QuantiviaCache` | Windows path |
| `worker_url` | `http://localhost/html` | |
| `worker_port` | `80` | |
| `use_wincache` | false | |
| `file_retention` | true | |
| `egw_bug_cat`, `egw_fea_cat`, `egw_gen_cat`, `egw_pmt_cat` | `36`, `35`, `94`, `95` | eGroupWare category ids for feedback |
| `excel_password` | present | Value omitted |
| `debug_ip` | one active address, older ones commented | Values omitted |

`EGW_SERVER_ROOT` in `header.inc.php` is the repository directory (`__DIR__` of that file). The same constant in `quantivia_setings.php` is `__DIR__` of `quantivia/setup`. `DPPR_INCLUDE_ROOT` is that setup directory plus `/quantivia`. Include order decides which definition wins. PHP will not change a constant that is already defined.

Tracker apps declare their own tables in each `setup/setup.inc.php` (`egw_ncr`, `egw_risk`, `egw_permit`, `egw_smt` was not re-listed here, `egw_womt` via the womt setup tables, `egw_actions`). Those tables live in the eGroupWare database, not in `demoppr`. Provenance: **Implemented** as setup metadata. A live database was not inspected.

Quantivia table names are referenced from the SO class (for example the projects table used by `is_user_project_admin`). A full table list was not extracted. `quantivia/setup/sql_construct.php` is present and was not fully read.

## Version identity

When `common_functions.inc.php` finishes loading:

- Active changelog keys: `2.0.000` through `2.0.013`.
- Version string: `2.0.013 - (SO:216 - BO:276)` because the code takes the last array key and appends SO and BO versions.
- Older notes `1.0.000` through `1.5.000` sit inside a block comment.

`quantivia/version.php` includes settings and `common_functions`, sets a worker session and template `templates_procon8_01`, logs posted `lic`, `mac`, `dom`, and `ser`, echoes `AD` if `ser` is `DJ00x`, otherwise echoes the version string. Error display is off (`E_ERROR` only).

## Authentication and sessions

- eGroupWare login via `login.php` and `loginextra.php`.
- Branches exist for auth types `cas`, `http`, and `sqlssl`. `header.inc.php` does not set `auth_type`. The value used at runtime is **Unknown / Requires Confirmation** (it usually comes from eGroupWare config stored in the database).
- Quantivia trusts cookies `sessionid` and `last_loginid`. It does not implement its own password check.
- Setup ACL (`setup_acl`) is an empty string, so the file does not restrict setup by IP.
- `show_domain_selectbox` is false.

No `auto_login.php` in this tree.

## Background work

`worker.php` task types 0–15 are documented in `business-rules.md`. Type 11 is an empty branch.

`ofload.php` is the script named by `ofload_location`, but the URL points at `online.quantivia.com`, not at the localhost worker URL. Provenance: **Implemented** configuration. Whether this snapshot is supposed to call that host is **Unknown / Requires Confirmation**.

`QFD/union.bat` starts `worker.vbs` ten times. `worker.vbs` GETs `http://quantivia.local.com/quantivia/inc/worker.php`. The loop is `Do Until i>10` and `i` is never incremented. **Inferred** from the script: the process does not stop after ten calls.

`TaskMaster.php` and `TaskMasterLoop.bat` are present. Their schedule on a server is **Unknown / Requires Confirmation**.

## Email

`class.quantivia_notifier.inc.php` uses PHPMailer `IsSMTP`. Host defaults to `localhost`, port `25`, timeout 15 seconds. SMTP auth is enabled only when `smtp_auth_user` is set in Quantivia config. From-address is `{sender}@{mail_suffix}` or `automailer@{mail_suffix}`. `mail_suffix`, `smtp_server`, and `site_title` are read from stored config rows, not from `quantivia_setings.php`. Provenance: **Implemented**.

## External integrations

| Integration | Where | Notes |
|---|---|---|
| Primavera P6 | `forms/p6import.php` | `.xer`, zip, XML. Title "Primavera P6 File Import" |
| Online Quantivia offload | settings `ofload_location` | HTTPS URL on `online.quantivia.com` |
| Local Quantivia worker | `QFD/worker.vbs` | `http://quantivia.local.com/.../worker.php` |
| AWS CodeDeploy | `codedeploy_deploy.py` | S3 upload then `create_deployment`. Uses env `APPLICATION_NAME`, `S3_BUCKET`, `DEPLOYMENT_GROUP_NAME`, `DEPLOYMENT_CONFIG`. `ignoreApplicationStopFailures` true |
| AWS CodeDeploy (develop script) | `codedeploy_deploy_develop.py` | Same pattern with `APPLICATION_NAME_DEV` and related `_DEV` env vars |
| eGroupWare feedback categories | settings category ids | Bug, feature, general, and a fourth id. Used by help links. Exact category names in the `demo` database were not read |
| GroupDAV, WebDAV, SyncML, SOAP, XML-RPC, JSON | root PHP endpoints | Stock eGroupWare transports |

## Deployment and environments

Three deployment stories are committed. They disagree.

### 1. Quantivia settings (Windows / WAMP)

Paths under `C:\wamp64\www\html` and `C:\Windows\temp`. Worker URL `http://localhost/html`. Databases on localhost. Offload URL on `online.quantivia.com`.

### 2. AWS CodeDeploy (Linux)

`appspec.yml` version `0.0`, `os: linux`, copies `/` to `/var/www/html/`.

| Hook | Script | Timeout | Run as |
|---|---|---|---|
| BeforeInstall | `scripts/install_dependencies` | 300s | root |
| BeforeInstall | `scripts/start_server` | 300s | root |
| ApplicationStop | `scripts/stop_server` | 300s | root |

`install_dependencies` is `yum install -y httpd`. `start_server` is `service httpd start`. `stop_server` uses `pgrep httpd` and `service httpd stop`. The stop script assigns `isExistApp = \`pgrep httpd\`` with spaces around `=`, which is not valid Bash. **Inferred** defect from reading the script. It was not executed.

`bitbucket-pipelinesOld.yml` (image `python:3.5.7`) zips the tree and runs `codedeploy_deploy.py` on branch `master`, and `codedeploy_deploy_develop.py` on branch `develop`. The remote branch is named `development`, not `develop`. Provenance: **Implemented** file. It is not the filename Bitbucket Pipelines loads.

### 3. Active Bitbucket Pipelines file

`bitbucket-pipelines.yml` is the filename Pipelines uses. Default image comment says `php:5.3`. The `master` step is named "Procon8/PHP 5.4", image `php:5.4.45`. It installs soap, installs Composer, runs `composer install`, `composer require phpunit/phpunit`, and `vendor/bin/phpunit --configuration ./phpunit.xml`.

`composer.json` and `phpunit.xml` are not in the repository. Provenance: **Implemented** pipeline text that does not match the tree. A successful run of this file on this snapshot is not possible without files that are absent.

### IIS

`web.config` sets the default document list, with `index.php` first. No rewrite rules. Provenance: **Implemented**.

### License host exceptions

See business rule BR-026. Hosts in that list are forced licensed. That is runtime behaviour, not a deploy manifest.

## Security observations (from the tree, not a penetration test)

- Database user `root` with an empty password is committed for both databases.
- A setup administrator password hash and mcrypt IV are committed in `header.inc.php`.
- An Excel password is committed in `quantivia_setings.php`.
- `setup_acl` is empty.
- `phpinfo.php` and `phpstats.php` are in the web root.
- `quantivia/quantiviasqladmin/` is a database admin UI inside the web tree.
- `version.php` accepts posted license material and writes it through `log_data` while running as the worker user.
- `requireFullLicence()` is a session flag. Hostname exceptions set that flag without a MAC check.
- Worker endpoints are ordinary HTTP scripts. `worker.vbs` calls `worker.php` with no credential in the URL. What `worker.php` requires before doing work was not fully audited.
- `custom/` is unrelated sample code in the same tree that CodeDeploy would copy to `/var/www/html/`.

These are **Implemented** facts about the snapshot. Whether they are still reachable on a host is **Unknown / Requires Confirmation**.

## Development and testing

- No Quantivia PHPUnit suite, no `phpunit.xml`, no Composer project.
- eGroupWare ships some upstream tests and docs under its own trees. They were not executed.
- `setup/test.php` is the eGroupWare setup test page.
- phpFreeChat includes a testcase path. Not a Quantivia test.
- Pipeline history on 2019-05-12 ("testing pipelines", "Test old php", "checking servrs deploy") is the only test-related git activity. Results of those runs are not in the repository.
- No `sonar-project.properties`.
- No Docker Compose file.
- Changelog and user guide are the developer-facing product notes.

## Monitoring and operations

No application monitoring agent, health endpoint standard, or log aggregation config was found. `ShowEnvironment.php` and the changelog array are the in-app environment display. `cpu_cores` and `cpu_speed` in settings are static numbers, not a live probe.

`version.php` is the only small status-style endpoint identified. It returns the version string (or `AD`).

## Configuration files to treat as environment-specific

| File | Why it matters |
|---|---|
| `header.inc.php` | eGroupWare DB, setup admin, session handler |
| `quantivia/setup/quantivia_setings.php` | Quantivia DB, paths, offload URL, category ids |
| `appspec.yml` | Linux deploy target |
| `bitbucket-pipelines.yml` | Active CI definition |
| `bitbucket-pipelinesOld.yml` | Previous CodeDeploy CI definition |
| `web.config` | IIS default document |

`header.inc.php` is a filled-in config, not only the template. It is committed. Provenance: **Implemented**.

## Discrepancies

1. **Windows settings vs Linux CodeDeploy.** Databases and file paths are a WAMP demo. `appspec.yml` deploys to Linux `/var/www/html` and installs httpd.
2. **Active pipeline vs old pipeline.** The live Pipelines filename runs PHPUnit. The CodeDeploy automation is in `bitbucket-pipelinesOld.yml`.
3. **Branch name.** Old pipeline builds `develop`. The git branch is `development`.
4. **Version number.** Settings say `1.2.000`. After common functions load, the version is `2.0.013`.
5. **`EGW_SERVER_ROOT`.** Defined as the repo root in `header.inc.php` and as `quantivia/setup` in the settings file.
6. **Offload target.** Settings call `online.quantivia.com`. The QFD script calls `quantivia.local.com`. The worker URL in settings is `http://localhost/html`.
7. **`development` is newer than `master`.** Message only: "Update from latest for version 2" (2019-08-07). Not reviewed.
8. **Related repositories** (`quantivia-clean`, `quantivialive`, `quantivia-svn`) are different git roots with their own Silicon Ark sets. They are not this tree.
9. **Stop script syntax.** `scripts/stop_server` is unlikely to run as written.
10. **QFD loop.** `worker.vbs` does not increment its counter.

## Unknown / requires confirmation

- Which branch and which host, if any, still run this code.
- PHP version actually used in production.
- eGroupWare `auth_type` on a real database.
- Whether SQL admin, `phpinfo.php`, and `version.php` are reachable on a deployed vhost.
- Full Quantivia physical schema.
- Contents of `development` at `ba5f6c5`.
- Whether task type 11 was intentionally left empty.
