| import { |
| sqliteTable, |
| text, |
| integer, |
| real, |
| primaryKey, |
| } from 'drizzle-orm/sqlite-core'; |
| import { sql } from 'drizzle-orm'; |
|
|
| |
| |
|
|
| export const currentUser = sqliteTable('current_user', { |
| id: text('id').primaryKey(), |
| phone: text('phone').notNull(), |
| fullName: text('full_name').notNull(), |
| email: text('email'), |
| avatarUrl: text('avatar_url'), |
| gender: text('gender', { enum: ['male', 'female', 'other'] }), |
| homeAddress: text('home_address'), |
| workAddress: text('work_address'), |
| preferredLanguage: text('preferred_language').default('en'), |
| rating: real('rating').default(0), |
| totalRides: integer('total_rides').default(0), |
| verified: integer('verified', { mode: 'boolean' }).default(false), |
| createdAt: text('created_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| updatedAt: text('updated_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| }); |
|
|
| |
|
|
| export const savedLocations = sqliteTable('saved_locations', { |
| id: text('id').primaryKey(), |
| userId: text('user_id') |
| .notNull() |
| .references(() => currentUser.id, { onDelete: 'cascade' }), |
| name: text('name').notNull(), |
| address: text('address').notNull(), |
| latitude: real('latitude').notNull(), |
| longitude: real('longitude').notNull(), |
| type: text('type', { |
| enum: ['home', 'work', 'favorite', 'recent'], |
| }).default('favorite'), |
| createdAt: text('created_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| }); |
|
|
| |
|
|
| export const rides = sqliteTable('rides', { |
| id: text('id').primaryKey(), |
| userId: text('user_id') |
| .notNull() |
| .references(() => currentUser.id, { onDelete: 'cascade' }), |
| originAddress: text('origin_address').notNull(), |
| originLatitude: real('origin_latitude').notNull(), |
| originLongitude: real('origin_longitude').notNull(), |
| destinationAddress: text('destination_address').notNull(), |
| destinationLatitude: real('destination_latitude').notNull(), |
| destinationLongitude: real('destination_longitude').notNull(), |
| routePolyline: text('route_polyline'), |
| scheduledTime: text('scheduled_time'), |
| status: text('status', { |
| enum: [ |
| 'searching', |
| 'matched', |
| 'in_progress', |
| 'completed', |
| 'cancelled', |
| ], |
| }) |
| .notNull() |
| .default('searching'), |
| seatPrice: real('seat_price'), |
| totalDistance: real('total_distance'), |
| estimatedDuration: integer('estimated_duration'), |
| createdAt: text('created_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| updatedAt: text('updated_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| }); |
|
|
| |
|
|
| export const matches = sqliteTable('matches', { |
| id: text('id').primaryKey(), |
| rideId: text('ride_id') |
| .notNull() |
| .references(() => rides.id, { onDelete: 'cascade' }), |
| matchedUserId: text('matched_user_id').notNull(), |
| matchedUserFullName: text('matched_user_full_name').notNull(), |
| matchedUserAvatar: text('matched_user_avatar'), |
| matchedUserRating: real('matched_user_rating').default(0), |
| pickupPoint: text('pickup_point'), |
| pickupLatitude: real('pickup_latitude'), |
| pickupLongitude: real('pickup_longitude'), |
| dropoffPoint: text('dropoff_point'), |
| dropoffLatitude: real('dropoff_latitude'), |
| dropoffLongitude: real('dropoff_longitude'), |
| status: text('status', { |
| enum: ['pending', 'accepted', 'rejected', 'completed', 'cancelled'], |
| }) |
| .notNull() |
| .default('pending'), |
| createdAt: text('created_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| updatedAt: text('updated_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| }); |
|
|
| |
|
|
| export const conversations = sqliteTable('conversations', { |
| id: text('id').primaryKey(), |
| participant1Id: text('participant_1_id').notNull(), |
| participant2Id: text('participant_2_id').notNull(), |
| lastMessage: text('last_message'), |
| lastMessageAt: text('last_message_at'), |
| unreadCount: integer('unread_count').default(0), |
| createdAt: text('created_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| updatedAt: text('updated_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| }); |
|
|
| |
|
|
| export const messages = sqliteTable('messages', { |
| id: text('id').primaryKey(), |
| conversationId: text('conversation_id') |
| .notNull() |
| .references(() => conversations.id, { onDelete: 'cascade' }), |
| senderId: text('sender_id').notNull(), |
| content: text('content').notNull(), |
| type: text('type', { enum: ['text', 'image', 'location', 'system'] }) |
| .notNull() |
| .default('text'), |
| status: text('status', { |
| enum: ['sending', 'sent', 'delivered', 'read', 'failed'], |
| }) |
| .notNull() |
| .default('sending'), |
| createdAt: text('created_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| }); |
|
|
| |
|
|
| export const friends = sqliteTable('friends', { |
| id: text('id').primaryKey(), |
| userId: text('user_id') |
| .notNull() |
| .references(() => currentUser.id, { onDelete: 'cascade' }), |
| friendId: text('friend_id').notNull(), |
| friendFullName: text('friend_full_name').notNull(), |
| friendAvatar: text('friend_avatar'), |
| friendPhone: text('friend_phone'), |
| status: text('status', { |
| enum: ['pending', 'accepted', 'blocked'], |
| }) |
| .notNull() |
| .default('pending'), |
| createdAt: text('created_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| }); |
|
|
| |
|
|
| export const ratings = sqliteTable('ratings', { |
| id: text('id').primaryKey(), |
| rideId: text('ride_id') |
| .notNull() |
| .references(() => rides.id, { onDelete: 'cascade' }), |
| fromUserId: text('from_user_id').notNull(), |
| toUserId: text('to_user_id').notNull(), |
| score: integer('score').notNull(), |
| review: text('review'), |
| createdAt: text('created_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| }); |
|
|
| |
|
|
| export const notifications = sqliteTable('notifications', { |
| id: text('id').primaryKey(), |
| userId: text('user_id') |
| .notNull() |
| .references(() => currentUser.id, { onDelete: 'cascade' }), |
| type: text('type', { |
| enum: [ |
| 'ride_matched', |
| 'ride_cancelled', |
| 'ride_completed', |
| 'message', |
| 'friend_request', |
| 'system', |
| ], |
| }).notNull(), |
| title: text('title').notNull(), |
| body: text('body').notNull(), |
| data: text('data'), |
| read: integer('read', { mode: 'boolean' }).default(false), |
| createdAt: text('created_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| }); |
|
|
| |
|
|
| export const searchHistory = sqliteTable('search_history', { |
| id: text('id').primaryKey(), |
| userId: text('user_id') |
| .notNull() |
| .references(() => currentUser.id, { onDelete: 'cascade' }), |
| query: text('query').notNull(), |
| address: text('address').notNull(), |
| latitude: real('latitude').notNull(), |
| longitude: real('longitude').notNull(), |
| searchedAt: text('searched_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| }); |
|
|
| |
| |
|
|
| export const appState = sqliteTable('app_state', { |
| key: text('key').primaryKey(), |
| value: text('value').notNull(), |
| updatedAt: text('updated_at') |
| .notNull() |
| .default(sql`(datetime('now'))`), |
| }); |
|
|