342 lines
11 KiB
Markdown
342 lines
11 KiB
Markdown
# 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.
|
|
|
|
|