# HR & Payroll Software — Cumulative QA Findings
**Project:** HRPAY-BMD-20260911-01  
**Current reviewed source:** v0.39.4-dev Consolidated  
**QA register:** QA-001 to QA-095

## Current QA state

- Total findings: **95**
- P0 / Final Delivery Blockers: **18** — source/static implementation evidence present; runtime closure pending.
- P1 / Required Before Production: **35** — 33 have source-level remediation evidence; QA-011 and QA-094 remain explicit runtime/release gates.
- Historical FIXED items: **22** — runtime regression evidence still required.
- P2: **15**
- P3 / informational: **5**

**Important:** The statuses below are the current tracker statuses. They must not be interpreted as Final Runtime PASS unless runtime evidence has been attached and accepted.

## Findings register

### QA-001 — Attendance device mapping form crashes at runtime
- Priority: FIXED
- Severity: Critical
- Area: Attendance Device / Employee Mapping
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-001 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-002 — Machine punch import does not create/update daily attendance
- Priority: P0 — Final Delivery Blocker
- Severity: Critical
- Area: FO-M1 / Attendance Integration
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending physical FO-M1 + Local Django/PostgreSQL proof
- Developer action: Execute QA-002 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-003 — Half-day leave bypasses overlap and holiday/weekly-off validation
- Priority: FIXED
- Severity: High
- Area: Leave
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-003 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-004 — Salary assignment can use another company's salary structure
- Priority: FIXED
- Severity: High
- Area: Payroll / Salary Assignment
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-004 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-005 — Salary assignment effective-date overlaps are allowed
- Priority: FIXED
- Severity: High
- Area: Payroll / Salary Assignment History
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-005 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-006 — Salary Structure is not actually driving payroll calculation
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Design Gap
- Area: Dynamic Payroll Configuration
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-006 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-007 — Payroll policy values are hard-coded
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Maintainability
- Area: Payroll Policy
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-007 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-008 — Dynamic employee custom fields are not wired to Employee UI
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Maintainability
- Area: Employee Master
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-008 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-009 — Data Import/Migration screen is not an import engine
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / UAT Gap
- Area: Migration Center
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-009 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-010 — Management Notice feature is model/admin-only
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / UAT Gap
- Area: HR Requests & Notices
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-010 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-011 — Django migrations are not shipped/frozen
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Release Engineering
- Area: Database / Maintainability
- Current status: Migration freeze protocol/tooling implemented; frozen migration files pending generation in real Django runtime
- Developer action: Run 00-FREEZE-MIGRATIONS-WINDOWS.bat on exact reviewed source, return generated migration files + MIGRATION-FREEZE-RESULT.txt, then require clean makemigrations --check and fresh DB migrate.

### QA-012 — Salary/leave master dropdown labels are not user-friendly
- Priority: FIXED
- Severity: Medium / Usability
- Area: Salary Structure and Leave Type
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-012 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-013 — Attendance Device allows cross-company branch selection
- Priority: FIXED
- Severity: High / Data Integrity
- Area: Attendance Device Master
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-013 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-014 — Several designed models are currently unused in normal application flow
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Design Completion
- Area: Not separately specified
- Current status: Implemented Update1; QA-014 model-flow static audit PASS; local runtime proof pending
- Developer action: Verify payroll adjustment UI, employee docs/custom fields, import errors and notice recipients in Local Django/PostgreSQL UAT.

### QA-015 — Branding/company identity is hard-coded in templates
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Maintainability
- Area: Base UI / Dashboard
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-015 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-016 — Documentation version mismatch
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Handover Quality
- Area: Not separately specified
- Current status: Closed at source/documentation level — current manuals, runtime scripts, preview labels and package metadata aligned to v0.39.4-dev Consolidated; DOCX render/PDF visual QA completed.
- Developer action: No runtime dependency. Re-open only if source/package/document versions diverge in a later patch.

### QA-017 — Automated test coverage is too small for final acceptance
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / QA Risk
- Area: Not separately specified
- Current status: Automated regression suite expanded; source/static evidence PASS; local test execution pending
- Developer action: Run manage.py test tests plus smoke tests on frozen-migration fresh UAT DB and attach result log.

