# HR collections – review and suggested tweaks

Your three collections align well with the architecture. Below are small clarifications and one extra collection to consider.

---

## 1. `working_hours`

```text
{ _id, adminId, date, startTime, endTime, totalHours, createdAt, updatedAt, lastEditedAt }
```

**Good:** Matches “from/to times or set number of hours”; one row per employee per day; audit-style timestamps.

**Suggestions:**

- **`lastEditedAt` vs `updatedAt`**  
  Both track “when this record changed.” You can:
  - **Option A:** Keep only **`updatedAt`** and use it for “last modified” (simpler).
  - **Option B:** Keep both only if you need to distinguish “last time a **user** edited” from “last time anything changed” (e.g. system job). Otherwise one is enough.

- **Optional: allow “hours only”**  
  Scope says employees can either enter from/to **or** set hours. So:
  - When they set only hours: allow **`startTime`** and **`endTime`** to be null and store **`totalHours`**.
  - When they set from/to: **`totalHours`** can be derived on read (or stored for convenience). So either:
    - make `startTime`/`endTime` optional and always store `totalHours`, or
    - keep all three and in app logic: if only hours given, leave start/end null and set totalHours.

- **Optional: timezone**  
  If employees are in different timezones, consider storing times in UTC or adding a `timezone` (or storing `date` as a proper date type so “day” is unambiguous). Not required for a first version.

**Verdict:** Structure is fine; simplify to **`updatedAt`** unless you explicitly need **`lastEditedAt`** for “user edit only.”

---

## 2. `holidays` (holiday requests)

```text
{ _id, adminId, startDate, endDate, comment, status, rejectedReason, approvedBy, createdAt }
```

**Good:** Covers requester, dates, comment, status, rejection reason, and who approved/rejected.

**Suggestions:**

- **`updatedAt`**  
  Add **`updatedAt`** and set it when the request is created and whenever it’s updated (e.g. when a manager approves/rejects). Useful for “when was this decided?” and sorting/filtering.

- **`approvedBy`**  
  Keep as-is: it’s the admin (manager) who approved or rejected. Fits “mandatory rejection reason” and “retained for reporting.”

- **Optional: `decidedAt`**  
  If you want an explicit “decision timestamp” separate from `updatedAt`, add **`decidedAt`** and set it only when status becomes approved/rejected. Otherwise `updatedAt` is enough.

**Suggested shape:**

```text
{
  _id,
  adminId,           // employee who requested
  startDate,
  endDate,
  comment,           // optional
  status,            // pending | approved | rejected
  rejectedReason,    // required when status === 'rejected'
  approvedBy,        // adminId of manager (null until decided)
  createdAt,
  updatedAt          // add this
}
```

**Verdict:** Add **`updatedAt`**; rest is good.

---

## 3. `public_holidays`

```text
{ _id, name, date }
```

**Good:** Simple and matches “configurable by Manager” and “Public holiday calendar.”

**Clarification:**

- **`date`**  
  Store as a **date** (e.g. ISO date `YYYY-MM-DD` or Date type). One document per occurrence (e.g. “Christmas 2025” = 2025-12-25, “Christmas 2026” = 2026-12-25). That way you can have different names per year and no “recurring rule” logic.

**Optional:**

- **`year`**  
  If you often filter by year, you can add **`year`** (number) and set it from `date` for convenience. Not required if you’re happy querying by `date` ranges.

**Verdict:** No change needed; just ensure `date` is a proper date type.

---

## 4. Missing from your list: **holiday allowance**

Architecture says: *“View annual holiday allowance, used days, and remaining balance per employee”* and *“Configure annual holiday allowances.”*

So you need something like:

**Option A – separate collection `holiday_allowances`:**

```text
{
  _id,
  adminId,           // employee
  year,              // e.g. 2026
  allowanceDays,     // total allowed (e.g. 25)
  usedDays,          // derived from approved holidays in that year, or stored
  createdAt,
  updatedAt
}
```

**Option B – one document per employee per year with the same fields.**  
Used days can be computed from approved **`holidays`** for that `adminId` and year, or cached in this collection and updated when a request is approved/rejected.

**Suggestion:** Add a small **`holiday_allowances`** (or similar) collection with at least **`adminId`**, **`year`**, **`allowanceDays`**, and optionally **`usedDays`** (and timestamps). Managers configure **allowanceDays**; **usedDays** can be derived or stored.

---

## Summary

| Collection         | Your shape | Suggested change |
|--------------------|------------|-------------------|
| **working_hours**  | OK         | Prefer one of `updatedAt` or `lastEditedAt`; allow null `startTime`/`endTime` when only hours are set. |
| **holidays**       | OK         | Add **`updatedAt`**. |
| **public_holidays**| OK         | Keep; ensure `date` is a date type. |
| **holiday_allowances** | (new) | Add for allowance/used/remaining per employee per year. |

If you want, next step can be defining Mongoose schemas (and, if needed, indexes) for these in the HR backend.
