# MRCU Tracker v2 upgrade

## 2.3.0: the organisation view, groups, the Inbox and borrowed views

New in this package. Same upload-and-restart procedure as below; no NPM install is needed if 2.2.0 is already running. The database upgrades itself on first start (two new columns and one new table).

**Portfolios are no longer empty for other people.** Until now a project shared with a
team was invisible to everyone outside that team, so a colleague opening the sidebar saw
your portfolio headings with nothing under them. Any project whose privacy is *not*
"Private" can now be **read** by everyone at MRCU: they can open it, follow its tasks and
see its progress, but they cannot change anything unless they are a member. Private
projects stay invitation-only and personal projects stay hidden from everyone, super
admins included — neither is affected.

- A project owner can switch this off per project: **Settings > "Let the rest of MRCU
  follow this project"**. Existing projects start with it on.
- View-only projects are marked with 👁 in the sidebar. The ◉ button beside the
  **Portfolios** heading hides them if the list gets long; the choice is remembered.
- **Organisation** (new sidebar item) is the "what is everyone working on" page: every
  person with their open, overdue and completed counts and the projects they are active
  in, plus every shared project grouped by portfolio. Clicking a person opens their
  profile: their open tasks, their projects, their groups and their recent activity.

**Portfolios can be renamed and recoloured**, including the shared **Work** portfolio,
by the person who created them or by any workspace admin (`...` beside the name). Work
cannot be made personal or deleted, because everyone's projects sit in it.

**Groups (teams) are open to everyone.** Anyone can create a group — Data Science,
Grants, Clinical — from **People & teams > + Group**, and whoever creates it leads it:
they add and remove members, set leads, rename, describe and delete it. Workspace admins
can still run any group. A member can leave a group on their own; the last lead cannot
leave without naming another.

**New projects can start with named people.** The New project dialog now has a **People**
picker beside **Team**, so a project can begin with a group, with individually chosen
colleagues (each as editor or viewer), or with both. Everyone added is notified.

**Inbox** (new sidebar item, with an unread badge). Email delivery is not configured yet,
so notifications are kept in the application: work assigned to you, tasks you were added
to, comments on tasks you are involved in, and invitations to projects and groups.
Opening an item marks it read and jumps to the task, project or group. When SMTP is
configured later, the email copy resumes on top of this — nothing needs to change.

**Super admins can borrow another person's view.** **People & teams > View as**, or the
button on anyone's profile page, shows the workspace exactly as that person sees it:
their Home feed, their tasks, their projects, their Inbox and their KPI Pulse. A banner
says whose view it is and offers the way back.

- The borrowed session is **read-only**: no writes are accepted while it is active, so
  nothing is ever recorded in the workspace under someone else's name.
- **Personal projects stay private**, even in a borrowed view. The Personal checkbox
  promises staff that not even a super admin can read that work, and borrowing a view
  does not break that promise.
- Each borrowed view is recorded in the activity log against the super admin.

## 2.2.0: personal portfolios and projects

New in this package. Same upload-and-restart procedure as below; no NPM install is needed if 2.1.0 is already running.

- A portfolio or a project can be marked **Personal: only I can see it** (portfolio: the `...` button next to its name in the sidebar; project: Settings). Personal work is hidden from everyone else in the application, including workspace admins and super admins: not in All projects, Insights, Progress & workload, search, People workload, the trash or the activity feed, and never in anyone else's emails. Personal projects cannot have members or collaborators; tasks in them belong to you.
- Every project inside a personal portfolio is personal. Dragging a project into a personal portfolio makes it personal; switching Personal off on a project inside one moves it to Work.
- **Upgrade conversion**: a portfolio you created whose name contains "personal" becomes personal automatically on first start, together with its projects (other members are removed and their tasks come back to you). Anything else stays as it is; use the switch.
- **Profile > Download my personal projects** gives you a JSON copy of all your personal portfolios, projects, tasks and comments.
- What it does not protect against: anyone with cPanel, phpMyAdmin or the nightly backup files can read the database directly.

## Quick upgrade for tracker.mrcug.org (your account)

Paths below use your cPanel username `mrcuttcj`, application root `~/mrcu-tracker` and Node 24. Allow 15 minutes.

1. **Back up first** (cPanel Terminal):
   ```bash
   mkdir -p ~/backups && cd ~/mrcu-tracker && node server/src/transfer.js backup ~/backups/mrcu-tracker-before-v2.json
   ```
   The command reads `.env`, so no extra variables are needed. Confirm the file exists: `ls -l ~/backups`.