### QA-018 — Mid-month joining is not prorated in payroll
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Payroll Accuracy
- Area: Payroll Build
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-018 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-019 — Mid-month salary change is applied as one salary for the entire month
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Payroll Accuracy
- Area: Salary History / Payroll
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-019 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-020 — Missing attendance days do not become absences
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Payroll Accuracy
- Area: Attendance -> Payroll
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-020 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-021 — Unpaid leave and absence can be double-deducted
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Payroll Accuracy
- Area: Leave + Attendance Integration
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-021 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-022 — Attendance metrics do not subtract configured shift break time
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Attendance Accuracy
- Area: Shift / Attendance
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-022 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-023 — Returned leave/attendance requests have no usable resubmission flow
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Workflow Completion
- Area: Workflow
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-023 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-024 — Employee master lacks basic date/business validation
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Data Integrity
- Area: Employee Master
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-024 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-025 — Salary assignment can start before employee joining date
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Data Integrity
- Area: Salary Assignment
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-025 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-026 — Company-wide Holiday uniqueness is not reliable with nullable branch
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Data Integrity
- Area: Holiday Master
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-026 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-027 — Attendance correction request attribution can be inaccurate
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Audit Integrity
- Area: Attendance Adjustment
- Current status: Implemented in v0.38.0-UAT Update 1; actual requester user/employee is stored and self-service attribution is derived; static evidence PASS; Local runtime proof pending.
- Developer action: Execute QA-027 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv; verify employee-vs-manager attribution, requester notification and original-requester-only resubmission before marking Closed.

### QA-028 — Payroll calculation lacks a single day-level attendance/leave service ledger
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Architecture
- Area: Payroll Maintainability
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-028 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-029 — Final settlement uses the latest locked payroll, not the actual exit-period payable salary
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Financial Accuracy
- Area: Exit & Final Settlement
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-029 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-030 — Final working day is never finalized or used by the exit workflow
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Exit Process Integrity
- Area: Resignation / Exit
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-030 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-031 — Loan outstanding is deducted in final settlement but the loan ledger is not settled/closed on payment
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Financial Ledger Integrity
- Area: Exit + Loan Integration
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-031 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-032 — Exit case can complete without an authoritative exit date on the employee master
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Data Integrity
- Area: Employee Lifecycle
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-032 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-033 — Final settlement monetary inputs accept negative values and net payable can become negative without an explicit policy
- Priority: FIXED / RUNTIME PENDING
- Severity: High / Financial Validation
- Area: Final Settlement
- Current status: Consolidated Master now rejects negative manual monetary inputs and also blocks submission when calculated net payable is negative. A negative balance must be reconciled through a separate approved recovery/receivable process rather than being posted as a payable settlement. Runtime regression test is still required.
- Consolidated action: Verify positive/zero settlement cases and a negative-net case in Local Django/PostgreSQL UAT before formal closure.

