> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/No-Country-simulation/S02-26-Equipo-33-Web-App/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart Guide

> Set up and run the Horse Trust platform in your local development environment

# Quickstart Guide

Get the Horse Trust platform running locally in just a few minutes. This guide will walk you through cloning the repository, installing dependencies, configuring environment variables, and starting both the client and server applications.

## Prerequisites

Before you begin, ensure you have the following installed:

<CardGroup cols={2}>
  <Card title="Node.js" icon="node-js">
    Version 24.13.0 or higher
  </Card>

  <Card title="Git" icon="git-alt">
    Version 2.43.0 or higher
  </Card>

  <Card title="MongoDB" icon="database">
    MongoDB Atlas account or local MongoDB instance
  </Card>

  <Card title="npm" icon="npm">
    Comes bundled with Node.js
  </Card>
</CardGroup>

## Installation

<Steps>
  <Step title="Clone the Repository">
    Clone the Horse Trust repository to your local machine:

    ```bash theme={null}
    git clone git@github.com:No-Country-simulation/S02-26-Equipo-33-Web-App.git
    cd S02-26-Equipo-33-Web-App
    ```

    The repository follows a monorepo structure with separate `client` and `server` directories.
  </Step>

  <Step title="Set Up the Backend Server">
    Navigate to the server directory and install dependencies:

    ```bash theme={null}
    cd server
    npm install
    ```

    ### Configure Server Environment Variables

    Create a `.env` file in the `server` directory based on `.env.example`:

    ```bash server/.env theme={null}
    # ================================
    # 🌍 SERVER DATABASE CONNECTION 🌍
    # ================================
    PORT=8031
    NODE_ENV=development
    MONGO_URI=mongodb+srv://username:password@cluster.mongodb.net/horsetrust?retryWrites=true&w=majority

    # ================================
    # JWT Configuration
    # ================================
    JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
    JWT_EXPIRES_IN=10d
    BCRYPT_SALT_ROUNDS=12

    # ================================
    # CORS Configuration
    # ================================
    CORS_ORIGINS=http://localhost:8030,http://localhost:3000

    # ================================
    # Rate Limiting (Optional)
    # ================================
    RATE_LIMIT_WINDOW_MS=900000
    RATE_LIMIT_MAX=100
    ```

    <Warning>
      Replace `MONGO_URI` with your actual MongoDB connection string. You can get one from [MongoDB Atlas](https://www.mongodb.com/cloud/atlas) for free.
    </Warning>

    <Note>
      The `JWT_SECRET` should be a long, random string. In production, use a cryptographically secure random value.
    </Note>

    ### Start the Server

    Run the development server:

    ```bash theme={null}
    npm run dev
    ```

    The server will start on `http://localhost:8031` (or the port specified in your `.env` file).

    ### Test the Server

    Verify the server is running by testing the health endpoint:

    ```bash theme={null}
    curl http://localhost:8031/health
    ```

    You should receive a response like:

    ```json theme={null}
    {
      "success": true,
      "message": "Horse Portal API is running",
      "env": "development"
    }
    ```
  </Step>

  <Step title="Set Up the Frontend Client">
    Open a new terminal window and navigate to the client directory:

    ```bash theme={null}
    cd client
    npm install
    ```

    ### Configure Client Environment Variables

    Create a `.env.local` file in the `client` directory:

    ```bash client/.env.local theme={null}
    # ==========================================
    # VARIABLES DE ENTORNO - HORSETRUST (FRONTEND)
    # ==========================================

    # URL base de la API de backend
    NEXT_PUBLIC_API_URL=http://localhost:8031/api

    # Cloudinary Configuration (for image uploads)
    NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=di2agiylz
    NEXT_PUBLIC_CLOUDINARY_UPLOAD_PRESET=horse_trust_uploads
    ```

    <Note>
      The `NEXT_PUBLIC_API_URL` should point to your backend server. Make sure the port matches your server configuration.
    </Note>

    ### Start the Client

    Run the Next.js development server:

    ```bash theme={null}
    npm run dev
    ```

    The client will start on `http://localhost:8030`.
  </Step>

  <Step title="Access the Application">
    Open your browser and navigate to:

    ```
    http://localhost:8030
    ```

    You should see the Horse Trust landing page with:

    * Hero section introducing the platform
    * Featured horses section
    * Security features section
    * Navigation header and footer
  </Step>
</Steps>

## Development Workflow

### Running Both Services

For development, you'll need two terminal windows:

<CodeGroup>
  ```bash Terminal 1 - Backend theme={null}
  cd server
  npm run dev
  ```

  ```bash Terminal 2 - Frontend theme={null}
  cd client
  npm run dev
  ```
</CodeGroup>

### Available Scripts

#### Backend Scripts

```json server/package.json theme={null}
{
  "scripts": {
    "dev": "nodemon",           // Start development server with hot reload
    "start": "node dist/index.js" // Start production server
  }
}
```

#### Frontend Scripts

```json client/package.json theme={null}
{
  "scripts": {
    "dev": "next dev -p 8030",    // Start development server on port 8030
    "build": "next build",         // Build for production
    "start": "next start -p 8030", // Start production server
    "lint": "eslint"                // Run ESLint
  }
}
```

## Authentication Flow

### Register a New User

Use the registration action to create a new account:

```typescript client/app/actions/auth.ts theme={null}
import { apiFetch } from '../utils/apiFetch';
import { cookies } from 'next/headers';

export async function registerUser(userData: any) {
  const res = await apiFetch('/auth/register', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(userData),
  });

  const data = await res.json();

  if (!res.ok) {
    throw new Error(data.message || 'Error al registrar el usuario');
  }

  // Store JWT token in HTTP-only cookie
  const cookieStore = await cookies();
  cookieStore.set('horse_trust_token', data.token, { 
    httpOnly: true, 
    secure: process.env.NODE_ENV === 'production',
    maxAge: 60 * 60 * 24 * 7, // 7 days
    path: '/',
  });

  return { success: true, data };
}
```

### Login Flow

```typescript theme={null}
export async function loginUser(email: string, password: string) {
  const res = await apiFetch('/auth/login', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password }),
  });

  const data = await res.json();

  if (!res.ok) {
    throw new Error(data.error || 'Error al validar credenciales');
  }
  
  const cookieStore = await cookies();
  cookieStore.set('horse_trust_token', data.token, { 
    httpOnly: true, 
    secure: process.env.NODE_ENV === 'production',
    maxAge: 60 * 60 * 24 * 7,
    path: '/',
  });

  return { success: true, data };
}
```

## Creating Your First Horse Listing

Once logged in as a seller, you can create horse listings:

```typescript client/app/actions/horses.ts theme={null}
import { apiFetch } from '../utils/apiFetch';
import { cookies } from 'next/headers';
import { revalidatePath } from 'next/cache';

export async function createHorse(horseData: any) {
  const cookieStore = await cookies();
  const token = cookieStore.get('horse_trust_token')?.value;

  if (!token) {
    return { success: false, error: "No hay una sesión activa" };
  }

  const res = await apiFetch('/horses', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}` 
    },
    body: JSON.stringify(horseData),
  });

  const data = await res.json();

  if (!res.ok) {
    return { success: false, error: data.error || "Error al publicar el caballo" };
  }

  // Revalidate relevant pages
  revalidatePath('/marketplace'); 
  revalidatePath('/dashboard'); 
  
  return { success: true, data };
}
```

### Horse Data Structure

```typescript theme={null}
const horseData = {
  name: "Thunder",
  age: 5,
  breed: "Thoroughbred",
  discipline: "Show Jumping",
  pedigree: "Sire: Lightning | Dam: Storm",
  location: {
    country: "Argentina",
    region: "Buenos Aires",
    city: "La Plata",
    coordinates: { lat: -34.9214, lng: -57.9544 }
  },
  price: 50000,
  currency: "USD",
  photos: [
    { url: "https://...", caption: "Front view", is_cover: true },
    { url: "https://...", caption: "Side view" },
    { url: "https://...", caption: "Action shot" }
  ],
  videos: [
    {
      url: "https://youtube.com/watch?v=...",
      video_type: "training",
      title: "Training Session",
      recorded_at: "2026-03-01T00:00:00Z"
    }
  ],
  status: "active"
};
```

<Note>
  At least 3 photos are required for each horse listing. The platform validates this at the database level.
</Note>

## Real-time Chat Setup

The platform uses Socket.io for real-time messaging between buyers and sellers:

```typescript server/src/index.ts theme={null}
import { Server as SocketServer } from "socket.io";
import jwt from "jsonwebtoken";

