# MSL Assets & Investments - API Documentation

> **Base URL**: `http://localhost:8000/api`  
> **Content-Type**: `application/json`  
> **Authentication**: Bearer Token (for protected endpoints)

---

## Table of Contents

1. [Authentication](#authentication)
2. [Investment Flow](#investment-flow)
3. [Payment Integration](#payment-integration)
4. [Investor Endpoints](#investor-endpoints)
5. [Document Generation](#document-generation)
6. [Compliance & KYC](#compliance--kyc)
7. [Reports & Analytics](#reports--analytics)
8. [Admin Endpoints](#admin-endpoints)
9. [Error Handling](#error-handling)
10. [Data Types & Enums](#data-types--enums)

---

## Authentication

### Admin Login
Authenticate an admin user and receive a Bearer token.

```http
POST /auth/admin/login
```

**Request Body:**
```json
{
  "email": "admin@meatsoko.com",
  "password": "password123"
}
```

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "user": {
      "id": "uuid",
      "name": "Super Admin",
      "email": "admin@meatsoko.com",
      "role": "super_admin"
    },
    "token": "1|abcdef123456...",
    "token_type": "Bearer"
  },
  "meta": {
    "timestamp": "2026-01-21T12:00:00Z"
  }
}
```

**Error Response (422):**
```json
{
  "message": "The provided credentials are incorrect.",
  "errors": {
    "email": ["The provided credentials are incorrect."]
  }
}
```

---

### Admin Logout
Invalidate the current access token.

```http
POST /auth/admin/logout
Authorization: Bearer {token}
```

**Success Response (200):**
```json
{
  "success": true,
  "message": "Successfully logged out"
}
```

---

### Get Current Admin User
Get the authenticated admin user's profile.

```http
GET /auth/admin/me
Authorization: Bearer {token}
```

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "Super Admin",
    "email": "admin@meatsoko.com",
    "role": "super_admin",
    "permissions": ["*"],
    "last_login": "2026-01-21T12:00:00Z"
  }
}
```

---

### Investor Request Access (Magic Link)
Request a magic link for investor dashboard access.

```http
POST /auth/investor/request-access
```

**Request Body:**
```json
{
  "email": "investor@example.com"
}
```

**Success Response (200):**
```json
{
  "success": true,
  "message": "If an account exists with this email, you will receive an access link."
}
```

---

## Investment Flow

### 1. Initiate Investment
Create a new investment application. This is the main entry point for the investment form.

```http
POST /investments/initiate
```

**Request Body:**
```json
{
  "investor_name": "John Doe",
  "email": "john@example.com",
  "phone": "+254712345678",
  "country": "Kenya",
  "investor_type": "individual",
  "investment_tier": "growth",
  "investment_amount": 500,
  "currency": "USD",
  "investment_term": 2,
  "terms_accepted": true,
  "memorandum_read": true,
  "risks_understood": true,
  "risk_tolerance_confirmed": true,
  "newsletter_subscribed": false,
  "call_requested": false
}
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `investor_name` | string | ✅ | Full name of investor |
| `email` | string | ✅ | Valid email address |
| `phone` | string | ❌ | International phone format |
| `country` | string | ❌ | Country of residence |
| `investor_type` | enum | ❌ | See [Investor Types](#investor-types) |
| `investment_tier` | enum | ✅ | `growth`, `strategic`, or `anchor` |
| `investment_amount` | number | ✅ | Amount in specified currency |
| `currency` | string | ❌ | Default: `USD` |
| `investment_term` | integer | ❌ | Years (1-10), default: 1 |
| `terms_accepted` | boolean | ✅ | Must be `true` |
| `memorandum_read` | boolean | ✅ | Must be `true` |
| `risks_understood` | boolean | ✅ | Must be `true` |
| `risk_tolerance_confirmed` | boolean | ✅ | Must be `true` |
| `newsletter_subscribed` | boolean | ❌ | Email newsletter opt-in |
| `call_requested` | boolean | ❌ | Request callback |

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "investment_id": "550e8400-e29b-41d4-a716-446655440000",
    "reference": "MSL-INV-20260121-ABCD1234",
    "tier": "growth",
    "amount": 500,
    "currency": "USD",
    "expected_roi": 15,
    "expected_returns": 150,
    "kyc_required": false
  },
  "meta": {
    "timestamp": "2026-01-21T12:00:00Z",
    "request_id": "MSL-INV-20260121-ABCD1234"
  }
}
```

**Validation Error (400):**
```json
{
  "error": true,
  "message": "Minimum investment for growth tier is 100 USD",
  "code": "BELOW_TIER_MINIMUM"
}
```

---

### 2. Get Investment by Reference
Retrieve investment details using the reference number.

```http
GET /investments/reference/{reference}
```

**Example:** `GET /investments/reference/MSL-INV-20260121-ABCD1234`

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "investment": {
      "id": "uuid",
      "reference": "MSL-INV-20260121-ABCD1234",
      "investor_name": "John Doe",
      "email": "john@example.com",
      "investment_tier": "growth",
      "investment_amount": "500.00",
      "currency": "USD",
      "investment_term": 2,
      "payment_status": "pending",
      "status": "pending_payment",
      "created_at": "2026-01-21T12:00:00Z"
    },
    "expected_roi": 15,
    "expected_returns": 150
  }
}
```

---

## Payment Integration

### 1. Initialize Paystack Payment
Get a Paystack authorization URL to redirect the user for payment.

```http
POST /payments/initialize
```

**Request Body:**
```json
{
  "investment_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "authorization_url": "https://checkout.paystack.com/abcdef123456",
    "access_code": "abcdef123456",
    "reference": "MSL-PAY-1705838400-XYZ789",
    "investment_reference": "MSL-INV-20260121-ABCD1234"
  }
}
```

**Frontend Implementation:**
```javascript
// After getting the response, redirect to Paystack
const response = await fetch('/api/payments/initialize', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ investment_id: investmentId })
});

const data = await response.json();
if (data.success) {
  // Redirect to Paystack checkout
  window.location.href = data.data.authorization_url;
}
```

---

### 2. Verify Payment
Verify a payment after Paystack redirects back to your callback URL.

```http
POST /payments/verify
```

**Request Body:**
```json
{
  "reference": "MSL-PAY-1705838400-XYZ789"
}
```

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "investment_id": "uuid",
    "investment_reference": "MSL-INV-20260121-ABCD1234",
    "amount": 500,
    "currency": "USD",
    "status": "payment_confirmed",
    "payment_status": "confirmed"
  }
}
```

**Payment Failed (400):**
```json
{
  "error": true,
  "message": "Payment verification failed",
  "code": "VERIFICATION_FAILED"
}
```

---

### Complete Payment Flow Diagram

```
┌─────────────────┐
│  Investment     │
│  Form           │
└────────┬────────┘
         │ POST /investments/initiate
         ▼
┌─────────────────┐
│  Get Investment │
│  ID & Reference │
└────────┬────────┘
         │ POST /payments/initialize
         ▼
┌─────────────────┐
│  Redirect to    │
│  Paystack       │
└────────┬────────┘
         │ User completes payment
         ▼
┌─────────────────┐
│  Paystack       │
│  Callback       │
└────────┬────────┘
         │ POST /payments/verify
         ▼
┌─────────────────┐
│  Success Page   │
│  Show Receipt   │
└─────────────────┘
```

---

## Investor Endpoints

> **Note:** These endpoints require authentication.

### Get Investor Profile

```http
GET /investors/{id}
Authorization: Bearer {token}
```

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "id": "uuid",
    "email": "john@example.com",
    "full_name": "John Doe",
    "phone": "+254712345678",
    "country": "Kenya",
    "investor_type": "individual",
    "total_invested": "1500.00",
    "active_investments": 2,
    "lifetime_returns": "225.00",
    "kyc_status": "approved",
    "risk_profile": "moderate",
    "investments": [...]
  }
}
```

---

### Get Investor by Email

```http
GET /investors/email/{email}
Authorization: Bearer {token}
```

---

### Get Investment History

```http
GET /investors/{id}/investments
Authorization: Bearer {token}
```

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "investments": [
      {
        "id": "uuid",
        "reference": "MSL-INV-20260121-ABCD1234",
        "tier": "growth",
        "amount": 500,
        "currency": "USD",
        "term": 2,
        "status": "active",
        "payment_status": "confirmed",
        "expected_roi": 15,
        "expected_returns": 150,
        "created_at": "2026-01-21T12:00:00Z"
      }
    ],
    "summary": {
      "total_count": 2,
      "total_invested": 1500,
      "active_count": 2
    }
  }
}
```

