# Project plan — timesheet

Evidence date: 2026-10-01.

Source repository: `git@bitbucket.org:overdrive/timesheet.git`.

Inspected revision: `master` at `3baa25ba` (2025-07-16 09:33:19 +0000, "sonar-project.properties created online with Bitbucket"). The scan-host path `~/projects/sonar_scan/repos/timesheet` was not on this machine. The tree was read from a clone of that revision. Committed database passwords, the login PIN constant, and other secrets are named by file and are not reproduced.

This plan describes what the repository contains. It does not decide what the product should become.

## Product

The README title is **Timesheet**. The only other README headings are "Test" and "Deployment", both empty.

The runnable application is a PHP server-rendered staff timesheet. People log time against clients, projects, project items, and tickets. The same records feed office and personal billing targets, reports, invoicing marks, QuickBooks invoice hand-off, and copies of time into the eIT and Convergence systems.

Provenance: **Documented** for the README title. The rest of this paragraph is **Implemented Behaviour**.

There is no product requirements document, project plan, or feature list in the source repository. The `docs` directory named in the 2026-09-28 discovery snapshot is not in `master` at `3baa25ba`.

## Objectives visible in the code

These are inferred from what the code does, not from a written goal statement.

1. Record who worked, for which client and project item, on which date, for how long, at what rate, with invoice notes and internal notes.
2. Show whether that time has been invoiced and whether it has been copied to eIT (`eitBillingID`).
3. Compare billed hours and amount with monthly targets stored on users (`sysUser.dblTarget`) and a base rate in system settings (`intBaseRate`).
4. Remind active users by email when logged hours are below a daily slice of their target.
5. Warn the ticket owner when spent hours cross 50%, 75%, and 100% of the ticket item estimate.
6. Produce operational reports, an IIF-style export, and a QuickBooks Online hand-off.
7. Administer clients, projects, project items, templates, rates, SLA contracts, public holidays, users, security groups, email templates, and system settings.
8. Deploy the tree to `/var/www/html/timesheet.overdrive.co.za/` and watch file changes with FIM.

## Scope

### In the repository

- Nemo page framework (`_nemo*.cls.php`, `layouts/`).
- Domain pages and list classes under the repository root and `includes/`.
- AJAX helpers in `ajaxfunctions.php`.
- Two cron scripts: `cron.daily.php` and `cron.reminder.php`.
- Vendored PHPExcel (`PHPExcel/`, `PHPExcel18/`).
- File-integrity monitor under `fim_2.0/`.
- AWS CodeDeploy app spec and Bitbucket pipeline that zips the tree to S3.
- Sonar project key file.

### Out of this repository

- The MySQL schema and seed data. Tables are named in SQL, but there are no migration files. Column lists are whatever `AssimulateTable` reads from the live database.
- Menu labels and which security group can open which page. Those rows live in `sysMenuLevel1`, `sysMenuLevel2`, `sysSecurity`, and `sysSecurityGroup`.
- System setting values (`sysSettings`), including SMTP, brand text, page size, password policy, and `intBaseRate`.
- Whether `cron.daily.php` and `cron.reminder.php` are scheduled on a host.
- The eIT, Convergence, and QuickBooks services this application calls.
- A test suite. None was found.

## System shape

```text
Browser
  -> PHP page (login.php or a Nemo page)
       -> system.php (pick DB by HTTP host, start file session, load sysSettings)
       -> MySQL timesheet database
       -> optional HTTP calls:
            eIT          https://eit.overdrive.co.za/ajax.functions.php
            Convergence  https://convergence.overdrive.co.za/ajaxFunctions.php
            QuickBooks   https://qb.overdrive.co.za/auth/
       -> SMTP mail through NemoEmail
```

A second and third database connection are configured for the production host name (eIT live database, and a QuickBooks webservice database on a hosted MySQL server). Whether every page uses those extra connections was not fully traced. Overview code references `$DATABASE_SETTINGS2`.

## Major components

