# minxa.lol URL Shortener

minxa.lol is a lightweight and efficient URL shortening service built with **FastAPI**, **SQLAlchemy**, and **Hashids**. It converts long URLs into short, shareable codes and provides redirection to the original URLs.

---

## Features

* 🔗 Shorten URLs into unique shortcodes
* 🚀 Redirect to original URLs using the shortcode
* ✅ Validates shortcode format
* 🛠 Built with modern async Python stack
* 🧂 Configurable encoding via `hashids`

---

## Tech Stack

* FastAPI
* SQLAlchemy (async + sync)
* PostgreSQL
* Hashids
* Alembic (for migrations)
* Pydantic / Pydantic Settings
* Uvicorn (ASGI server)

---

## Getting Started

### 1. Clone the repository

```bash
git clone https://github.com/yourusername/minxa.git
cd minxa
```

### 2. Create and configure your environment file

Copy the example file and update it with your local settings:

```bash
cp .env.example .env
```

Required variables in `.env`:

```env
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/minxa
ENVIRONMENT=dev
HASHIDS_SALT=your-secret-salt
ENCODER_ALPHABET=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
```

### 3. Install dependencies

```bash
pip install -r requirements.txt
```

### 4. Run the application

```bash
uvicorn app.main:app --reload
```

---

## API Endpoints

### `POST /`

Create a new shortened URL.

**Request Body:**

```json
{
  "url": "https://example.com"
}
```

**Response:**

```json
{
  "shortcode": "abc123",
  "url": "https://example.com"
}
```

---

### `GET /{shortcode}`

Redirects to the original URL associated with the given shortcode.

**Example:**

```bash
curl -v http://localhost:8000/abc123
```

Returns a `302` redirect to the original URL.

---

## Project Structure

```
app/
├── main.py               # FastAPI entry point
├── config.py             # Environment and settings
├── database.py           # Database setup
├── models/               # SQLAlchemy models
├── routes/               # API endpoints
├── services/             # URL logic
├── schemas/              # Pydantic schemas
├── utils/                # Encoder logic using hashids
├── exceptions.py         # Custom exceptions
```

---

## Development Notes

* Database tables auto-create in development mode
* Encoder uses Hashids for deterministic, unique shortcodes
* Uses `pydantic` for validation and FastAPI's dependency injection
* Alembic is available for database migrations