### QA-034 — Loan sanction can exceed the employee's requested amount
- Priority: FIXED
- Severity: High / Approval Control
- Area: Loan / Salary Advance
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-034 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-035 — Loan recovery start month is not validated against disbursement timing
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Loan Recovery
- Area: Loan / Payroll
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-035 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-036 — Payroll can consume non-finalized attendance records
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Payroll Control
- Area: Attendance -> Payroll
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-036 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-037 — Multi-company access is not company-scoped for privileged roles
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Authorization & Data Segregation
- Area: Security / Roles / Reports / Payroll
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-037 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-038 — Payroll workflow does not enforce segregation of duties
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Approval Governance
- Area: Payroll Workflow
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-038 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-039 — Returned final-settlement approval resets the settlement to Draft but provides no clean resubmission lifecycle
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Workflow Completion
- Area: Final Settlement Workflow
- Current status: Implemented explicit Submitted/Returned/Rejected settlement lifecycle with reviewer note and resubmission count in v0.38.0-UAT Update 1; static evidence PASS; Local workflow proof pending
- Developer action: Execute QA-039 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-040 — Reports are operational exports only; key final-delivery HR/payroll reports are absent
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Functional Completeness
- Area: Reports
- Current status: Implemented core blueprint/business report set in v0.38.0-UAT Update 1; static evidence PASS; final report acceptance list + Local Django/PostgreSQL export proof pending
- Developer action: Execute QA-040 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-041 — Report/PDF rendering is not fully Unicode/Bangla-safe
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Output Quality
- Area: Payslip PDF
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-041 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-042 — Payroll/bonus/deduction month fields accept arbitrary dates instead of canonical month values
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Data Consistency
- Area: Payroll Inputs
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-042 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-043 — Resignation date validation is incomplete
- Priority: FIXED
- Severity: Medium / Data Integrity
- Area: Resignation Application
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-043 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-044 — Salary effective date can precede joining date
- Priority: FIXED
- Severity: High / Data Integrity
- Area: Salary Assignment
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-044 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-045 — Detailed backend runtime/status endpoint was publicly accessible
- Priority: FIXED
- Severity: High / Security Hardening
- Area: Core / Runtime Information
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-045 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-046 — Public health endpoint disclosed project reference and application version
- Priority: FIXED
- Severity: Medium / Information Disclosure
- Area: Core / Health Check
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-046 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-047 — Employee request attachment upload has no file-type allow-list
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Upload Security
- Area: Workflow / Employee Applications
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-047 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-048 — Important master-data/admin changes are not covered by the application audit trail
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Audit Completeness
- Area: Audit / Administration
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-048 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-049 — Baseline role bootstrap grants broad model add/change/delete permissions by whole app
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Authorization Governance
- Area: Roles / Django Administration
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-049 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-050 — Django Admin is not company-scoped for multi-company operation
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Data Segregation
- Area: Administration / Multi-company Security
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-050 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-051 — HR-Payroll custom User fields were not exposed in UserAdmin
- Priority: FIXED
- Severity: Medium / Maintainability
- Area: Accounts / Administration
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-051 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-052 — Login throttling is only per username + source IP
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Authentication Hardening
- Area: Login Security
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-052 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-053 — LoginAttempt records have no cleanup/retention mechanism
- Priority: P3 — Low / Informational
- Severity: Low / Operations
- Area: Authentication / Database Housekeeping
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-053 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-054 — Database backup files are stored unencrypted by the application command
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Data Protection
- Area: Backup / Payroll PII
- Current status: Implemented encrypted-at-rest backup path in v0.38.0-UAT Update 1; static evidence PASS; OpenSSL + PostgreSQL backup/verify/restore proof pending Local UAT
- Developer action: Execute QA-054 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-055 — Backup verification treats SHA-256 sidecar as optional
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Restore Integrity
- Area: Backup / Restore
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-055 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-056 — Business AuditLog is protected from add/delete in Django Admin (verified positive control)
- Priority: P3 — Low / Informational
- Severity: Informational / Control Verified
- Area: Audit
- Current status: Verified positive control in source/static review; no remediation change required; retain as regression assertion
- Developer action: Reconfirm during Local runtime regression and retain result in UAT evidence.

### QA-057 — Template named-URL wiring check found no broken named links
- Priority: P3 — Low / Informational
- Severity: Informational / UI Wiring Verified
- Area: Templates / Navigation
- Current status: Verified positive control in source/static review; no remediation change required; retain as regression assertion
- Developer action: Reconfirm during Local runtime regression and retain result in UAT evidence.