---

### Get Returns & Dividends

```http
GET /investors/{id}/returns
Authorization: Bearer {token}
```

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "total_invested": 1500,
    "total_expected_returns": 450,
    "total_actual_returns": 225,
    "roi_percentage": 15,
    "investments_count": 2
  }
}
```

---

### Get Dividend History

```http
GET /investors/{id}/dividends
Authorization: Bearer {token}
```

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "dividends": [
      {
        "id": "uuid",
        "period": "Q4 2025",
        "amount": 56.25,
        "currency": "USD",
        "status": "completed",
        "paid_at": "2026-01-05T09:00:00Z",
        "investment_reference": "MSL-INV-20250815-XYZ789"
      }
    ],
    "summary": {
      "total_payments": 4,
      "total_amount": 225,
      "pending_amount": 0
    }
  }
}
```

---

## Document Generation

> **Note:** Requires authentication and payment confirmation.

### Generate Investment Agreement

```http
POST /documents/generate-agreement
Authorization: Bearer {token}
```

**Request Body:**
```json
{
  "investment_id": "uuid"
}
```

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "url": "http://localhost:8000/storage/documents/agreements/investment-agreement-MSL-INV-20260121-ABCD1234.pdf",
    "file_name": "investment-agreement-MSL-INV-20260121-ABCD1234.pdf"
  }
}
```

---

### Generate Payment Receipt

```http
POST /documents/generate-receipt
Authorization: Bearer {token}
```

**Request Body:**
```json
{
  "investment_id": "uuid"
}
```

---

### Generate Quarterly Report

```http
POST /documents/generate-quarterly-report
Authorization: Bearer {token}
```

**Request Body:**
```json
{
  "investor_id": "uuid",
  "year": 2026,
  "quarter": 1
}
```

---

## Compliance & KYC

### Initiate KYC Process

```http
POST /compliance/kyc/initiate
Authorization: Bearer {token}
```

**Request Body:**
```json
{
  "investor_id": "uuid"
}
```

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "investor_id": "uuid",
    "kyc_status": "pending",
    "required_documents": ["passport", "proof_of_address"],
    "upload_url": "http://localhost:8000/api/compliance/kyc/upload-document"
  }
}
```

