# ABC Core API Endpoints (Phase 2)

All endpoints return JSON.
All timestamps are in ISO 8601 format (Y-m-d H:i:s) in UTC unless otherwise configured.

## Base URL

```
https://api.example.com/api/v1
```

## Authentication

All protected endpoints require a Bearer token in the Authorization header:

```
Authorization: Bearer <token>
```

---

## Health Check

### GET /health

Returns the service health status.

**Response:**
```json
{
  "success": true,
  "message": "Success",
  "data": {
    "status": "healthy",
    "service": "ABC Core",
    "version": "1.1.0",
    "timestamp": "2026-07-02 10:00:00"
  }
}
```

---

## Authentication

### POST /api/v1/auth/register

Register a new user (self-registration).

**Request:**
```json
{
  "email": "user@example.com",
  "password": "SecurePass123",
  "password_confirmation": "SecurePass123",
  "first_name": "John",
  "last_name": "Doe",
  "phone": "+2348000000000"
}
```

**Response:**
```json
{
  "success": true,
  "message": "User registered successfully",
  "data": {
    "id": 1,
    "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "email": "user@example.com",
    "first_name": "John",
    "last_name": "Doe",
    "phone": "+2348000000000",
    "status": "ACTIVE",
    "roles": [{"role": "CUSTOMER"}],
    "created_at": "2026-07-02 10:00:00"
  }
}
```

---

### POST /api/v1/auth/login

Authenticate and receive a Bearer token.

**Request:**
```json
{
  "email": "user@example.com",
  "password": "SecurePass123"
}
```

**Response:**
```json
{
  "success": true,
  "message": "Login successful",
  "data": {
    "user": {
      "id": 1,
      "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "email": "user@example.com",
      "first_name": "John",
      "last_name": "Doe",
      "status": "ACTIVE",
      "roles": [{"role": "CUSTOMER"}]
    },
    "token": "<bearer-token>",
    "expires_at": "2026-07-02 12:00:00"
  }
}
```

---

### POST /api/v1/auth/logout

Invalidate the current Bearer token.

**Headers:**
```
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "message": "Logout successful",
  "data": null
}
```

---

### POST /api/v1/auth/forgot-password

Request a password reset token.

**Request:**
```json
{
  "email": "user@example.com"
}
```

**Response:**
```json
{
  "success": true,
  "message": "If the email exists, a reset link will be sent",
  "data": null
}
```

> Note: Always returns success to prevent email enumeration.

---

### POST /api/v1/auth/reset-password

Reset password using a token.

**Request:**
```json
{
  "token": "<reset-token>",
  "password": "NewSecurePass123",
  "password_confirmation": "NewSecurePass123"
}
```

**Response:**
```json
{
  "success": true,
  "message": "Password reset successful",
  "data": {
    "message": "Password has been reset successfully"
  }
}
```

---

### POST /api/v1/auth/change-password

Change password for the authenticated user.

**Headers:**
```
Authorization: Bearer <token>
```

**Request:**
```json
{
  "old_password": "OldPass123",
  "password": "NewSecurePass123",
  "password_confirmation": "NewSecurePass123"
}
```

**Response:**
```json
{
  "success": true,
  "message": "Password changed successfully",
  "data": {
    "message": "Password changed successfully"
  }
}
```

---

## Users

### GET /api/v1/users

List all users (paginated, filterable).

**Headers:**
```
Authorization: Bearer <token>
```

**Query Parameters:**
- `status` - Filter by status (ACTIVE, PENDING_KYC, SUSPENDED, etc.)
- `email` - Search by email (partial match)
- `name` - Search by first or last name (partial match)
- `page` - Page number (default: 1)
- `per_page` - Items per page (default: 20)

**Response:**
```json
{
  "success": true,
  "message": "Success",
  "data": {
    "items": [...],
    "page": 1,
    "per_page": 20,
    "total": 100,
    "total_pages": 5
  }
}
```

---

### POST /api/v1/users

Create a new user (admin/staff action).

**Headers:**
```
Authorization: Bearer <token>
```

**Request:**
```json
{
  "email": "new@example.com",
  "password": "SecurePass123",
  "password_confirmation": "SecurePass123",
  "first_name": "Jane",
  "last_name": "Doe",
  "phone": "+2348000000001",
  "status": "ACTIVE",
  "roles": ["CUSTOMER"]
}
```

**Response:**
```json
{
  "success": true,
  "message": "User created successfully",
  "data": {
    "id": 2,
    "uuid": "...",
    "email": "new@example.com",
    "first_name": "Jane",
    "last_name": "Doe",
    "status": "ACTIVE",
    "roles": [{"role": "CUSTOMER"}]
  }
}
```

---

### GET /api/v1/users/{uuid}

Get a single user by UUID.

**Headers:**
```
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "message": "Success",
  "data": {
    "id": 1,
    "uuid": "...",
    "email": "user@example.com",
    "first_name": "John",
    "last_name": "Doe",
    "status": "ACTIVE",
    "roles": [{"role": "CUSTOMER"}]
  }
}
```

---

### PUT /api/v1/users/{uuid}

Update a user.

**Headers:**
```
Authorization: Bearer <token>
```

**Request:**
```json
{
  "first_name": "Johnny",
  "last_name": "Doe",
  "phone": "+2348000000002",
  "status": "ACTIVE"
}
```

**Response:**
```json
{
  "success": true,
  "message": "User updated successfully",
  "data": {
    "id": 1,
    "uuid": "...",
    "first_name": "Johnny",
    "last_name": "Doe",
    "phone": "+2348000000002",
    "status": "ACTIVE"
  }
}
```

---