2. Node.js app page: **Stop** the application.
3. File Manager: upload `mrcu-tracker-2.3.0-<date>.zip` into `/home/mrcuttcj/mrcu-tracker`, **Extract**, open the extracted folder, **Select All > Move** to `/home/mrcuttcj/mrcu-tracker` (overwrite when asked), then delete the empty folder and the zip. `.env` and the database are untouched.
   Terminal alternative, after uploading the zip into `~/mrcu-tracker`:
   ```bash
   cd ~/mrcu-tracker && unzip -o mrcu-tracker-2.3.0-*.zip && cp -r mrcu-tracker-2.3.0-*/. . && rm -rf mrcu-tracker-2.3.0-* && ls
   ```
4. Node.js app page: **Run NPM Install** (adds `nodemailer`), then **Start**. Startup creates the new tables and columns on its own; no SQL to run.
5. Check `https://tracker.mrcug.org/api/health` shows `"version":"2.3.0"`, sign in, open Home, a project, a task and KPI Pulse.
6. People & teams > **KPI reporting lines & director access**: set who reports to whom and give the Director account *Director* Pulse access once it exists.
7. **Nightly backup** (still outstanding from v1). cPanel > Cron Jobs > *Once Per Day*, command:
   ```bash
   cd /home/mrcuttcj/mrcu-tracker && /home/mrcuttcj/nodevenv/mrcu-tracker/24/bin/node server/src/transfer.js backup /home/mrcuttcj/backups/mrcu-tracker-$(date +\%F).json >> /home/mrcuttcj/backups/backup.log 2>&1
   ```
8. **Email** (optional, when you are ready): add the SMTP lines from the *Email setup* section to `~/mrcu-tracker/.env` (the `info@tracker.mrcug.org` mailbox password, not your login), add the 15-minute cron job, run it once with `EMAIL_ENABLED=false`, then switch to `true`.

What changed for people already using the tracker: existing projects sit under the **Work** portfolio; the primary assignee of each task is shown as its *Owner*; earlier KPI values remain in history and prefill the current period; project and task names that used an em dash now use a hyphen.

---

## Background and details

This release is built in `asana-clone-v2`. It retains the existing Node.js + MySQL/MariaDB architecture and is intended for the existing Namecheap cPanel Node.js application. It is not a PHP application. It does not need a new database, a replacement database, or reseeding.

## Before uploading

1. Take a database backup using the **currently deployed version's** backup command or cPanel/phpMyAdmin export. Save it outside the public web directory. Also retain the current application files for rollback.
2. Arrange a short maintenance window so nobody is editing during the upgrade. Stop the cPanel Node.js application and any existing tracker cron jobs.
3. Keep the existing `.env`, cPanel environment variables, database credentials and database files. Do not upload any local preview/test databases or the source folder wholesale.

## Upload and restart

1. Upload the files inside the supplied `release/mrcu-tracker-2.3.0-<date>` folder into the existing Node.js application root. The zip contains that enclosing folder: open it after extracting, then copy its contents into the application root.
2. Run cPanel's **Run NPM Install** in the application root. The new runtime dependency is Nodemailer. Do not overwrite the application's `.env` with `.env.example`.
3. Confirm the configured Node.js version is 22.5 or newer and that the database user can CREATE and ALTER tables. Keep the existing database settings.
4. Restart the Node.js application. Startup adds the v2 tables and missing columns automatically. No manual SQL or seed command is required. The migration is repeatable.
5. Open `/api/health`: it should report version `2.3.0`. Refresh the browser, sign in, and verify Home, a current project, a task and KPI Pulse. Existing sessions remain valid for their normal duration.

Do **not** run `seed:mrcu`, `restore`, or `migrate:sqlite` as part of this upgrade. Those commands serve different purposes.

## What happens to existing records

- Existing projects appear under the Work portfolio, retaining their team memberships, privacy and ownership. Users can create additional portfolios and move projects into them.
- Existing tasks, comments, descriptions, dates and KPI entries are preserved. Existing primary assignees are shown as task owners. Contributor/reviewer assignments are additive.
- Tasks without a selected project use a private personal inbox internally. The inbox is omitted from the project navigation. Move a task into a shared project to collaborate with others.
- Existing KPI values are available to prefill the current/previous period and remain in indicator history. They do not automatically become reviewed submissions.
- A single existing active account whose name exactly matches Ronald Mulebeke (case-insensitive) receives KPI director access once during migration. If no unique match exists, a superadmin must select the correct account under People & teams. No account is created and no password is changed.
- Set each person's supervisor under **People & teams > KPI reporting lines & director access**. Workspace admin status alone does not grant organisation-wide KPI access. Directors and superadmins can see all; others see themselves and their direct reports.
- A superadmin can choose **Use this session as** in their profile to work as admin or member and can restore superadmin access from the same place. This does not change the account's stored role.