---

### Upload KYC Document

```http
POST /compliance/kyc/upload-document
Authorization: Bearer {token}
Content-Type: multipart/form-data
```

**Form Data:**
| Field | Type | Description |
|-------|------|-------------|
| `investor_id` | uuid | Investor ID |
| `document_type` | enum | See [Document Types](#document-types) |
| `document` | file | PDF, JPG, PNG (max 10MB) |

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "document_id": "uuid",
    "document_type": "passport",
    "status": "pending"
  }
}
```

---

### Get KYC Status

```http
GET /compliance/kyc/{investorId}
Authorization: Bearer {token}
```

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "kyc_status": "pending",
    "documents": [
      {
        "id": "uuid",
        "type": "passport",
        "status": "approved",
        "uploaded_at": "2026-01-20T10:00:00Z",
        "verified_at": "2026-01-20T14:00:00Z",
        "rejection_reason": null
      },
      {
        "id": "uuid",
        "type": "proof_of_address",
        "status": "pending",
        "uploaded_at": "2026-01-21T09:00:00Z",
        "verified_at": null,
        "rejection_reason": null
      }
    ],
    "required_documents": ["passport", "proof_of_address"]
  }
}
```

---

## Reports & Analytics

> **Note:** Admin authentication required.

### Get Investment Summary

