# 🎯 Resident API - Thay Đổi & Hướng Dùng

## ✨ Những Thay Đổi

### 1. Database (Migration 010)

```sql
ALTER TABLE residents ADD COLUMN nationality VARCHAR(100);
ALTER TABLE residents ADD COLUMN job VARCHAR(255);
```

### 2. API Fields Mới

- `nationality` - Quốc tịch (optional, max 100 chars)
- `job` - Nghề nghiệp (optional, max 255 chars)

### 3. Multiple Beds Support

- **Old**: `bed_id` (single UUID) → gắn 1 giường
- **New**: `bed_ids` (array of UUIDs) → gắn nhiều giường

**Backend tự động**:

- Tạo 1 `residents` record
- Tạo N `resident_stays` records (một cho mỗi bed_id)

---

## 🚀 Cách Dùng - API

### Create Resident

```bash
POST /api/v1/residents
```

**Request Body**:

```json
{
	"full_name": "Nguyễn Văn A",
	"email": "a@example.com",
	"phone": "+84 901 234 567",
	"id_card": "001234567890",
	"date_of_birth": "1990-05-15",
	"nationality": "Việt Nam",
	"job": "Kỹ sư phần mềm",
	"emergency_contact_name": "Nguyễn Thị B",
	"emergency_contact_phone": "+84 902 345 678",
	"emergency_contact_relationship": "Vợ",
	"bed_ids": ["uuid-1", "uuid-2", "uuid-3"],
	"move_in_at": "2024-01-15T08:30:00Z"
}
```

**Response (201 Created)**:

```json
{
	"success": true,
	"responseData": {
		"id": "resident-uuid",
		"full_name": "Nguyễn Văn A",
		"nationality": "Việt Nam",
		"job": "Kỹ sư phần mềm",
		"email": "a@example.com",
		"status": "active"
	}
}
```

---

## 📋 Fields Detail

| Field                            | Type     | Required | Max | Notes               |
| -------------------------------- | -------- | -------- | --- | ------------------- |
| `full_name`                      | string   | ✅       | 200 | Tên cư dân          |
| `email`                          | email    | ❌       | 255 | Email address       |
| `phone`                          | string   | ❌       | 25  | Số điện thoại       |
| `id_card`                        | string   | ❌       | 50  | CCCD/Passport       |
| `date_of_birth`                  | date     | ❌       | -   | YYYY-MM-DD          |
| `nationality`                    | string   | ❌       | 100 | **NEW**             |
| `job`                            | string   | ❌       | 255 | **NEW**             |
| `emergency_contact_name`         | string   | ❌       | 200 | Tên liên hệ         |
| `emergency_contact_phone`        | string   | ❌       | 25  | SĐT liên hệ         |
| `emergency_contact_relationship` | string   | ❌       | 100 | Quan hệ (Vợ, Bố...) |
| `status`                         | enum     | ❌       | -   | active \| inactive  |
| `bed_ids`                        | UUID[]   | ✅       | -   | **CHANGED** - Array |
| `move_in_at`                     | datetime | ✅       | -   | ISO 8601 format     |

---

## 💡 Frontend - Quick Start

### 1. Form Fields

```jsx
<input placeholder="Nguyễn Văn A" />           {/* full_name */}
<input type="email" />                          {/* email */}
<input placeholder="+84 901 234 567" />        {/* phone */}
<input placeholder="001234567890" />           {/* id_card */}
<input type="date" />                           {/* date_of_birth */}
<input placeholder="Việt Nam" />               {/* nationality - NEW */}
<input placeholder="Kỹ sư phần mềm" />         {/* job - NEW */}
<input placeholder="Nguyễn Thị B" />           {/* emergency_contact_name */}
<input placeholder="+84 902 345 678" />        {/* emergency_contact_phone */}
<select>Vợ, Chồng, Bố, Mẹ...</select>         {/* emergency_contact_relationship */}
```

### 2. Multiple Beds Selection

