# Webhook API Documentation

## Overview

Webhook API cho phép hệ thống đối tác gửi dữ liệu cư dân về hệ thống Bekind một cách tự động. Khi
nhận được webhook, hệ thống sẽ tự động tạo hoặc cập nhật thông tin cư dân và tài khoản người dùng
tương ứng.

## Endpoint

```
POST https://bekind-dev.meucorp.com/api/v1/webhooks/residents
```

## Authentication

Hệ thống hỗ trợ 2 cách xác thực (chọn 1 trong 2):

### Cách 1: X-Webhook-Token Header

```
X-Webhook-Token: {WEBHOOK_TOKEN}
```

### Cách 2: Authorization Bearer Header

```
Authorization: Bearer {WEBHOOK_TOKEN}
```

**Lưu ý:** Token được cấu hình trong biến môi trường `WEBHOOK_TOKEN` của hệ thống Bekind.

## Request Headers

```http
Content-Type: application/json
X-Webhook-Token: {WEBHOOK_TOKEN}
```

## Request Body

```json
{
	"event_id": "evt_123456789",
	"type": "KTX",
	"c_name": "Nguyễn Văn A",
	"c_dob": "01/01/2000",
	"c_tel": "0901234567",
	"c_sex": "Nam",
	"c_cccd": "012345678901",
	"c_add": "Đồng Nai"
}
```

### Field Descriptions

| Field      | Type   | Required | Description                                     |
| ---------- | ------ | -------- | ----------------------------------------------- |
| `event_id` | string | No       | Event ID từ hệ thống đối tác để tracking        |
| `type`     | string | Yes      | Loại khách thuê (KTX, tro, hoặc custom)         |
| `c_name`   | string | Yes      | Họ tên đầy đủ của cư dân                        |
| `c_dob`    | string | No       | Ngày sinh (format: DD/MM/YYYY)                  |
| `c_tel`    | string | No       | Số điện thoại (nếu có sẽ tự tạo tài khoản user) |
| `c_sex`    | string | No       | Giới tính (Nam/Nữ)                              |
| `c_cccd`   | string | No       | Số CCCD/CMND                                    |
| `c_add`    | string | No       | Địa chỉ                                         |

## Response

### Success Response (200 OK)

```json
{
	"success": true,
	"trace_id": null,
	"timestamp": "2026-05-27T11:53:20.458Z",
	"errors": null,
	"data": {
		"message": "Resident data processed successfully",
		"resident_id": "1b3da269-600a-45bd-a4f8-d9a36cb205ec",
		"full_name": "Nguyễn Văn A",
		"event_id": "evt_123456789"
	}
}
```

### Error Response (401 Unauthorized)

```json
{
	"success": false,
	"trace_id": "8d612b65-aa2e-44d7-baeb-dc7c287f7591",
	"timestamp": "2026-05-27T11:40:53.370Z",
	"errors": [
		{
			"field": "",
			"code": "UNAUTHORIZED",
			"messages": {
				"vi": "Bạn chưa được xác thực",
				"en": "Unauthorized"
			},
			"severity": "medium"
		}
	]
}
```

### Validation Error (400 Bad Request)

```json
{
	"success": false,
	"errors": [
		{
			"field": "c_name",
			"code": "INVALID",
			"message": "Name is required"
		}
	]
}
```

## Logic Xử Lý

### 1. Tìm kiếm cư dân tồn tại

Hệ thống tìm cư dân dựa trên:

- Số CCCD/CMND (nếu có)
- Số điện thoại (nếu có)

### 2. Tạo mới hoặc cập nhật

- **Nếu cư dân đã tồn tại**: Cập nhật thông tin
- **Nếu cư dân chưa tồn tại**: Tạo cư dân mới

### 3. Tạo tài khoản user (chỉ khi tạo mới)

Nếu cư dân mới có số điện thoại:

- Tự động tạo tài khoản user
- Email: `{phone}@bekind.com`
- Username: `{phone}`
- Password mặc định: `Bekind@123`
- Role: USER
- Link user với resident

### 4. Audit Logs

Tất cả thao tác đều được ghi log:

- `RESIDENT_CREATED` - Khi tạo cư dân mới
- `RESIDENT_UPDATED` - Khi cập nhật cư dân
- `USER_ACCOUNT_CREATED` - Khi tạo tài khoản user

## Webhook Logs Tracking

Hệ thống ghi log tất cả các webhook request vào bảng `webhook_logs` với các trạng thái:

- **PROCESSING**: Đang xử lý
- **SUCCESS**: Xử lý thành công
- **FAILED**: Xử lý thất bại