| Component | Role | Evidence |
|---|---|---|
| Nemo | Session, menu, page security, lists, detail forms, mail, passwords | `_nemo.cls.php`, `_nemo.basic.cls.php`, `_nemo.list.cls.php`, `_nemo.details.cls.php`, `_nemo.email.cls.php`, `_nemo.password.cls.php` |
| Timesheet | Time entry list and save | `timesheet.php`, `includes/timesheet.cls.php` |
| Ticket timesheet | Parallel time-entry page | `timesheet_ticket.php` |
| Tickets | Ticket list, status, priority, items | `ticket.php`, `includes/ticket.cls.php` |
| Clients and projects | Client, project, project item, templates | `client.php`, `project.php`, `project.item.php`, `project.templates.php` |
| Overview | Monthly target dashboard | `overview.php`, `includes/overview.cls.php` |
| Reports | Ten named reports plus invoice and IIF actions | `report.php`, `includes/*.rpt.php` |
| People and access | Users, security groups, settings | `user.php`, `security.group.php`, `settings.php` |
| Rates, SLA, holidays | Reference data | `rate.php`, `sla.contracts.php`, `public.holidays.php` |
| Mail log | Stored outbound mail and templates | `email.php`, `email.template.php` |
| Reminders | Weekday hour reminders | `cron.reminder.php` |
| Daily cron | Invite and course-mail cases left from another product | `cron.daily.php` |
| FIM | File hash audit and email report | `fim_2.0/` |
| Deploy | S3 zip on `master`; CodeDeploy app spec | `bitbucket-pipelines.yml`, `appspec.yml` |

## Dependencies known from the tree

- PHP with the `mysqli` and `openssl` extensions. The code calls `mysqli_connect` (`system.php`, comment dated 2018-12-10).
- MySQL or MariaDB database named `timesheet2` for the production host, and `timesheets` for the host name `timesheets.php8`.
- Apache. `scripts/start_server` runs `service apache2 start`.
- Composer packages requested at deploy time: `phpmailer/phpmailer` and `aws/aws-sdk-php`. No `composer.json` is in the tree.
- PHPExcel, committed under `PHPExcel/` and `PHPExcel18/`.
- jQuery 3.3.1, jQuery UI 1.8.6, Chart.js, and other scripts under `js/`.
- AWS: S3 bucket from `$PROD_S3_BUCKET`, region and role from pipeline variables, RDS host named in `system.php`.
- External HTTP services: eIT, Convergence, QuickBooks (`qb.overdrive.co.za`).

## Milestones visible in comments

There is no milestone plan. Dated comments in the code are the change log that exists:

| Date in comment | What the comment says | Where |
|---|---|---|
| 2014-02 | Timesheet colours, hour override, project templates, mark as invoiced | `timesheet.php`, `includes/timesheet.cls.php`, `includes/project.cls.php` |
| 2016-09-06 | Office and user targets | `includes/timesheet.cls.php` |
| 2016-10-03 | Password framework and forgot-password | `login.php` |
| 2018-08-08 | Insert time into Convergence | `includes/timesheet.cls.php`, `project.functions.inc.php` |
| 2018-12-10 | `mysqli_connect` | `system.php` |
| 2019-01-15 | Copy timesheet to eIT | `timesheet.php`, `CopyToEit` |
| 2021-04-30 | `refUserProjectItemID` added to the eIT URL | `CopyToEit` |
| 2023-02-13 | Email when spent hours pass estimate thresholds | `Timesheet::Save` |

The newest commit on `master` (2025-07-16) only adds `sonar-project.properties`. Deeper history was not available from the shallow clone used for this inspection.

## Implementation status

**Implemented** and present on `master`: the pages and jobs listed above, deploy files, and FIM.

**Not established:**

- Which menu items each security group actually sees. The menu is loaded from the database at runtime.
- Whether CodeDeploy still runs after the pipeline uploads the zip. `bitbucket-pipelines.yml` stops at `aws s3 cp`. `appspec.yml` and `codedeploy_deploy.py` are in the tree. `bitbucket-pipelines.yml.bak.ftp` is an older git-ftp pipeline and is not the file Bitbucket runs.
- Whether `cron.daily.php` is still scheduled. Its cases create workshop invites, vouchers, and course-start mail. That behaviour does not match the timesheet screens.
- PHP version on the live host. One configured host name is `timesheets.php8`, which suggests a PHP 8 vhost. **Inferred**, not confirmed.
- Automated test status. README heading "Test" has no body. No PHPUnit or other test directory was found.

## Current project status

The repository is a long-lived internal Silicon Overdrive application. The last commit is a SonarQube project key. Production is aimed at `https://timesheet.overdrive.co.za/` (`appspec.yml` destination and FIM live base URL).

Human confirmation is required for live scheduling, the real menu and roles, and whether the course-invite cron and the hardcoded Convergence task map are still in use.