const io = new SocketServer(httpServer, {
  cors: {
    origin: process.env.CORS_ORIGINS.split(","),
    credentials: true,
  },
});

// JWT authentication for socket connections
io.use((socket, next) => {
  const token = socket.handshake.auth?.token;
  if (!token) {
    return next(new Error("Authentication error: no token"));
  }
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    socket.user = decoded;
    next();
  } catch {
    next(new Error("Authentication error: invalid token"));
  }
});

io.on("connection", (socket) => {
  // Join user-specific room
  socket.join(`user:${socket.user.userId}`);
  
  // Join conversation room
  socket.on("join_conversation", (conversationId) => {
    socket.join(`conv:${conversationId}`);
  });
  
  // Send message
  socket.on("send_message", async (data, ack) => {
    // Message handling logic...
  });
});
```

## Troubleshooting

### Common Issues

<AccordionGroup>
  <Accordion title="MongoDB Connection Failed">
    * Verify your `MONGO_URI` is correct
    * Check if your IP address is whitelisted in MongoDB Atlas
    * Ensure network connectivity to MongoDB
    * Check MongoDB Atlas cluster status
  </Accordion>

  <Accordion title="CORS Errors">
    * Ensure `CORS_ORIGINS` in server `.env` includes your client URL
    * Check that both frontend and backend are running
    * Verify the `NEXT_PUBLIC_API_URL` matches your backend URL
  </Accordion>

  <Accordion title="Port Already in Use">
    Change the port in your `.env` files:

    * Server: Update `PORT` in `server/.env`
    * Client: Update the `-p` flag in `client/package.json` scripts
  </Accordion>

  <Accordion title="JWT Token Issues">
    * Ensure `JWT_SECRET` is set in server `.env`
    * Check token expiration (default 10 days)
    * Clear browser cookies and re-login
  </Accordion>
</AccordionGroup>

### Database Auto-Reconnect

The platform includes an automatic database reconnection feature:

```typescript client/app/utils/apiFetch.ts theme={null}
export async function apiFetch(endpoint: string, options: RequestInit = {}) {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;
  const url = `${apiUrl}${endpoint}`;

  try {
    let res = await fetch(url, options);

    // Auto-retry with database reconnection on 5xx errors
    if (!res.ok && res.status >= 500) {
      console.log(`API failed. Attempting to wake Oracle...`);
      
      const reconRes = await fetch(`${apiUrl}/health/reconnect`, { 
        method: 'POST' 
      });
      
      if (reconRes.ok) {
        console.log(`DB reconnected. Retrying request...`);
        res = await fetch(url, options);
      }
    }

    return res;
  } catch (error) {
    console.error(`Network error. Attempting reconnect...`, error);
    await fetch(`${apiUrl}/health/reconnect`, { method: 'POST' });
    return await fetch(url, options);
  }
}
```

<Note>
  The `/health/reconnect` endpoint called by the frontend is referenced in the client code but not yet implemented in the backend API. The frontend includes this code for future database reconnection functionality.
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="Architecture Overview" icon="sitemap" href="/architecture">
    Learn about the system architecture and how components interact
  </Card>

  <Card title="API Reference" icon="code" href="/api/auth/register">
    Explore the complete API documentation
  </Card>

  <Card title="Contributing" icon="code-pull-request" href="/contributing/git-workflow">
    Learn how to contribute to the Horse Trust project
  </Card>

  <Card title="Deployment" icon="rocket" href="/deployment/setup">
    Deploy Horse Trust to production
  </Card>
</CardGroup>

<Note>
  For production deployment, remember to:

  * Use strong, unique values for `JWT_SECRET`
  * Set `NODE_ENV=production`
  * Configure proper CORS origins
  * Use SSL/TLS certificates
  * Set up proper MongoDB authentication
  * Enable security features (Helmet, rate limiting)
</Note>