```http
GET /reports/investment-summary
Authorization: Bearer {token}
```

**Query Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| `start_date` | date | Filter from date (YYYY-MM-DD) |
| `end_date` | date | Filter to date (YYYY-MM-DD) |

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "total_investments": 150,
    "total_value": 2500000,
    "average_investment": 16666.67,
    "by_status": {
      "active": { "count": 100, "total": 2000000 },
      "pending_payment": { "count": 20, "total": 200000 },
      "completed": { "count": 30, "total": 300000 }
    },
    "by_tier": {
      "growth": { "count": 80, "total": 500000 },
      "strategic": { "count": 50, "total": 1000000 },
      "anchor": { "count": 20, "total": 1000000 }
    },
    "monthly_trend": [
      { "month": "2025-12", "count": 15, "total": 250000 },
      { "month": "2026-01", "count": 20, "total": 350000 }
    ]
  }
}
```

---

### Get Investor Demographics

```http
GET /reports/investor-demographics
Authorization: Bearer {token}
```

---

### Get Financial Performance

```http
GET /reports/financial-performance
Authorization: Bearer {token}
```

---

### Get Conversion Funnel

```http
GET /reports/conversion-funnel
Authorization: Bearer {token}
```

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "stages": {
      "form_submissions": 500,
      "payment_initiated": 400,
      "payment_confirmed": 350,
      "agreement_sent": 340,
      "active_investments": 320
    },
    "conversion_rates": {
      "submission_to_initiation": 80,
      "initiation_to_payment": 87.5,
      "payment_to_activation": 91.43,
      "overall": 64
    }
  }
}
```

---

## Admin Endpoints

> **Note:** Admin authentication required. Some endpoints require specific roles.

### Get Dashboard Stats