```jsx
{
	/* OLD: Single select */
}
<select name="bed_id">
	<option value="uuid-1">Tòa A - Căn 101</option>
	<option value="uuid-2">Tòa A - Căn 102</option>
</select>;

{
	/* NEW: Multiple checkboxes */
}
<div>
	<label>
		<input type="checkbox" value="uuid-1" /> Tòa A - Căn 101
	</label>
	<label>
		<input type="checkbox" value="uuid-2" /> Tòa A - Căn 102
	</label>
	<label>
		<input type="checkbox" value="uuid-3" /> Tòa B - Căn 201
	</label>
</div>;

{
	/* Collect checked: */
}
const bed_ids = document.querySelectorAll('input[type="checkbox"]:checked').map((el) => el.value);
```

### 3. Send Request

```javascript
const response = await fetch('/api/v1/residents', {
	method: 'POST',
	headers: {
		'Content-Type': 'application/json',
		Authorization: `Bearer ${token}`,
	},
	body: JSON.stringify({
		full_name: 'Nguyễn Văn A',
		nationality: 'Việt Nam',
		job: 'Kỹ sư phần mềm',
		bed_ids: ['uuid-1', 'uuid-2', 'uuid-3'], // ARRAY
		move_in_at: '2024-01-15T08:30:00Z',
	}),
});

const { responseData } = await response.json();
console.log(`Created: ${responseData.id}`);
```

---

## 📝 Update Resident

```bash
PUT /api/v1/residents/{id}
```

**Cập nhật Nationality & Job**:

```json
{
	"nationality": "Việt Nam",
	"job": "Bác sĩ"
}
```

---

## 📊 Get List & Detail

### List Residents

```bash
GET /api/v1/residents
```

Response bao gồm: `id`, `full_name`, `nationality`, `job`, `status`, `residence`

### Get Single Resident

```bash
GET /api/v1/residents/{id}
```

---

## ❌ Error Handling

**Validation Error (400)**:

```json
{
	"success": false,
	"errors": [
		{
			"field": "full_name",
			"messages": { "vi": "Tên cư dân không được trống" }
		}
	]
}
```

**Common Errors**:

- `full_name` trống → 400 Bad Request
- `bed_ids` trống → 400 Bad Request
- `bed_ids` invalid → 400 Bad Request
- Email trùng → 400 Duplicate
- Giường đang có người ở → 409 Conflict

---

## ✅ Testing Quick Cases

### ✅ Valid Request

```bash
curl -X POST http://localhost:3001/api/v1/residents \
  -H "Content-Type: application/json" \
  -d '{
    "full_name": "Nguyễn Văn A",
    "nationality": "Việt Nam",
    "job": "Kỹ sư",
    "bed_ids": ["uuid-1", "uuid-2"],
    "move_in_at": "2024-01-15T08:30:00Z"
  }'
```

### ❌ Missing full_name

```bash
curl -X POST http://localhost:3001/api/v1/residents \
  -H "Content-Type: application/json" \
  -d '{
    "bed_ids": ["uuid-1"],
    "move_in_at": "2024-01-15T08:30:00Z"
  }'
# → 400 Bad Request
```

### ❌ Empty bed_ids

```bash
curl -X POST http://localhost:3001/api/v1/residents \
  -H "Content-Type: application/json" \
  -d '{
    "full_name": "Nguyễn Văn B",
    "bed_ids": [],
    "move_in_at": "2024-01-15T08:30:00Z"
  }'
# → 400 Bad Request
```

---

## 📚 Summary

| Before                  | After                      |
| ----------------------- | -------------------------- |
| `bed_id` (1 giường)     | `bed_ids[]` (nhiều giường) |
| Không có quốc tịch      | Có `nationality` field     |
| Không có nghề           | Có `job` field             |
| Tạo 1 resident → 1 stay | Tạo 1 resident → N stays   |

**Migration**: 010-add-nationality-job-to-residents.sql ✅  
**Docs**: See [docs/](docs/) folder

---

**Date**: 2026-05-12  
**API Version**: v1  
**Status**: Ready ✅