## Email setup (optional, disabled by default)

The supplied code sends only assignment notifications when another person assigns a task and one morning digest per person. The digest includes open tasks due today or overdue, plus undated tasks. Future-dated work is excluded. Comments, mentions and small edits do not generate emails. Each user can opt out in their profile.

Create the `info@tracker.mrcug.org` mailbox first. Its password is separate from the tracker login password. Set these variables in a protected `.env` in the application root so the cron command can read them as well as the web app:

```dotenv
EMAIL_ENABLED=false
SMTP_HOST=tracker.mrcug.org
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=info@tracker.mrcug.org
SMTP_PASSWORD=your-mailbox-password
SMTP_FROM="MRCU Tracker <info@tracker.mrcug.org>"
APP_ORIGIN=https://tracker.mrcug.org
APP_TIMEZONE=Africa/Kampala
DIGEST_HOUR=7
```

Use the secure outgoing host shown by your cPanel mailbox configuration if it differs. TLS certificate validation remains enabled. No paid email service is required by this code; the mailbox provider's sending limits still apply.

Add a cPanel cron job every 15 minutes, using the full Node executable path from your cPanel Node.js environment and your actual application directory:

```sh
cd /home/CPANEL_USER/APP_DIRECTORY && /FULL/PATH/TO/node server/src/mail-worker.js >> /home/CPANEL_USER/tracker-mail.log 2>&1
```

Run once while `EMAIL_ENABLED=false`; it should report that no messages were sent. Once credentials and the cron command are confirmed, set `EMAIL_ENABLED=true`. The first cron run after 07:00 Kampala time creates that day's digest. Assignment messages are delivered on the next cron run. Verify a single intended assignment and its receipt in Outlook before inviting the wider team.

No real SMTP messages were sent during local testing. Live mailbox delivery, DNS/SPF/DKIM and provider rate limits must be verified on hosting. The worker retries failed deliveries up to five runs. Logs omit credentials. After a process crash, an outbox row left in `sending` needs an administrator to inspect delivery logs before resetting it; blind retries could duplicate a message already accepted by SMTP.

## Rollback

Stop the application and mail cron, retain a new backup if any v2 data has been entered, and restore the previous application files. The additive columns do not overwrite the old fields, but the old application will not expose v2 contributors, portfolios or period reviews. For a complete return to the pre-upgrade state, restore the database backup taken before upgrading; doing so discards changes made since that backup. Restart the application only after choosing which data state to retain.

## Verification completed locally

- Production TypeScript and Vite build.
- Existing API/session/privacy/backup regression suite on SQLite and MariaDB 11.4.
- V2 personal tasks, contributor visibility, ordering, supervisor/director scope, atomic period submissions, duplicate prevention, review/return, access switching, opt-outs, digest deduplication and backup round-trip tests on both database engines.
- Existing-data upgrade fixtures and repeat migration on SQLite and MariaDB.
- Browser checks for Home, description autosave and Activity, period submission and form collapse, director trends, and mobile layout.

Century Gothic is requested throughout, with local fallback fonts if it is not installed on a device. A licensed font file is not bundled. Files remain external; task descriptions/comments support links, formatted text and references. The only upload is a profile photo (PNG/JPEG/WebP); the browser crops it to a 192 px square before upload and the server stores it in its own table (`user_photos`) and serves it as a cacheable image URL, so photos never inflate task or people listings.



source /home/mrcuttcj/nodevenv/mrcu-tracker/24/bin/activate && cd ~/mrcu-tracker && cat >> .env <<'EOF'
EMAIL_ENABLED=true
SMTP_HOST=tracker.mrcug.org
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=info@tracker.mrcug.org
SMTP_PASSWORD=OrA;*u#Sp+DRMq39
SMTP_FROM="MRCU Tracker <info@tracker.mrcug.org>"
APP_ORIGIN=https://tracker.mrcug.org
DIGEST_HOUR=7
EOF
nano .env 