# 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.