### QA-058 — Reporting hierarchy can contain indirect circular manager loops
- Priority: FIXED
- Severity: High / Data Integrity
- Area: Employee Master / Organization Hierarchy
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-058 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-059 — Leave Balance can combine an employee and leave type from different companies
- Priority: FIXED
- Severity: Critical / Multi-company Data Integrity
- Area: Leave Master / Balance
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-059 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-060 — Leave balance core quantity fields accept invalid negative values
- Priority: FIXED
- Severity: High / Data Integrity
- Area: Leave Balance
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-060 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-061 — Leave yearly allocation/carry-forward settings have no automated lifecycle engine
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Business Logic Completeness
- Area: Leave Policy / Year Opening
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-061 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-062 — Approved leave is not reconciled into daily AttendanceRecord status
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Leave-Attendance Integration
- Area: Leave / Attendance / Payroll
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-062 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-063 — No approved-leave cancellation/reversal flow refunds consumed balance
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Transaction Reversal
- Area: Leave Lifecycle
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-063 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-064 — Attendance `finalized` flag has no operational finalization workflow
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Control Design
- Area: Attendance Close
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-064 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-065 — Normal HR attendance edit bypasses finalized-state protection
- Priority: FIXED
- Severity: Critical / Data Integrity
- Area: Attendance Editing
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-065 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-066 — Attendance form does not validate employee service-date/status coherence
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Data Integrity
- Area: Attendance Entry
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-066 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-067 — Attendance status can conflict with entered timestamps
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Data Quality
- Area: Attendance Entry
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-067 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-068 — Payroll can still be rebuilt/recalculated after it reaches APPROVED state
- Priority: FIXED
- Severity: Critical / Payroll Control
- Area: Payroll Approval / Lock
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-068 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-069 — Employee status can be changed directly without synchronized lifecycle transaction
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Employee Lifecycle
- Area: Employee Master / Exit
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-069 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-070 — Employee document upload has no file-type allow-list
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Upload Security
- Area: Employee Documents
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-070 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-071 — Employee date validation was incomplete
- Priority: FIXED
- Severity: High / Data Integrity
- Area: Employee Master
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-071 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-072 — PayrollLineItem is never generated by payroll calculation
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Output Accuracy / Design Completion
- Area: Payroll / Payslip
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-072 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-073 — PayrollAdjustment records are not consumed by payroll calculation or payslip/report output
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Payroll Completeness
- Area: Payroll Adjustments
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-073 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-074 — Payroll calculation snapshot is insufficient to reproduce/audit a historical payroll result
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Audit & Reconciliation
- Area: Payroll Snapshot
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-074 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-075 — Payslip PDF uses a non-Unicode standard font and is unsafe for Bangla output
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Output Rendering
- Area: Payslip PDF
- Current status: Implemented Unicode/Bangla-capable ReportLab font discovery + shaping in v0.38.0-UAT Update 1; static evidence PASS; visual PDF proof pending Local UAT font environment
- Developer action: Execute QA-075 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-076 — CSV exports were vulnerable to spreadsheet formula injection
- Priority: FIXED
- Severity: High / Export Security
- Area: Reports / CSV
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-076 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-077 — No payroll bank/payment master data or Bank Advice/transfer export exists
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Functional Completeness
- Area: Payroll Payment Output
- Current status: Implemented secured/masked salary payment master + locked-payroll Bank Advice export in v0.38.0-UAT Update 1; static evidence PASS; Local DB/payment export proof pending
- Developer action: Execute QA-077 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-078 — Leave date-range CSV reports the full leave-request day count, not days within the selected report window
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Report Accuracy
- Area: Leave Report
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-078 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-079 — Report exports inherit the unresolved multi-company authorization/scoping gap
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Data Segregation
- Area: Reports
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-079 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-080 — Payslip/report output lacks payroll-day explanation needed for salary dispute reconciliation
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Usability / Auditability
- Area: Payslip / Payroll Report
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-080 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-081 — Browser review and real backend are intentionally separate, but demo capability substantially exceeds backend capability
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Acceptance Risk
- Area: OPEN-ME.html vs Django backend
- Current status: Explicit Demo-to-Backend parity matrix added; static evidence PASS; runtime evidence pending
- Developer action: Use DEMO-BACKEND-PARITY-MATRIX.csv during UAT; required Implemented items need backend test evidence; Demo Only items cannot count as acceptance proof.

### QA-082 — System Configuration Center is demo-only; core policies are not backed by a persistent configuration model/UI
- Priority: P0 — Final Delivery Blocker
- Severity: Critical / Maintainability
- Area: Dynamic Configuration
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-082 in P0-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-083 — Employee Custom Fields are visible in demo but unavailable in normal employee business workflow
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Maintainability / Functional Parity
- Area: Employee Master
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-083 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-084 — Employee documents exist in the data model but have no normal employee UI workflow
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Functional Completeness
- Area: Employee Documents
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-084 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-085 — Organization masters are maintained only through raw Django Admin, not a purpose-built HR configuration UI
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Usability / Maintainability
- Area: Company / Branch / Department / Designation / Shift / Holiday
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-085 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-086 — Main application branding is hard-coded instead of using Company master
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Multi-company / Maintainability
- Area: Base UI
- Current status: Implemented in v0.38.0-UAT Update 1; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof
- Developer action: Execute QA-086 in P1-RUNTIME-VERIFICATION-CHECKLIST.csv and attach evidence before marking Closed.

### QA-087 — Navigation is not role-aware and exposes inaccessible modules to ordinary users
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / UX / Authorization Clarity
- Area: Main Navigation
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-087 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-088 — Top bar does not show the user's actual role(s)
- Priority: P3 — Low / Informational
- Severity: Low / Usability
- Area: Identity / Role Awareness
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-088 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-089 — Employee list was unbounded and lacked pagination
- Priority: FIXED
- Severity: Medium / Performance / Usability
- Area: Employee Master
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-089 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-090 — Employee dependent dropdowns were not filtered by selected company in the form UI
- Priority: FIXED
- Severity: Medium / Data-entry Usability
- Area: Employee Form
- Current status: Fixed in corrected copy; runtime regression test still required
- Developer action: Execute QA-090 in FIXED-ITEMS-RUNTIME-REGRESSION-CHECKLIST.csv and attach runtime evidence before formal closure.

