# Database Overview - What Your Database is Doing

## Database Purpose

Your PostgreSQL database is the **central data store** for a **Farm Market Authentication Service** that handles:
1. **User Authentication** (Phone-based OTP login)
2. **Farm/Marketplace Data** (Animals, Listings, Locations)
3. **Security & Audit Logging**
4. **Session Management** (Multi-device support)

---

## Table Categories

### 🔐 **AUTHENTICATION TABLES**

#### 1. `users` - User Accounts
**Purpose:** Store user account information
**Key Fields:**
- `id` (UUID) - Primary key
- `phone_number` (UNIQUE) - Phone is the login identifier
- `name` - User's name (can be NULL until profile completed)
- `user_type` - Enum: 'seller', 'buyer', 'service_provider'
- `role` - System role: 'user', 'admin', 'moderator'
- `token_version` - Incremented on logout-all to invalidate all tokens
- `last_login_at` - Tracks last login time

**Current Usage:**
- Created **AFTER** OTP verification (find-or-create pattern)
- Phone number is encrypted before storage
- One phone number = One account (UNIQUE constraint)

#### 2. `otp_codes` - OTP Storage (ACTIVELY USED)
**Purpose:** Store OTP codes for phone verification
**Key Fields:**
- `id` (UUID)
- `phone_number` - Phone requesting OTP (NO user_id - user doesn't exist yet)
- `otp_hash` - Hashed OTP code (bcrypt)
- `expires_at` - OTP expiry (2 minutes default)
- `attempt_count` - Failed verification attempts
- `created_at`

**Current Usage:**
- Created when `/auth/request-otp` is called
- Deleted after successful verification or expiry
- Used for OTP verification in `/auth/verify-otp`

#### 3. `otp_requests` - Legacy OTP Table (NOT ACTIVELY USED)
**Purpose:** Alternative OTP storage (currently unused)
**Note:** Your code uses `otp_codes` table, not `otp_requests`

#### 4. `refresh_tokens` - Session Management
**Purpose:** Store refresh tokens for JWT authentication
**Key Fields:**
- `id` (UUID)
- `user_id` - Links to users table
- `token_id` (UNIQUE) - UUID identifier for token
- `token_hash` - Hashed refresh token (bcrypt)
- `device_id` - Device identifier from client
- `expires_at` - Token expiry
- `revoked_at` - NULL = active, timestamp = revoked
- `rotated_from_id` - Links to previous token (rotation tracking)
- `reuse_detected_at` - Detects token theft/reuse

**Current Usage:**
- Created during OTP verification
- Rotated on each refresh (old token revoked, new one created)
- Tracks which device each token belongs to
- Supports multi-device logins (one token per device)

#### 5. `user_devices` - Device Tracking
**Purpose:** Track user's logged-in devices
**Key Fields:**
- `id` (UUID)
- `user_id` - Links to users
- `device_identifier` - Unique device ID (e.g., Firebase Installation ID)
- `device_platform` - 'android', 'ios'
- `device_model`, `os_version`, `app_version`
- `first_seen_at`, `last_seen_at`
- `is_active` - Whether device session is active
- UNIQUE(`user_id`, `device_identifier`) - One record per user-device pair

**Current Usage:**
- Created/updated during OTP verification
- Tracks all devices a user is logged in from
- Used for device management (view/revoke devices)

#### 6. `auth_audit` - Security Audit Log
**Purpose:** Log all authentication events for security monitoring
**Key Fields:**
- `id` (UUID)
- `user_id` - NULL if user doesn't exist yet (e.g., failed login)
- `action` - 'otp_request', 'otp_verify', 'token_refresh', 'logout', etc.
- `status` - 'success', 'failed', 'error'
- `ip_address`, `user_agent`, `device_id`
- `meta` (JSONB) - Additional metadata (errors, risk scores, etc.)
- `created_at`

**Current Usage:**
- Logs every authentication event
- Used by admin dashboard for security monitoring
- Used for risk scoring and anomaly detection
- Tracks suspicious activities (enumeration, brute force, etc.)

---

### 🏪 **MARKETPLACE TABLES**

#### 7. `species` - Animal Species
**Purpose:** Master data for animal species (e.g., "Cow", "Goat", "Sheep")
**Key Fields:**
- `id` (UUID)
- `name` (UNIQUE)

#### 8. `breeds` - Animal Breeds
**Purpose:** Breeds within each species (e.g., "Holstein", "Jersey" for Cow)
**Key Fields:**
- `id` (UUID)
- `species_id` - Links to species
- `name` - Breed name
- UNIQUE(`species_id`, `name`)

#### 9. `locations` - Geographic Locations
**Purpose:** Store farm/home/office locations
**Key Fields:**
- `id` (UUID)
- `user_id` - Links to users (NULL = temporary/captured location)
- `is_saved_address` - Whether user saved this location
- `location_type` - Enum: 'farm', 'home', 'office', etc.
- `country`, `state`, `district`, `city_village`, `pincode`
- `lat`, `lng` - GPS coordinates
- `source_type` - 'device_gps', 'manual', 'unknown'
- `source_confidence` - 'high', 'medium', 'low'

**Current Usage:**
- Stores where animals are kept
- Stores listing locations
- Can be temporary (no user_id) or saved (with user_id)

#### 10. `animals` - Animal Records
**Purpose:** Store individual animal information
**Key Fields:**
- `id` (UUID)
- `species_id`, `breed_id` - Animal classification
- `location_id` - Where animal is kept
- `sex` - Enum: 'M', 'F', 'Neutered'
- `age_months`, `weight_kg`
- `purpose` - Enum: 'dairy', 'meat', 'breeding', 'pet', 'work', 'other'
- `health_status` - Enum: 'healthy', 'minor_issues', 'serious_issues'
- `vaccinated`, `dewormed`
- `milk_yield_litre_per_day` - For dairy animals
- `ear_tag_no` - Ear tag identification
- `quantity` - Number of animals (default: 1)

**Current Usage:**
- Created by sellers when they want to list animals
- Linked to listings (one animal per listing)

#### 11. `listings` - Marketplace Listings
**Purpose:** Animals for sale/stud service/adoption
**Key Fields:**
- `id` (UUID)
- `seller_id` - Links to users (who is selling)
- `animal_id` - Links to animals (what is being sold)
- `title`, `price`, `currency` (default: 'INR')
- `listing_type` - Enum: 'sale', 'stud_service', 'adoption'
- `status` - Enum: 'active', 'sold', 'expired', 'hidden'
- `is_negotiable` - Price negotiation allowed
- Engagement metrics: `views_count`, `bookmarks_count`, `enquiries_call_count`, `enquiries_whatsapp_count`, `clicks_count`

**Current Usage:**
- Created when seller lists an animal
- Tracked engagement metrics
- Can be marked as sold/expired/hidden

#### 12. `listing_images` - Listing Photos
**Purpose:** Store images for listings
**Key Fields:**
- `id` (UUID)
- `listing_id` - Links to listings
- `image_url` - URL to image
- `is_primary` - Main image flag
- `sort_order` - Image ordering

---

### 🔮 **FUTURE TABLES**

#### 13. `oauth_accounts` - OAuth Integration (Placeholder)
**Purpose:** Future OAuth support (Google, Facebook, Apple)
**Key Fields:**
- `id` (UUID)
- `user_id` - Links to users
- `provider` - 'google', 'facebook', 'apple'
- `provider_user_id` - OAuth provider's user ID
- UNIQUE(`provider`, `provider_user_id`)

**Current Usage:**
- Table exists but not actively used yet

---

## Key Relationships & Constraints

### Foreign Key Relationships:
```
users (1) ──< (many) user_devices
users (1) ──< (many) refresh_tokens
users (1) ──< (many) listings
users (1) ──< (many) locations
listings (1) ──< (many) listing_images
listings (many) ──> (1) animals
animals (many) ──> (1) locations
animals (many) ──> (1) species
animals (many) ──> (1) breeds
breeds (many) ──> (1) species
```

### Cascade Behaviors:
- **DELETE user** → Cascades delete to: `user_devices`, `refresh_tokens`, `listings`, `locations`
- **DELETE species** → RESTRICTED (can't delete if animals reference it)
- **DELETE breed** → Sets `breed_id` to NULL on animals (SET NULL)
- **DELETE listing** → Cascades delete to: `listing_images`
- **DELETE animal** → RESTRICTED (can't delete if listings reference it)
- **DELETE location** → RESTRICTED (can't delete if animals reference it)

---

## Current Data Flow

### Authentication Flow:
```
1. User requests OTP
   └─> INSERT into `otp_codes` (phone_number, otp_hash, expires_at)

2. User verifies OTP
   ├─> Verify OTP from `otp_codes` table
   ├─> DELETE OTP from `otp_codes`
   ├─> FIND or CREATE user in `users` table
   ├─> INSERT/UPDATE `user_devices` table
   ├─> INSERT into `refresh_tokens` table
   └─> INSERT into `auth_audit` (log event)

3. User refreshes token
   ├─> Verify refresh token from `refresh_tokens` table
   ├─> ROTATE token (revoke old, create new)
   └─> INSERT into `auth_audit` (log event)
```

### Marketplace Flow:
```
1. Seller creates listing
   ├─> CREATE `location` (where animal is)
   ├─> CREATE `animal` (animal details)
   └─> CREATE `listing` (link animal to seller)

2. Buyer views listing
   └─> UPDATE `listings.views_count`

3. Buyer bookmarks/contacts
   └─> UPDATE engagement metrics (bookmarks_count, enquiries_*)
```

---

## Database Features

### 1. **Automatic Timestamps**
- All tables have `created_at` and `updated_at`
- `updated_at` automatically updated via database triggers

### 2. **UUID Primary Keys**
- All tables use UUIDs (not auto-increment integers)
- Generated via PostgreSQL `uuid-ossp` extension

### 3. **Enum Types**
- PostgreSQL ENUM types for controlled values:
  - `sex_enum`, `purpose_enum`, `health_status_enum`
  - `location_type_enum`, `listing_type_enum`, `listing_status_enum`
  - `user_type_enum`, `listing_role_enum`

### 4. **Indexes**
- Indexes on foreign keys for fast joins
- Indexes on frequently queried fields (phone_number, expires_at, status)
- Partial indexes for performance (e.g., unconsumed OTPs)

### 5. **Data Integrity**
- CHECK constraints (e.g., non-negative counters)
- UNIQUE constraints (phone_number, user+device pairs)
- Foreign key constraints with appropriate CASCADE/RESTRICT behaviors

---

## What's NOT in the Database (Handled Elsewhere)

1. **Access Tokens (JWT)** - Stored only on client, validated via signature
2. **Rate Limiting Counters** - Stored in Redis or in-memory (not PostgreSQL)
3. **OTP Codes (Plain)** - Only hashed versions stored, plain codes never persisted
4. **SMS Messages** - Sent via Twilio, not stored in database
5. **User Passwords** - Phone-based auth only, no password storage

---

## Current Issues / Design Notes

### ⚠️ Dual OTP Tables
- `otp_codes` - **ACTIVELY USED** by your code
- `otp_requests` - **NOT USED** (legacy/alternative table)
- **Recommendation:** Consider removing `otp_requests` if not needed

### ⚠️ Phone Number Encryption
- Phone numbers in `users` and `otp_codes` are **encrypted at application level**
- Database stores encrypted values, not plaintext
- Encryption handled by `src/utils/fieldEncryption.js`

### ✅ Multi-Device Support
- Users can log in from multiple devices simultaneously
- Each device has its own refresh token
- Devices can be managed (viewed/revoked) via API

### ✅ Security Features
- OTP attempt tracking (prevents brute force)
- Token rotation (prevents token reuse)
- Audit logging (tracks all auth events)
- Risk scoring (detects suspicious activity)

---

## Summary

Your database is a **well-structured PostgreSQL database** that:
- ✅ Handles phone-based authentication securely
- ✅ Supports a farm marketplace (animals, listings, locations)
- ✅ Tracks multi-device user sessions
- ✅ Logs security events for monitoring
- ✅ Uses proper constraints and relationships
- ✅ Supports data encryption at application level

The design follows good practices with UUIDs, enums, cascades, and proper indexing.



