# Employee Entry Date Implementation Plan

> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Add an `entryDate` field to Employee, automatically populated from `contractStartDate` at creation.

**Architecture:** New nullable `DATE` column on `employees` table. The `EmployeeWriteProcessor` sets `entryDate` from the first contract period's start date during employee creation. Exposed read-only in the API. No fallback needed — existing employees will be updated manually in prod DB.

**Tech Stack:** Symfony/Doctrine (backend), Nuxt/Vue/TypeScript (frontend)

---

## File Structure

| File | Action | Responsibility |
|------|--------|----------------|
| `src/Entity/Employee.php` | Modify | Add `entryDate` column + getter/setter, expose in `employee:read` |
| `src/State/EmployeeWriteProcessor.php` | Modify | Set `entryDate` from `contractStartDate` on creation |
| `migrations/Version20260312120000.php` | Create | Add `entry_date` column to `employees` table |
| `tests/State/EmployeeWriteProcessorTest.php` | Modify | Assert `entryDate` is set on new employee |
| `frontend/services/dto/employee.ts` | Modify | Add `entryDate` field to `Employee` type |
| `frontend/pages/employees/index.vue` | Modify | Display entry date in employee list |

---

## Chunk 1: Backend

### Task 1: Migration

**Files:**
- Create: `migrations/Version20260312120000.php`

- [ ] **Step 1: Create the migration file**

```php
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20260312120000 extends AbstractMigration
{
    public function getDescription(): string
    {
        return 'Add entry_date column to employees table';
    }

    public function up(Schema $schema): void
    {
        $this->addSql('ALTER TABLE employees ADD entry_date DATE DEFAULT NULL COMMENT \'(DC2Type:date_immutable)\'');
    }

    public function down(Schema $schema): void
    {
        $this->addSql('ALTER TABLE employees DROP entry_date');
    }
}
```

- [ ] **Step 2: Run migration**

Run: `php bin/console doctrine:migrations:migrate --no-interaction`
Expected: Migration applied successfully

- [ ] **Step 3: Commit**

```bash
git add migrations/Version20260312120000.php
git commit -m "feat : ajout colonne entry_date sur employees"
```

---

### Task 2: Entity — add `entryDate` property

**Files:**
- Modify: `src/Entity/Employee.php:56-61` (insert after `displayOrder`)

- [ ] **Step 1: Add the column, getter, and setter to Employee entity**

Add after the `displayOrder` property (line 58):

```php
#[ORM\Column(type: 'date_immutable', nullable: true)]
#[Groups(['employee:read'])]
private ?\DateTimeImmutable $entryDate = null;
```

Add getter and setter after `setDisplayOrder()` (after line 167):

```php
public function getEntryDate(): ?\DateTimeImmutable
{
    return $this->entryDate;
}

public function setEntryDate(?\DateTimeImmutable $entryDate): self
{
    $this->entryDate = $entryDate;

    return $this;
}
```

- [ ] **Step 2: Verify schema is in sync**

Run: `php bin/console doctrine:schema:validate`
Expected: OK (or only existing unrelated warnings)

- [ ] **Step 3: Commit**

```bash
git add src/Entity/Employee.php
git commit -m "feat : ajout propriete entryDate sur Employee"
```

---

### Task 3: Set `entryDate` on employee creation

**Files:**
- Modify: `src/State/EmployeeWriteProcessor.php:60-71`
- Modify: `tests/State/EmployeeWriteProcessorTest.php`

- [ ] **Step 1: Write the failing test**

Add `use ApiPlatform\Metadata\Post;` to the imports at the top of the test file (alongside the existing `Delete` and `Patch` imports).

Then add this test method to `EmployeeWriteProcessorTest`:

```php
public function testSetsEntryDateOnNewEmployee(): void
{
    $employee = new Employee();
    $employee->setFirstName('Jane');
    $employee->setLastName('Doe');
    $employee->setContractStartDate('2026-04-01');
    $employee->setContractNature('CDI');

    $contract = new Contract()
        ->setName('35h')
        ->setTrackingMode(Contract::TRACKING_TIME)
        ->setWeeklyHours(35);
    $employee->setContract($contract);

    $persistProcessor     = $this->createMock(ProcessorInterface::class);
    $removeProcessor      = $this->createStub(ProcessorInterface::class);
    $entityManager        = $this->createStub(EntityManagerInterface::class);
    $periodRepository     = $this->createStub(EmployeeContractPeriodReadRepositoryInterface::class);
    $changeRequestFactory = new EmployeeContractChangeRequestFactory();
    $periodManager        = $this->createMock(EmployeeContractPeriodManagerInterface::class);

    $persistProcessor
        ->expects(self::once())
        ->method('process')
        ->willReturn($employee);

    $periodManager
        ->expects(self::once())
        ->method('ensureContractPeriodExists');

    $processor = new EmployeeWriteProcessor(
        $persistProcessor,
        $removeProcessor,
        $entityManager,
        $periodRepository,
        $changeRequestFactory,
        $periodManager
    );

    $processor->process($employee, new Post());

    self::assertNotNull($employee->getEntryDate());
    self::assertSame('2026-04-01', $employee->getEntryDate()->format('Y-m-d'));
}
```

- [ ] **Step 2: Run test to verify it fails**

Run: `php bin/phpunit tests/State/EmployeeWriteProcessorTest.php --filter=testSetsEntryDateOnNewEmployee`
Expected: FAIL — `entryDate` is null

- [ ] **Step 3: Implement — set entryDate in EmployeeWriteProcessor**

In `src/State/EmployeeWriteProcessor.php`, inside the `if ($isNew)` block (line 60-71), add **before** `return $result;` (line 71):

```php
$data->setEntryDate($startDate);
```

The full block becomes:

```php
if ($isNew) {
    $startDate = $changeRequest->contractStartDate ?? new DateTimeImmutable('1970-01-01');
    $nature    = $changeRequest->contractNature ?? ContractNature::CDI;
    $this->periodManager->ensureContractPeriodExists(
        employee: $data,
        contract: $currentContract,
        startDate: $startDate,
        endDate: $changeRequest->contractEndDate,
        nature: $nature
    );

    $data->setEntryDate($startDate);

    return $result;
}
```

- [ ] **Step 4: Run test to verify it passes**

Run: `php bin/phpunit tests/State/EmployeeWriteProcessorTest.php --filter=testSetsEntryDateOnNewEmployee`
Expected: PASS

- [ ] **Step 5: Run all EmployeeWriteProcessor tests**

Run: `php bin/phpunit tests/State/EmployeeWriteProcessorTest.php`
Expected: All tests pass (no regression)

- [ ] **Step 6: Commit**

```bash
git add src/State/EmployeeWriteProcessor.php tests/State/EmployeeWriteProcessorTest.php
git commit -m "feat : remplissage automatique entryDate a la creation employe"
```

---

## Chunk 2: Frontend

### Task 4: Update frontend DTO and display entry date

**Files:**
- Modify: `frontend/services/dto/employee.ts:14-25`
- Modify: `frontend/pages/employees/index.vue`

- [ ] **Step 1: Add `entryDate` to the Employee DTO**

In `frontend/services/dto/employee.ts:24`, add `entryDate` after `displayOrder`:

```typescript
  displayOrder?: number
  entryDate?: string | null
```

- [ ] **Step 2: Display entry date in the employee card hover overlay**

In `frontend/pages/employees/index.vue`, inside the hover overlay `<div>` (line 49-54), add a new line after the "Site" line (after line 53):

```vue
<p><strong>Entree :</strong> {{ employee.entryDate ? employee.entryDate.split('-').reverse().join('/') : '-' }}</p>
```

This uses string splitting instead of `new Date()` to avoid timezone parsing issues with date-only strings.

- [ ] **Step 3: Verify in browser**

1. Check the API response for an employee: `GET /api/employees` should include `entryDate` field (confirms backend `employee:read` group works)
2. Open the employee list page, hover over a card — entry date should appear in the overlay
3. Create a new employee, verify the entry date shows the contract start date
4. Existing employees without entry date should show "-"

- [ ] **Step 4: Commit**

```bash
git add frontend/services/dto/employee.ts frontend/pages/employees/index.vue
git commit -m "feat : affichage date d'entree dans la liste employes"
```