```http
GET /admin/dashboard-stats
Authorization: Bearer {token}
```

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "today": {
      "investments": 5,
      "value": 25000
    },
    "this_week": {
      "investments": 35,
      "value": 175000
    },
    "pending": {
      "payments": 12,
      "kyc": 8,
      "agreements": 5
    },
    "recent_investments": [...]
  }
}
```

---

### List All Investments

```http
GET /admin/investments
Authorization: Bearer {token}
```

**Query Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| `status` | enum | Filter by status |
| `payment_status` | enum | Filter by payment status |
| `tier` | enum | Filter by tier |
| `start_date` | date | Filter from date |
| `end_date` | date | Filter to date |
| `min_amount` | number | Minimum amount |
| `max_amount` | number | Maximum amount |
| `search` | string | Search by reference, name, or email |
| `per_page` | integer | Results per page (10-100) |
| `page` | integer | Page number |

---

### Get Single Investment

```http
GET /admin/investment/{id}
Authorization: Bearer {token}
```

---

### Update Investment

```http
PUT /admin/investment/{id}
Authorization: Bearer {token}
```

**Request Body:**
```json
{
  "status": "active",
  "notes": "Investor onboarding complete"
}
```

---

### Process Refund

```http
POST /admin/investment/{id}/refund
Authorization: Bearer {token}
```

**Required Role:** `super_admin` or `finance_manager`

**Request Body:**
```json
{
  "reason": "Customer requested refund within cooling-off period"
}
```

---

## Error Handling

All error responses follow this format:

```json
{
  "error": true,
  "message": "Human-readable error message",
  "code": "ERROR_CODE",
  "details": {}
}
```

### HTTP Status Codes

| Code | Description |
|------|-------------|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request / Validation Error |
| 401 | Unauthenticated |
| 403 | Forbidden (insufficient permissions) |
| 404 | Not Found |
| 422 | Validation Error |
| 500 | Server Error |

### Common Error Codes

| Code | Description |
|------|-------------|
| `BELOW_TIER_MINIMUM` | Investment amount below tier minimum |
| `COMPLIANCE_INCOMPLETE` | Required checkboxes not accepted |
| `ALREADY_PAID` | Investment already paid |
| `PAYMENT_NOT_CONFIRMED` | Payment not confirmed yet |
| `VERIFICATION_FAILED` | Payment verification failed |
| `KYC_ALREADY_APPROVED` | KYC already completed |
| `CANNOT_REFUND` | Refund not allowed for this investment |

---

## Data Types & Enums

### Investment Tiers

| Tier | Minimum | Expected ROI |
|------|---------|--------------|
| `growth` | $100 | 15% |
| `strategic` | $1,000 | 18% |
| `anchor` | $5,000 | 22% |

### Investor Types

| Value | Description |
|-------|-------------|
| `individual` | Individual investor |
| `company` | Company/Corporation |
| `fund` | Investment fund |
| `family_office` | Family office |
| `institution` | Institutional investor |

### Investment Status

| Value | Description |
|-------|-------------|
| `pending_payment` | Awaiting payment |
| `payment_confirmed` | Payment received |
| `agreement_pending` | Awaiting agreement signature |
| `active` | Active investment |
| `completed` | Investment matured |
| `cancelled` | Investment cancelled |

### Payment Status

| Value | Description |
|-------|-------------|
| `pending` | Not yet initiated |
| `processing` | Payment in progress |
| `confirmed` | Payment successful |
| `failed` | Payment failed |
| `refunded` | Payment refunded |

### KYC Status

| Value | Description |
|-------|-------------|
| `not_started` | KYC not initiated |
| `pending` | Documents under review |
| `approved` | KYC verified |
| `rejected` | KYC rejected |

### Document Types

| Value | Description |
|-------|-------------|
| `passport` | Passport |
| `national_id` | National ID card |
| `drivers_license` | Driver's license |
| `proof_of_address` | Utility bill, bank statement |
| `source_of_funds` | Document proving source of funds |

### Admin Roles

| Role | Permissions |
|------|-------------|
| `super_admin` | Full access |
| `finance_manager` | Payments, refunds, financial reports |
| `compliance_officer` | KYC review, sanctions checks |
| `investor_relations` | Investor communication, documents |
| `viewer` | Read-only access |

---

## Rate Limiting

- **Default:** 60 requests/minute per IP
- **Authenticated:** 120 requests/minute per user
- **Webhooks:** No rate limiting

---

## CORS

Allowed origins are configured server-side. For local development:
- `http://localhost:3000`
- `http://localhost:5173`

---

## Webhooks (For Backend Reference)

### Paystack Webhook

```http
POST /webhooks/paystack
X-Paystack-Signature: {hmac_sha512_signature}
```

Events handled:
- `charge.success` - Payment successful
- `transfer.success` - Dividend payment successful
- `charge.dispute.create` - Payment dispute
- `refund.processed` - Refund completed

---

## Example: Complete Investment Flow

```javascript
// 1. Submit investment form
const investment = await fetch('/api/investments/initiate', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    investor_name: 'John Doe',
    email: 'john@example.com',
    investment_tier: 'growth',
    investment_amount: 500,
    terms_accepted: true,
    memorandum_read: true,
    risks_understood: true,
    risk_tolerance_confirmed: true
  })
});
const { data: { investment_id } } = await investment.json();

// 2. Initialize payment
const payment = await fetch('/api/payments/initialize', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ investment_id })
});
const { data: { authorization_url } } = await payment.json();

// 3. Redirect to Paystack
window.location.href = authorization_url;

// 4. On callback page (after Paystack redirect)
const urlParams = new URLSearchParams(window.location.search);
const reference = urlParams.get('reference');

const verify = await fetch('/api/payments/verify', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ reference })
});
const result = await verify.json();

if (result.success) {
  // Show success page
  console.log('Payment confirmed!', result.data);
}
```
