# Zettai Process Tracker (ZPT)

**Software delivery workflow tracker** — Odoo-inspired project / task / bug / timesheet / leave management.

**Stack:** Node.js + PostgreSQL (`server/`) with product UI in `server/web`.  
**Config:** single repo-root `.env`. Root `package.json` only proxies scripts into `server/`.

---

## Table of contents

1. [Project layout](#1-project-layout)
2. [Product goals](#2-product-goals)
3. [Apps & navigation](#3-apps--navigation)
4. [Roles & permissions (RBAC)](#4-roles--permissions-rbac)
5. [Domain model](#5-domain-model)
6. [Task workflow & gates](#6-task-workflow--gates)
7. [Modules — detailed requirements](#7-modules--detailed-requirements)
8. [UX patterns](#8-ux-patterns)
9. [Formats & conventions](#9-formats--conventions)
10. [Demo / seed data](#10-demo--seed-data)
11. [Tech stack](#11-tech-stack)
12. [Run & deploy](#12-run--deploy)
13. [Related docs](#13-related-docs)

---

## 1. Project layout

```
zs-tracker/
├── .env / .env.example     # Single env file (repo root only)
├── package.json            # Thin scripts → server/ (dev, migrate, seed, …)
├── scripts/                # Optional local Postgres helpers
├── docs/                   # UI_LAYOUT, deploy/backup notes
└── server/                 # The application
    ├── package.json        # Real dependencies & Prisma scripts
    ├── prisma/             # Schema, migrations, seed
    ├── src/                # Express API
    └── web/                # Product UI (index.html, js/, css/, assets/)
```

| Concern | Location |
|---------|----------|
| Env / secrets | **Root** `.env` only — do not add `server/.env` |
| npm install | `npm --prefix server install` |
| Day-to-day commands | From root: `npm run dev`, `migrate`, `seed`, … |
| UI / API | `server/web`, `server/src` |

---

## 2. Product goals

- Track **projects**, **tasks / subtasks**, and **bugs** through gated workflow stages
- Log **timesheets** (HH:MM) and a **live timer** (start / pause / resume / stop)
- Support **Time Off** (allocate, apply, approve, holidays)
- Provide **dashboards & reporting** by role
- Enforce **role-based access** (Super Admin, Project Admin, BA, Developer, Tester / QA)
- Deliver **Odoo-like UX**: apps menu, facet search with chips, inline edit with dirty save, stage bars, chatter

---

## 3. Apps & navigation

Hash-style routing (`#/<route>`). **Menu structure must stay the same**.

### Apps grid

| App | Home | Sub-menus |
|-----|------|-----------|
| **Dashboards** | Dashboard (SA/PA) / My Work (others) | **Super Admin & Project Admin:** Dashboard, My Work. **BA / Developer / Tester:** My Work only (Dashboard duplicates My Work for these roles) |
| **Project** | Projects | Projects, Tasks, Bugs, Reporting, Releases |
| **Timesheets** | Timesheets | Timesheets |
| **Time Off** | My Time | My Time, Overview, Management (**Super Admin only**) |
| **Employees** | Employees | Employees (**Super Admin only**) |

### Shell chrome

- Apps grid button
- Current app name + top menu for that app
- Notifications bell + unread count
- Current user (name, role) + logout
- Floating **timer bar** (global)
- Shared modal + toast notifications

### Routes

| Route | Feature |
|-------|---------|
| `dashboard` | Role-based dashboard |
| `mywork` | My Work |
| `projects` | Projects list / detail (`?project=`) |
| `tasks` | Tasks kanban/list/detail (`?task=`, `?project=`) |
| `bugs` | Bugs kanban/list/detail (`?bug=`, `?new=`, `?edit=`, `?task=`) |
| `timesheets` | Timesheets |
| `leave` | Time Off — My Time |
| `leave-overview` | Time Off — Overview |
| `leave-management` | Time Off — Management (SA) |
| `employees` | Employees (SA) |
| `reports` | Reporting |
| `releases` | Release / Deadline Tracking (project → deadline → task status) |
| `settings` | Configuration (hidden; reset demo via `#/settings`) |

---

## 4. Roles & permissions (RBAC)

### System roles

`Super Admin` · `Project Admin` · `BA` · `Developer` · `Tester / QA`

### Project member roles

Stored per membership: `Project Admin`, `BA`, `Developer`, `Tester / QA`, `Member`

### Permission matrix

| Action | Who can |
|--------|---------|
| **Super Admin** | Everything |
| `manage_employees` | Super Admin only |
| `create_project` | Project Admin |
| `manage_project` | Project Admin (admin or member of that project) |
| `view_task` | PA (on project); assignee / contributors / assignments; BA/Dev/QA if project member; or related bug assignee/reporter |
| `edit_task` (field edits) | PA; assignee / contributors / assignments; other **project members**; **blocked** when stage is Done unless PA/SA |
| `change_task_status` | PA (on project); task assignee; assignments; contributors |
| `edit_requirements` | BA / Project Admin (BA may edit requirements beyond Inbox) |
| `log_time` | Any active user |
| `upload_evidence` | PA, Developer, BA, Tester / QA |
| `create_bug` | Project Admin, Tester / QA |
| `manage_bug` (field edits) | PA, Tester / QA, bug assignee, or project member on parent task |
| `change_bug_status` | PA (parent project); bug assignee; **Tester / QA only** `Ready for Retest` → `Closed` or `Reopened` |
| `assign_work` | Project Admin |
| `apply_leave` | Any active user |
| `manage_leave` | Super Admin only |
| `view_reports_all` | Super Admin |
| `view_reports_project` | Project Admin |

### Visibility

- **Projects:** SA = all; PA = admin/member projects; others = member projects
- **Tasks / bugs:** filtered by `view_task` / parent task visibility
- **Employees UI:** Super Admin only (route + actions)

---

## 5. Domain model

### Employee

`id`, `name`, `email`, `phone`, `department`, `designation`, `role`, `active`, `avatarColor`

### Project

`id`, `code`, `name`, `description`, `startDate`, `endDate`, `adminId`, `status` (`Active` \| `On Hold` \| `Completed`), `color`, `tags[]`, delivery rules (`requireAssigneeHours`, `requireBaAnalysis`, `requireDescriptionAc`, `requireRequirementDoc`, `requireReadyForDevelopment`, `enforceRequiredSubtasks`, `requireDevelopmentComplete`, `requireUnitTestEvidence`, `allowTypedEvidence`, `enforceDependencies`, `requireCodeReview`, `requireQaPassed`, `requireQaEvidence`, `blockDoneOnBlockingBugs`, `requireAcceptance`, `requireTesterApproval`, `requireBugRetestEvidence`), `members[{ employeeId, projectRole }]`, `internalStatuses[{ id, text, color, stage, active }]`

**Default internal statuses (cloned per project):**

| Stage | Statuses |
|-------|----------|
| Inbox | Created, Requirement Analysis, Clarification Needed, Ready for Development |
| In Progress | Development, Unit Testing, Blocked |
| Code Review & QA | Code Review, QA Testing, Bug Fixing, Ready for Retest |
| Done | Approved, Completed, Released |

**Lifecycle (any stage):** `Open` (default) · `Done` · `Cancelled` — available in the status pill menu (dimmed, below a separator). Cancelled/Done tasks are hidden from list & kanban unless Filters → **Include Cancelled / Done**.

### Task / subtask

`id`, `title`, `projectId`, `description`, `acceptanceCriteria`, `stage`, `lifecycle` (`Open` \| `Done` \| `Cancelled`), `internalStatusId`, `priority` (0–3), `tags[]`, `assigneeId`, `contributors[]`, `assignments[{ employeeId, allocatedHours }]`, `allocatedHours`, `billingType` (`Billable` \| `Non-billable`), `startDate`, `dueDate`, `parentId`, `dependencies[]`, `attachments[]`, workflow flags (`baAnalysisComplete`, `developmentComplete`, `unitTestEvidence`, `developerCompletionLog`, `codeReviewApproved`, `qaResult`, `qaEvidence`, `acceptanceSatisfied`, `testerApproval`, `completionDate`, `completedBy`), `required` (subtask), `requiredSubtasksComplete`, audit fields

**Task stages:** `Inbox` → `In Progress` → `Code Review & QA` → `Done`

### Bug

`id`, `parentTaskId`, `title`, `description`, `reproSteps`, `expected`, `actual`, `severity` (Critical/High/Medium/Low), `priority`, `assigneeId`, `reporterId`, `allocatedHours`, `status`, `resolutionNotes`, `blocking`, `attachments[]`, `unitTestEvidence`, timestamps

**Bug statuses:** `Open` → `Assigned` → `In Progress` → `Ready for Retest` → `Reopened` → `Closed` · `Cancelled`

Closed and Cancelled bugs are hidden from list & kanban unless Filters → **Include Cancelled / Closed**.

### Timesheet

`id`, `employeeId`, `projectId`, `taskId`, `bugId`, `workDate`, `hours` (decimal storage), `category`, `description`, `billingType`, `createdAt`, `approvalStatus` (`Pending` \| `Approved`), optional `fromTimer`, `autoClosed`

**Categories:** Analysis, Development, Unit Testing, Code Review, QA, Bug Fixing, Other

### Activity (audit)

`id`, `entityType`, `entityId`, `userId`, `action`, `details`, `at`

### Planned activity (schedule)

`id`, `taskId`, `type` (`todo` \| `email` \| `call` \| `meeting` \| `document`), `summary`, `dueDate`, `assigneeId`, `note`, `status` (`planned` \| `done`), audit fields

### Note / message

`id`, `taskId`, `userId`, `body`, `kind` (`note` \| `message`), `createdAt`, `updatedAt`, `deleted`

### Active timer

`employeeId`, `entityType`, `taskId`, `bugId`, `projectId`, `status` (`running` \| `paused`), `startedAt`, `accumulatedMs`, `category`, `description`, `sessionDate`, `lastHeartbeatAt`

### Leave

- **Types:** CL, EL, SL, Comp Off (balance-tracked); Unpaid (no balance)
- **Allocation:** `employeeId`, `typeId`, `year`, `allocated`, `validUntil`
- **Request:** `fromDate`, `toDate`, `dayPeriod` (`full` \| `morning` \| `afternoon`), `days`, `description`, `status` (`to_approve` \| `validated` \| `refused`), decision fields
- **Holiday:** `date`, `name`

### Notification

`id`, `text`, `at`, `read`

### Attachment (metadata + real files in production)

`id`, `name`, `size`, `type`, `kind` (e.g. `requirement`, `unit-test`), `createdAt` (+ stored file path/URL in production)

---

## 6. Task workflow & gates

Forward stage moves must pass **server-side** gates (`server/src/services/workflow.ts`).

### Gate A — Inbox → In Progress

- At least one assignee
- All assignment allocated hours &gt; 0
- `baAnalysisComplete`
- Description and acceptance criteria non-empty
- Requirement attachment if `project.requireRequirementDoc`
- All **required** subtasks Done
- Internal status text = **Ready for Development**

### Gate B — In Progress → Code Review & QA

- `developmentComplete`
- Unit-test evidence (file, or typed if `allowTypedEvidence`; reject bare “done”)
- Required subtasks Done; no open dependency tasks

### Gate C — Code Review & QA → Done

- `codeReviewApproved`
- `qaResult === 'Passed'` + `qaEvidence`
- No **blocking** open bugs
- Required subtasks Done
- `acceptanceSatisfied` + `testerApproval`

### Reopen (from Done)

- Reason required
- Move to **Code Review & QA**
- Clear completion / acceptance / tester approval / QA result
- Align internal status toward QA Testing

### Return to In Progress

- From Code Review & QA (e.g. when QA Failed), with reason

### Return to Inbox

- From **In Progress**, with reason (undo accidental start)

Failed transitions must be blocked with clear errors and logged (`transition_blocked`). Successful moves log `stage_change`.

### Bug gates

- **Ready for Retest** requires unit-test evidence
- Blocking open bugs block parent task Gate C
- Tester / QA status changes limited to Close / Reopen from Ready for Retest

---

## 7. Modules — detailed requirements

### 7.1 Employees

- CRUD for employees (SA)
- Activate / deactivate (retain history; warn if tasks assigned to inactive)
- Fields: name, email, phone, department, designation, role, active

### 7.2 Projects

- Kanban-style cards + list; search
- Click project → tasks filtered by project
- Create / edit: code, name, description, dates, status, color, tags, full **delivery rules** (Gate A/B/C + bug retest evidence), admin, members + project roles
- New project clones default internal statuses
- Detail: stats, members, internal statuses, stage counts
- Settings gear from Tasks when project filter is active

### 7.3 Tasks

**List / Kanban**

- Parent tasks on board (`parentId` null); columns = stages
- Drag-and-drop stage change if `change_task_status`
- Quick create (`+`) per column
- List view with multi-level Group By (selection order = hierarchy, e.g. Stage › Project › Client); CSV export
- **Odoo facet search:** chips + Filters (My Tasks, Unassigned, Client, Project, Stage, Assignees, Priority) + multi Group By + Favorites (saved searches)

**Detail**

- Stage chevron bar (immediate transition via gates)
- **Inline edit** (click value): title, priority stars, internal status pill (dropdown for current stage), project, tags, assignees, deadline, allocated hours, billing, description, acceptance criteria
- Cloud **Save** / **Discard** appear only when dirty
- Read-only: Customer (the client mapped on the project), Task ID
- Remove redundant “Internal status” field from grid (status via pill + stage bar)
- Timer Start / Pause / Resume / Stop
- Allocation info `(i)` modal: member hours / actual / remaining
- Multi-assignee `assignments` with hours; primary assignee = first
- Parent allocation consolidates parent + subtasks where applicable
- Backward stage moves: click previous stage on the chevron → reason modal (Return to Inbox / In Progress / Reopen)
- Tabs: Description, Acceptance criteria, Timesheets, Sub-tasks, Bugs, Attachments, Workflow
- Chatter: Send message, Log note, Schedule Activity; planned activities (edit / mark done); activity feed
- Workflow tab: BA analysis, development complete, code review, acceptance, unit-test evidence, QA result, completion log (role-gated)
- Subtasks: create with `parentId`; list stage/assignee/alloc/actual
- New tasks start in **Inbox**; billing required

### 7.4 Bugs

- Kanban by status + list with multi-level Group By (selection order = hierarchy) + CSV
- Facet search: My Bugs, Unassigned, Blocking, Client, Project, Status, Severity, Assignees; multi Group By; Favorites
- Detail: status bar; shortcuts (Ready for Retest, Retest Passed→Close, Retest Failed→Reopened)
- Inline dirty edit: title, stars, task, severity, assignee, alloc, blocking, description / expected / actual / resolution / repro
- No status pill duplicate next to title (status via stage bar)
- Timer (default category Bug Fixing)
- Tabs: Description, Reproduction, Timesheets, Attachments
- Create: PA / Tester; Open→Assigned when assignee set
- Evidence gate before Ready for Retest

### 7.5 Timesheets

- Store decimal hours; **display and edit as HH:MM**
- Billing inherited from task
- **User view:** own rows; group Month→Date | Date | Month; expand/collapse; add line
- **Admin (SA / PA):** all rows; filters project / billing / employee / search; group by Project, Project→Task, Task, Member, Member→Date, Project→Member, etc.
- Inline add / edit / delete; footer totals
- Embed on task/bug Timesheets tabs
- `approvalStatus` exists in model — production should support approval if retained

### 7.6 Timer

- One active timer per user (confirm when switching entity)
- Start on task or bug; Pause / Resume; Stop → create timesheet (`fromTimer`); Discard without log
- Floating bar: entity link, live HH:MM:SS, controls, Open
- Heartbeat (~15s) → `lastHeartbeatAt`
- Auto-stop on tab/window close → timesheet with `autoClosed`
- Recovery: overnight or stale heartbeat (&gt;2 min) → auto-log to last heartbeat
- Short sessions (&lt;1 min): discard or minimal duration when forced

### 7.7 Time Off (Leave)

- **My Time:** balance cards (CL/EL/SL/Comp Off); year calendar; type filter; holidays; my requests; Apply (balance check; day period)
- **Overview:** calendar / requests (SA may see all)
- **Management (SA):** Approvals (approve/deny + note); Allocations by employee/year/type; Public Holidays CRUD
- Notifications on apply / decide
- Half-day only when from date = to date

### 7.8 Reporting & dashboards

**Dashboard**

- SA: projects, employees, overdue, bugs, alloc vs actual, over-budget, stages, workload, recent activity
- PA: per-project progress, bugs, overdue, member workload
- Others: My Work–style summary

**My Work**

- My tasks/bugs, today/week hours, alloc vs actual, deadlines, pending evidence, open bugs

**Reporting**

- Project effort, Employee effort, Task/subtask effort, Bug effort & aging, Over-budget, Daily timesheet, Stage transition history, QA results & reopened bugs
- Effort reports (Project / Employee / Task / Bug / Over-budget / Daily) show **Allocated**, **Actual**, and **Variance** (HH:MM; Variance = Actual − Allocated; under = green, over = red)
- Filters: date range, project, billing, employee (admins); CSV export

**Releases / Deadline Tracking**

- Project-level upcoming and overdue deadlines (task/subtask due dates + project end date)
- Open bugs appear on their parent task’s deadline (or project end date if the parent has none)
- Expand project → deadline date → task / subtask / bug status · assignee · priority
- Done-stage internal status **Released** (after Completed) removes the item from this screen; Completed alone still appears until Released

**Configuration** (route `#/settings`, not in main menu)

- Reset demo data (non-prod); production: system settings as needed

### 7.9 Notifications

- In-app list + unread badge
- Created for leave apply/decide, and seed events (blocking bug, overdue, etc.)

---

## 8. UX patterns

**Full layout contract (navbar, control panel, Employees, Projects cards/detail/forms):** see **[docs/UI_LAYOUT.md](./docs/UI_LAYOUT.md)**.

| Pattern | Requirement |
|---------|-------------|
| **Shell** | Sticky brand-blue `#00579a` navbar: apps grid · current app name · per-app top menus · notifications · user · logout. See UI_LAYOUT §2. |
| Apps grid | Dashboards / Project / Timesheets / Time Off / Employees (SA). Switch app → reload top menus |
| Control panel | Sticky under navbar: brand-blue **New** (left) + title (+ gear) · **center** search or facet bar · right counts / view toggles / actions. Do not put “New” only on the far right of a card header. |
| Projects cards | Odoo kanban cards: ★ · name · ⚙ settings · tags line · tasks/hours/bugs/dates · admin avatar · status dot. **Card click → Tasks filtered by project**; gear → project settings. Cards/list toggle on the right. |
| Project form | Full-page create/edit with code, name, description, dates, status, color, tags, req-doc, typed evidence, admin, **members + roles** |
| Employees | Control panel + table: ID, Name+avatar, Email, Phone, Dept, Designation, Role, Status, Edit/Activate. Create/Edit via shared modal |
| Facet search | Chips in bar; Filters / Group By / Favorites dropdown; remove chip with × (Tasks & Bugs) |
| Inline edit | Click value → editor; Save cloud only when dirty; Discard |
| Stage bars | Chevron statusbar for task stages / bug statuses |
| Priority | 1–3 clickable stars |
| Chatter | Messages, notes, scheduled activities, audit feed |
| Views | Kanban + List toggles where applicable |
| Empty states | Friendly empty copy |
| Toasts / modal | Success, warning, danger; shared Bootstrap dialog (`#appModal`) |
| Visual system | Roboto + Bootstrap Icons; `server/web/css/styles.css` tokens (`.o-navbar`, `.o-control-panel`, `.project-card`, …) |

**Anti-pattern:** A slim custom shell (only “Employees | Projects” links, blue primary buttons, thick color-bar cards, truncated project modal) is **not** acceptable as product UI.

---

## 9. Formats & conventions

| Concern | Rule |
|---------|------|
| Dates (display) | **DD-MM-YYYY** |
| Date-times (display) | DD-MM-YYYY + time |
| Date inputs | ISO `YYYY-MM-DD` |
| Hours (UI) | **HH:MM** |
| Hours (storage) | Decimal hours |
| IDs / codes | e.g. `EMP-001`, `PRJ-001`, `ZPT-101`, `BUG-001`, `TS-001` — DB may use UUID + display codes |
| Billing | Task-level Billable / Non-billable; timesheets inherit |

---

## 10. Demo / seed data

Use equivalent seed for demos / tests:

| ID | Name | Role |
|----|------|------|
| EMP-001 | Gowtham | Super Admin |
| EMP-002 | Priya | Project Admin |
| EMP-003 | Arun | BA |
| EMP-004 | Karthik | Developer |
| EMP-005 | Nisha | Tester / QA |
| EMP-006 | Meena | Developer |
| EMP-007 | Vikram | Developer (inactive) |

- Projects: **ZPT** (req doc required, typed evidence off), **PORTAL** (typed evidence on)
- Tasks ZPT-101…110 (+ subtasks), PORTAL-201 across stages
- Bugs BUG-001…003 (blocking, Ready for Retest, Closed)
- Sample timesheets, leave allocations/requests, Indian public holidays, notifications

---

## 11. Tech stack

| Layer | Choice |
|-------|--------|
| Runtime | **Node.js** (`server/`) |
| Database | **PostgreSQL** + Prisma |
| Auth | JWT (email / password) |
| Files | Disk uploads via `UPLOAD_DIR` |
| API | Express — RBAC + workflow gates on the server |
| UI | `server/web` — Bootstrap 5.3, Bootstrap Icons, Roboto |

---

## 12. Run & deploy

Credentials live in the repo-root **`.env`** (see `.env.example`). Do not commit `.env`. Do not create `server/.env`.

```bash
# From repo root
cp .env.example .env          # edit DATABASE_URL, JWT_SECRET, …
npm --prefix server install
npm run migrate               # prisma migrate deploy
npm run seed                  # or: npm --prefix server run db:setup
npm run dev                   # API + UI on :4000
```

- App: http://localhost:4000  
- Health: http://localhost:4000/api/health  
- Demo Super Admin: `gowtham@zettai.demo` / `Password123!`  
- Layout contract: [docs/UI_LAYOUT.md](./docs/UI_LAYOUT.md)  
- Full deploy guide: [DEPLOY-README.md](./DEPLOY-README.md)

See **[task.md](./task.md)** for the backlog and **[.cursorrules](./.cursorrules)** for agent coding rules.

---

## 12.5 UAT Environment & CI/CD

- **UAT URL**: [https://notify-uat.zettai.in](https://notify-uat.zettai.in)
- **API Health Check**: [https://notify-uat.zettai.in/api/health](https://notify-uat.zettai.in/api/health)
- **Deployment Path**: `/var/www/html/zs-tracker`
- **Systemd Service**: `zpt.service` (Node.js on port 4000 via Apache reverse proxy)
- **Auto-Deployment**: Webhook-driven CI/CD pipeline enabled for `main` branch
- **Webhook Endpoint**: `https://notify-uat.zettai.in/webhook/deploy`
- **Deploy Script**: `/home/ubuntu/cicd/deploy_tracker.sh`

---

## 13. Related docs

- [`DEPLOY-README.md`](./DEPLOY-README.md) — deployment: Postgres, migrate, seed, production run, backups
- [`task.md`](./task.md) — build plan & checklist
- [`docs/UI_LAYOUT.md`](./docs/UI_LAYOUT.md) — UI layout contract (shell, Employees, Projects, forms)
- [`.cursorrules`](./.cursorrules) — always-on Cursor guidance
- [`.cursor/rules/zpt-requirements.mdc`](./.cursor/rules/zpt-requirements.mdc) — structured project rule

---

## License / status

Functional parity with this README and docs/UI_LAYOUT.md is the acceptance baseline.