### PATCH /api/v1/users/{uuid}/activate

Activate a suspended user.

**Headers:**
```
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "message": "User activated successfully",
  "data": {
    "id": 1,
    "uuid": "...",
    "status": "ACTIVE"
  }
}
```

---

### PATCH /api/v1/users/{uuid}/suspend

Suspend a user.

**Headers:**
```
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "message": "User suspended successfully",
  "data": {
    "id": 1,
    "uuid": "...",
    "status": "SUSPENDED"
  }
}
```

---

### GET /api/v1/users/{uuid}/roles

Get user roles.

**Headers:**
```
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "message": "Success",
  "data": [
    {"role": "CUSTOMER"}
  ]
}
```

---

### POST /api/v1/users/{uuid}/roles

Assign a role to a user.

**Headers:**
```
Authorization: Bearer <token>
```

**Request:**
```json
{
  "role": "STAFF"
}
```

**Response:**
```json
{
  "success": true,
  "message": "Role assigned successfully",
  "data": {
    "roles": [
      {"role": "CUSTOMER"},
      {"role": "STAFF"}
    ]
  }
}
```

---

## Accounts

### GET /api/v1/accounts

List all accounts (paginated, filterable).

**Headers:**
```
Authorization: Bearer <token>
```

**Query Parameters:**
- `status` - Filter by status (PENDING, ACTIVE, FROZEN, CLOSED)
- `account_type` - Filter by type (SAVINGS, CURRENT, etc.)
- `currency` - Filter by currency (NGN, USD, etc.)
- `account_number` - Search by account number (partial match)
- `user_uuid` - Filter by owner user UUID
- `page` - Page number (default: 1)
- `per_page` - Items per page (default: 20)

**Response:**
```json
{
  "success": true,
  "message": "Success",
  "data": {
    "items": [
      {
        "id": 1,
        "uuid": "...",
        "user_id": 1,
        "account_number": "1001234567",
        "account_type": "SAVINGS",
        "currency": "NGN",
        "status": "ACTIVE",
        "branch_code": "001",
        "daily_transaction_limit": 100000.00,
        "balance": 0.00,
        "created_at": "2026-07-02 10:00:00"
      }
    ],
    "page": 1,
    "per_page": 20,
    "total": 50,
    "total_pages": 3
  }
}
```

---

### POST /api/v1/accounts

Create a new account.

**Headers:**
```
Authorization: Bearer <token>
```

**Request:**
```json
{
  "user_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "account_type": "SAVINGS",
  "currency": "NGN",
  "status": "ACTIVE",
  "branch_code": "001",
  "daily_transaction_limit": 100000.00
}
```

**Response:**
```json
{
  "success": true,
  "message": "Account created successfully",
  "data": {
    "id": 1,
    "uuid": "...",
    "account_number": "1001234567",
    "account_type": "SAVINGS",
    "currency": "NGN",
    "status": "ACTIVE",
    "balance": 0.00,
    "created_at": "2026-07-02 10:00:00"
  }
}
```

> Note: Account number is auto-generated. Balance is initialized to 0.00 and is NOT modified by the Accounts module.

---

### GET /api/v1/accounts/{uuid}

Get a single account by UUID.

**Headers:**
```
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "message": "Success",
  "data": {
    "id": 1,
    "uuid": "...",
    "account_number": "1001234567",
    "account_type": "SAVINGS",
    "currency": "NGN",
    "status": "ACTIVE",
    "balance": 0.00,
    "daily_transaction_limit": 100000.00,
    "created_at": "2026-07-02 10:00:00"
  }
}
```

---

### PATCH /api/v1/accounts/{uuid}/freeze

Freeze an account.

**Headers:**
```
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "message": "Account frozen successfully",
  "data": {
    "id": 1,
    "uuid": "...",
    "status": "FROZEN"
  }
}
```

---

### PATCH /api/v1/accounts/{uuid}/unfreeze

Unfreeze an account.

**Headers:**
```
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "message": "Account unfrozen successfully",
  "data": {
    "id": 1,
    "uuid": "...",
    "status": "ACTIVE"
  }
}
```

---

### PATCH /api/v1/accounts/{uuid}/close

Close an account.

**Headers:**
```
Authorization: Bearer <token>
```

**Request:**
```json
{
  "reason": "Customer request"
}
```

**Response:**
```json
{
  "success": true,
  "message": "Account closed successfully",
  "data": {
    "id": 1,
    "uuid": "...",
    "status": "CLOSED",
    "closed_at": "2026-07-02 10:00:00",
    "closed_reason": "Customer request"
  }
}
```

---

## Error Responses

All errors return a consistent JSON structure:

```json
{
  "success": false,
  "message": "Error message",
  "errors": {
    "field": ["Error detail"]
  }
}
```

**Common HTTP Status Codes:**
- `200` - Success
- `400` - Bad Request
- `401` - Unauthorized / Invalid Token
- `403` - Forbidden / Insufficient Permissions
- `404` - Not Found
- `422` - Validation Error
- `429` - Rate Limit Exceeded
- `500` - Internal Server Error

---

## Authentication Flow

1. **Register:** `POST /api/v1/auth/register` → Returns user data
2. **Login:** `POST /api/v1/auth/login` → Returns Bearer token
3. **Use Token:** Include `Authorization: Bearer <token>` in all protected requests
4. **Logout:** `POST /api/v1/auth/logout` → Invalidates token

---

## Password Policy

Default requirements:
- Minimum 8 characters
- At least 1 uppercase letter
- At least 1 lowercase letter
- At least 1 number
- Cannot reuse last 5 passwords
- Account locked after 5 failed login attempts (30 minutes)