### QA-091 — No first-class employee document/custom-field visibility on Employee Detail creates an incomplete personnel profile
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Operational Usability
- Area: Employee Detail
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-091 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-092 — Core list screens use hard row caps without pagination or an explicit “results limited” warning
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Data Visibility
- Area: Attendance / Leave / Payroll Inputs / Exit
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-092 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-093 — Destructive/deactivation lifecycle is not available as a controlled business workflow
- Priority: P2 — Next Release / Controlled Improvement
- Severity: Medium / Data Lifecycle
- Area: Employee / Masters
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-093 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.

### QA-094 — Browser review contains its own demo backup/restore and migration experiences that must not be accepted as production proof
- Priority: P1 — Go-Live Blocker / Required Before Production
- Severity: High / Acceptance Control
- Area: UAT / Go-Live
- Current status: Runtime acceptance gate remains open
- Developer action: Attach isolated PostgreSQL backup file/checksum, verify log, restore log, restored control totals, migration log and recovery procedure before final sign-off.

### QA-095 — No JavaScript/AJAX dependent-master behavior exists on the backend employee form
- Priority: P3 — Low / Informational
- Severity: Low / UX
- Area: Employee Form
- Current status: Implemented in v0.38.0-UAT Update 1 working tree; static evidence PASS; formal closure pending Local Django/PostgreSQL UAT proof where applicable
- Developer action: Execute QA-095 in P2-RUNTIME-VERIFICATION-CHECKLIST.csv where listed; retain evidence before marking Closed.


## Consolidation Development Findings — QA-096 to QA-098

### QA-096 — High — Unified half-day leave bypassed weekly-off/holiday validation
**Confirmed in developer Update 1:** `EmployeeRequestForm._clean_leave()` validated working days only for full-day leave. Half-day leave could be submitted on the employee weekly holiday or an active company/branch Holiday.

**Consolidated Master correction:** Half-day requests now reject weekly-off and declared-holiday dates before assigning 0.50 day.

**Status:** SOURCE FIXED — compile/static verification passed; Django runtime regression test remains required.

### QA-097 — High — Missing attendance day could not enter the correction/approval workflow
**Confirmed in developer Update 1:** Unified attendance correction rejected a date when no `AttendanceRecord` existed. This prevented an employee from requesting correction for a genuine missing day/missing roll-up.

**Consolidated Master correction:** The form now accepts an in-service date without an existing record. Submission uses `create_missing_attendance_adjustment_request()`, which first invokes the authoritative day reconciliation service to create the policy-consistent placeholder AttendanceRecord/AttendanceDayLedger, then creates the normal approval request. Requested values are applied only after approval.

**Status:** SOURCE FIXED — compile/static verification passed; Django/PostgreSQL workflow test remains required.

### QA-098 — High — Unified attendance correction could not intentionally clear an incorrect punch
**Confirmed in developer Update 1:** The submission view used `corrected_value or existing_value`, so a blank corrected check-in/check-out silently restored the old value.

**Consolidated Master correction:** Unified submission now passes explicit blank values through as `None`; the existing adjustment approval service already applies `None` as a cleared timestamp. Status-specific validation was also aligned with the dedicated attendance adjustment form.

**Status:** SOURCE FIXED — compile/static verification passed; Django runtime regression test remains required.


## Consolidated Development Finding — 2026-09-16

### QA-099 — Exit loan settlement could close a loan when outstanding balance and unpaid installment ledger disagree
- Priority: FIXED / RUNTIME PENDING
- Severity: High / Financial Ledger Integrity
- Area: Loans / Final Settlement
- Finding: `settle_employee_loans_via_exit()` used the LoanAccount outstanding balance as the settlement recovery amount, allocated against available installments, and then closed the loan without first proving that unpaid installments reconciled exactly to the outstanding balance. Corrupt/imported/inconsistent loan data could therefore be silently closed with a ledger mismatch.
- Consolidated correction: The exit settlement now locks the installment rows, calculates total unpaid installment balance, requires exact reconciliation with LoanAccount.outstanding_balance, and blocks posting with ValidationError if the ledger is inconsistent.
- Runtime requirement: Test a reconciled active loan (must close) and an intentionally mismatched loan ledger (must block settlement and leave balances unchanged).