Mỗi log bao gồm:

- `event_id`: Event ID từ đối tác
- `webhook_type`: Loại webhook (ví dụ: RESIDENT_KTX)
- `payload`: Dữ liệu gốc từ request
- `response_data`: Dữ liệu response trả về
- `error_message`: Thông báo lỗi (nếu có)
- `resident_id`: ID của cư dân được tạo/cập nhật
- `ip_address`: IP của sender
- `user_agent`: User agent của sender
- `processed_at`: Thời gian xử lý xong
- `failed_at`: Thời gian thất bại

## Transaction

Toàn bộ quá trình xử lý được thực hiện trong một database transaction để đảm bảo tính toàn vẹn dữ
liệu. Nếu bất kỳ bước nào thất bại, toàn bộ thao tác sẽ được rollback.

## Direct Processing (No Worker/Queue)

Webhook được xử lý trực tiếp trong request (synchronous processing):

1. API nhận request và verify token
2. Validate body và tạo webhook_log với status PROCESSING
3. Process resident data trong transaction
4. Nếu thành công: update webhook_log SUCCESS và trả 200
5. Nếu lỗi: update webhook_log FAILED và trả lỗi rõ ràng

**Lợi ích:**

- Đối tác nhận response đúng: success thật thì 200, lỗi thật thì error
- Không bị rủi ro API trả success rồi xử lý fail phía sau
- Dễ test, dễ debug
- Không cần Redis/BullMQ/RabbitMQ

## Ví dụ cURL

### Tạo cư dân mới

```bash
curl -X POST https://bekind-dev.meucorp.com/api/v1/webhooks/residents \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Token: webhook_bekind_2026_secure_token_ktx_tro_integration_v1" \
  -d '{
    "event_id": "evt_123456789",
    "type": "KTX",
    "c_name": "Nguyễn Văn A",
    "c_dob": "01/01/2000",
    "c_tel": "0901234567",
    "c_sex": "Nam",
    "c_cccd": "012345678901",
    "c_add": "Đồng Nai"
  }'
```

### Tạo cư dân không có số điện thoại

```bash
curl -X POST https://bekind-dev.meucorp.com/api/v1/webhooks/residents \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Token: webhook_bekind_2026_secure_token_ktx_tro_integration_v1" \
  -d '{
    "type": "tro",
    "c_name": "Trần Thị B",
    "c_dob": "15/05/1998",
    "c_sex": "Nữ",
    "c_cccd": "098765432109",
    "c_add": "Hồ Chí Minh"
  }'
```

## Cấu hình cho đối tác

### Bước 1: Cung cấp thông tin cho đối tác

- Webhook URL: `https://bekind-dev.meucorp.com/api/v1/webhooks/residents`
- Webhook Token: `{WEBHOOK_TOKEN}` (lấy từ biến môi trường)
- Request format: JSON
- Authentication method: X-Webhook-Token hoặc Authorization Bearer

### Bước 2: Đối tác cấu hình hệ thống

Đối tác cần:

1. Thêm webhook URL vào hệ thống của họ
2. Thêm token vào header khi gọi API
3. Định dạng dữ liệu theo schema trên
4. Xử lý response để kiểm tra kết quả

### Bước 3: Test

- Gửi request test để đảm bảo kết nối thành công
- Kiểm tra dữ liệu được tạo/cập nhật đúng trong hệ thống Bekind
- Xác nhận audit logs được ghi nhận

## Lưu ý quan trọng

1. **Token bảo mật**: Không chia sẻ webhook token cho bên thứ ba
2. **Retry mechanism**: Đối tác nên implement retry khi nhận response lỗi (5xx)
3. **Rate limiting**: Hệ thống có thể áp dụng rate limiting để bảo vệ
4. **Date format**: Sử dụng format DD/MM/YYYY cho ngày sinh
5. **Phone format**: Số điện thoại sẽ được normalize tự động (loại bỏ space, dash)
6. **ID Card format**: Số CCCD/CMND sẽ được normalize tự động

## Troubleshooting

### 401 Unauthorized

- Kiểm tra token có đúng không
- Kiểm tra header có đúng format không

### 400 Bad Request

- Kiểm tra body có đúng format không
- Kiểm tra các required field (`c_name`, `type`)

### 500 Internal Server Error

- Liên hệ team Bekind để kiểm tra logs
- Cung cấp timestamp và trace_id từ response

## Hỗ trợ

Nếu gặp vấn đề khi tích hợp webhook, vui lòng liên hệ:

- Email: support@bekind.vn
- Cung cấp: timestamp, trace_id, và request details
