--- /dev/null
+/**
+ * @file Unified database access interface
+ */
+
+const model_cache = new Map();
+
+/**
+ * Get a model class from cache or require it
+ * @param {string} name - Model name
+ * @returns {Function} Model class
+ */
+const get_model = (name) => {
+ if (!model_cache.has(name)) {
+ model_cache.set(name, require(`./${name}.model`));
+ }
+ return model_cache.get(name);
+};
+
+/**
+ * @returns {Function} User model class
+ */
+const get_user_model = () => get_model('user');
+
+/**
+ * @returns {Function} Phone number model class
+ */
+const get_phone_number_model = () => get_model('phone_number');
+
+/**
+ * @returns {Function} User phone numbers model class
+ */
+const get_user_phone_numbers_model = () => get_model('user_phone_numbers');
+
+/**
+ * @returns {Function} Address model class
+ */
+const get_address_model = () => get_model('address');
+
+/**
+ * @returns {Function} User addresses model class
+ */
+const get_user_addresses_model = () => get_model('user_addresses');
+
+/**
+ * @returns {Function} Authentication model class
+ */
+const get_authentication_model = () => get_model('authentication');
+
+/**
+ * Unified database interface
+ * @type {Object}
+ */
+const db = {
+ user: {
+ /**
+ * Create a new user
+ * @param {Object} user_data - User data
+ * @returns {Promise<User>} Created user instance
+ * @throws {ValidationError} If required fields are missing
+ */
+ async create(user_data) {
+ try {
+ return await get_user_model().create(user_data);
+ } catch (error) {
+ logger.error(`Failed to create user: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find user by email
+ * @param {string} email - Email to search for
+ * @param {string[]} [excludes] - Fields to exclude
+ * @returns {Promise<User|null>} User instance or null
+ */
+ async find_by_email(email, excludes) {
+ try {
+ return await get_user_model().find_by_email(email, excludes);
+ } catch (error) {
+ logger.error(`Failed to find user by email: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find user by nickname
+ * @param {string} nickname - Nickname to search for
+ * @param {string[]} [excludes] - Fields to exclude
+ * @returns {Promise<User|null>} User instance or null
+ */
+ async find_by_nickname(nickname, excludes) {
+ try {
+ return await get_user_model().find_by_nickname(nickname, excludes);
+ } catch (error) {
+ logger.error(`Failed to find user by nickname: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find active users
+ * @param {string[]} [excludes] - Fields to exclude
+ * @param {{name: string, direction?: 'asc'|'desc'}||null} [order_by] - Order by configuration
+ * @param {number} [limit] - Maximum number of records
+ * @param {number} [offset] - Number of records to skip
+ * @returns {Promise<User[]>} Array of active users
+ */
+ async find_active(excludes, order_by, limit, offset) {
+ try {
+ return await get_user_model().find_active(excludes, order_by, limit, offset);
+ } catch (error) {
+ logger.error(`Failed to find active users: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find deleted users
+ * @param {string[]} [excludes] - Fields to exclude
+ * @param {{name: string, direction?: 'asc'|'desc'}||null} [order_by] - Order by configuration
+ * @param {number} [limit] - Maximum number of records
+ * @param {number} [offset] - Number of records to skip
+ * @returns {Promise<User[]>} Array of deleted users
+ */
+ async find_deleted(excludes, order_by, limit, offset) {
+ try {
+ return await get_user_model().find_deleted(excludes, order_by, limit, offset);
+ } catch (error) {
+ logger.error(`Failed to find deleted users: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find one user
+ * @param {Object} where - Conditions
+ * @param {string[]} [excludes] - Fields to exclude
+ * @returns {Promise<User|null>} User instance or null
+ */
+ async find_one(where, excludes) {
+ try {
+ return await new (get_user_model())().find_one(where, excludes);
+ } catch (error) {
+ logger.error(`Failed to find one user: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find many users
+ * @param {Object} [where] - Conditions
+ * @param {string[]} [excludes] - Fields to exclude
+ * @param {{name: string, direction?: 'asc'|'desc'}||null} [order_by] - Order by configuration
+ * @param {number} [limit] - Maximum number of records
+ * @param {number} [offset] - Number of records to skip
+ * @returns {Promise<User[]>} Array of users
+ */
+ async find_many(where, excludes, order_by, limit, offset) {
+ try {
+ return await new (get_user_model())().find_many(where, excludes, order_by, limit, offset);
+ } catch (error) {
+ logger.error(`Failed to find many users: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Deactivate user
+ * @param {number|string} id - User ID
+ * @param {number|string} deactivated_by_id - ID of user performing deactivation
+ * @returns {Promise<User>} Updated user instance
+ */
+ async deactivate(id, deactivated_by_id) {
+ try {
+ const user = await new (get_user_model())().find_one({ id }, []);
+ if (!user) throw new Error('User not found');
+ return await user.deactivate(deactivated_by_id);
+ } catch (error) {
+ logger.error(`Failed to deactivate user: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Reactivate user
+ * @param {number|string} id - User ID
+ * @returns {Promise<User>} Updated user instance
+ */
+ async reactivate(id) {
+ try {
+ const user = await new (get_user_model())().find_one({ id }, []);
+ if (!user) throw new Error('User not found');
+ return await user.reactivate();
+ } catch (error) {
+ logger.error(`Failed to reactivate user: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Soft delete user
+ * @param {number|string} id - User ID
+ * @param {number|string} deleted_by_id - ID of user performing deletion
+ * @returns {Promise<User>} Updated user instance
+ */
+ async soft_delete(id, deleted_by_id) {
+ try {
+ const user = await new (get_user_model())().find_one({ id }, []);
+ if (!user) throw new Error('User not found');
+ return await user.soft_delete(deleted_by_id);
+ } catch (error) {
+ logger.error(`Failed to soft delete user: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Create a new User instance
+ * @returns {User} User instance
+ */
+ instance: () => new (get_user_model())()
+ },
+ phone_number: {
+ /**
+ * Create a new phone number
+ * @param {Object} phone_data - Phone number data
+ * @returns {Promise<PhoneNumber>} Created phone number instance
+ * @throws {ValidationError} If required fields are missing
+ */
+ async create(phone_data) {
+ try {
+ return await get_phone_number_model().create(phone_data);
+ } catch (error) {
+ logger.error(`Failed to create phone number: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find phone number by number
+ * @param {string} number - Phone number to search for
+ * @param {string[]} [excludes] - Fields to exclude
+ * @returns {Promise<PhoneNumber|null>} Phone number instance or null
+ */
+ async find_by_number(number, excludes) {
+ try {
+ return await get_phone_number_model().find_by_number(number, excludes);
+ } catch (error) {
+ logger.error(`Failed to find phone number: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find one phone number
+ * @param {Object} where - Conditions
+ * @param {string[]} [excludes] - Fields to exclude
+ * @returns {Promise<PhoneNumber|null>} Phone number instance or null
+ */
+ async find_one(where, excludes) {
+ try {
+ return await new (get_phone_number_model())().find_one(where, excludes);
+ } catch (error) {
+ logger.error(`Failed to find one phone number: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find many phone numbers
+ * @param {Object} [where] - Conditions
+ * @param {string[]} [excludes] - Fields to exclude
+ * @param {{name: string, direction?: 'asc'|'desc'}||null} [order_by] - Order by configuration
+ * @param {number} [limit] - Maximum number of records
+ * @param {number} [offset] - Number of records to skip
+ * @returns {Promise<PhoneNumber[]>} Array of phone numbers
+ */
+ async find_many(where, excludes, order_by, limit, offset) {
+ try {
+ return await new (get_phone_number_model())().find_many(where, excludes, order_by, limit, offset);
+ } catch (error) {
+ logger.error(`Failed to find many phone numbers: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Create a new PhoneNumber instance
+ * @returns {PhoneNumber} PhoneNumber instance
+ */
+ instance: () => new (get_phone_number_model())()
+ },
+ user_phone_numbers: {
+ /**
+ * Add a user-phone number relation
+ * @param {number|string} user_id - User ID
+ * @param {number|string} phone_number_id - Phone number ID
+ * @returns {Promise<UserPhoneNumber>} Created relation instance
+ * @throws {ValidationError} If IDs are invalid
+ */
+ async add_relation(user_id, phone_number_id) {
+ try {
+ return await get_user_phone_numbers_model().add_relation(user_id, phone_number_id);
+ } catch (error) {
+ logger.error(`Failed to add user-phone number relation: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Remove a user-phone number relation
+ * @param {number|string} user_id - User ID
+ * @param {number|string} phone_number_id - Phone number ID
+ * @returns {Promise<UserPhoneNumber|null>} Deleted relation instance or null
+ * @throws {ValidationError} If IDs are invalid
+ */
+ async remove_relation(user_id, phone_number_id) {
+ try {
+ return await get_user_phone_numbers_model().remove_relation(user_id, phone_number_id);
+ } catch (error) {
+ logger.error(`Failed to remove user-phone number relation: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find user-phone number relation by IDs
+ * @param {number|string} user_id - User ID
+ * @param {number|string} phone_number_id - Phone number ID
+ * @param {string[]} [excludes] - Fields to exclude
+ * @returns {Promise<UserPhoneNumber|null>} Relation instance or null
+ */
+ async find_by_ids(user_id, phone_number_id, excludes) {
+ try {
+ return await get_user_phone_numbers_model().find_by_ids(user_id, phone_number_id, excludes);
+ } catch (error) {
+ logger.error(`Failed to find user-phone number by IDs: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find user-phone number relations by user ID
+ * @param {number|string} user_id - User ID
+ * @param {string[]} [excludes] - Fields to exclude
+ * @param {{name: string, direction?: 'asc'|'desc'}||null} [order_by] - Order by configuration
+ * @param {number} [limit] - Maximum number of records
+ * @param {number} [offset] - Number of records to skip
+ * @returns {Promise<UserPhoneNumber[]>} Array of relations
+ */
+ async find_by_user_id(user_id, excludes, order_by, limit, offset) {
+ try {
+ return await get_user_phone_numbers_model().find_by_user_id(user_id, excludes, order_by, limit, offset);
+ } catch (error) {
+ logger.error(`Failed to find user-phone numbers by user ID: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Create a new UserPhoneNumber instance
+ * @returns {UserPhoneNumber} UserPhoneNumber instance
+ */
+ instance: () => new (get_user_phone_numbers_model())()
+ },
+ address: {
+ /**
+ * Create a new address
+ * @param {Object} address_data - Address data
+ * @returns {Promise<Address>} Created address instance
+ * @throws {ValidationError} If required fields are missing
+ */
+ async create(address_data) {
+ try {
+ return await get_address_model().create(address_data);
+ } catch (error) {
+ logger.error(`Failed to create address: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find address by zip code
+ * @param {string} zip_code - Zip code to search for
+ * @param {string[]} [excludes] - Fields to exclude
+ * @returns {Promise<Address|null>} Address instance or null
+ */
+ async find_by_zip_code(zip_code, excludes) {
+ try {
+ return await get_address_model().find_by_zip_code(zip_code, excludes);
+ } catch (error) {
+ logger.error(`Failed to find address by zip code: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find one address
+ * @param {Object} where - Conditions
+ * @param {string[]} [excludes] - Fields to exclude
+ * @returns {Promise<Address|null>} Address instance or null
+ */
+ async find_one(where, excludes) {
+ try {
+ return await new (get_address_model())().find_one(where, excludes);
+ } catch (error) {
+ logger.error(`Failed to find one address: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find many addresses
+ * @param {Object} [where] - Conditions
+ * @param {string[]} [excludes] - Fields to exclude
+ * @param {{name: string, direction?: 'asc'|'desc'}||null} [order_by] - Order by configuration
+ * @param {number} [limit] - Maximum number of records
+ * @param {number} [offset] - Number of records to skip
+ * @returns {Promise<Address[]>} Array of addresses
+ */
+ async find_many(where, excludes, order_by, limit, offset) {
+ try {
+ return await new (get_address_model())().find_many(where, excludes, order_by, limit, offset);
+ } catch (error) {
+ logger.error(`Failed to find many addresses: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Create a new Address instance
+ * @returns {Address} Address instance
+ */
+ instance: () => new (get_address_model())()
+ },
+ user_addresses: {
+ /**
+ * Add a user-address relation
+ * @param {number|string} user_id - User ID
+ * @param {number|string} address_id - Address ID
+ * @returns {Promise<UserAddress>} Created relation instance
+ * @throws {ValidationError} If IDs are invalid
+ */
+ async add_relation(user_id, address_id) {
+ try {
+ return await get_user_addresses_model().add_relation(user_id, address_id);
+ } catch (error) {
+ logger.error(`Failed to add user-address relation: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Remove a user-address relation
+ * @param {number|string} user_id - User ID
+ * @param {number|string} address_id - Address ID
+ * @returns {Promise<UserAddress|null>} Deleted relation instance or null
+ * @throws {ValidationError} If IDs are invalid
+ */
+ async remove_relation(user_id, address_id) {
+ try {
+ return await get_user_addresses_model().remove_relation(user_id, address_id);
+ } catch (error) {
+ logger.error(`Failed to remove user-address relation: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find user-address relation by IDs
+ * @param {number|string} user_id - User ID
+ * @param {number|string} address_id - Address ID
+ * @param {string[]} [excludes] - Fields to exclude
+ * @returns {Promise<UserAddress|null>} Relation instance or null
+ */
+ async find_by_ids(user_id, address_id, excludes) {
+ try {
+ return await get_user_addresses_model().find_by_ids(user_id, address_id, excludes);
+ } catch (error) {
+ logger.error(`Failed to find user-address by IDs: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find user-address relations by user ID
+ * @param {number|string} user_id - User ID
+ * @param {string[]} [excludes] - Fields to exclude
+ * @param {{name: string, direction?: 'asc'|'desc'}||null} [order_by] - Order by configuration
+ * @param {number} [limit] - Maximum number of records
+ * @param {number} [offset] - Number of records to skip
+ * @returns {Promise<UserAddress[]>} Array of relations
+ */
+ async find_by_user_id(user_id, excludes, order_by, limit, offset) {
+ try {
+ return await get_user_addresses_model().find_by_user_id(user_id, excludes, order_by, limit, offset);
+ } catch (error) {
+ logger.error(`Failed to find user-addresses by user ID: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Create a new UserAddress instance
+ * @returns {UserAddress} UserAddress instance
+ */
+ instance: () => new (get_user_addresses_model())()
+ },
+ authentication: {
+ /**
+ * Create a new authentication record
+ * @param {Object} auth_data - Authentication data
+ * @returns {Promise<Authentication>} Created authentication instance
+ * @throws {ValidationError} If required fields are missing
+ */
+ async create(auth_data) {
+ try {
+ return await get_authentication_model().create(auth_data);
+ } catch (error) {
+ logger.error(`Failed to create authentication record: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find authentication record by user ID
+ * @param {number|string} user_id - User ID
+ * @param {string[]} [excludes] - Fields to exclude
+ * @returns {Promise<Authentication|null>} Authentication instance or null
+ */
+ async find_by_user_id(user_id, excludes) {
+ try {
+ return await get_authentication_model().find_by_user_id(user_id, excludes);
+ } catch (error) {
+ logger.error(`Failed to find authentication by user ID: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find authentication record by reset token
+ * @param {string} token - Password reset token
+ * @param {string[]} [excludes] - Fields to exclude
+ * @returns {Promise<Authentication|null>} Authentication instance or null
+ */
+ async find_by_reset_token(token, excludes) {
+ try {
+ return await get_authentication_model().find_by_reset_token(token, excludes);
+ } catch (error) {
+ logger.error(`Failed to find authentication by reset token: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find one authentication record
+ * @param {Object} where - Conditions
+ * @param {string[]} [excludes] - Fields to exclude
+ * @returns {Promise<Authentication|null>} Authentication instance or null
+ */
+ async find_one(where, excludes) {
+ try {
+ return await new (get_authentication_model())().find_one(where, excludes);
+ } catch (error) {
+ logger.error(`Failed to find one authentication record: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Find many authentication records
+ * @param {Object} [where] - Conditions
+ * @param {string[]} [excludes] - Fields to exclude
+ * @param {{name: string, direction?: 'asc'|'desc'}||null} [order_by] - Order by configuration
+ * @param {number} [limit] - Maximum number of records
+ * @param {number} [offset] - Number of records to skip
+ * @returns {Promise<Authentication[]>} Array of authentication records
+ */
+ async find_many(where, excludes, order_by, limit, offset) {
+ try {
+ return await new (get_authentication_model())().find_many(where, excludes, order_by, limit, offset);
+ } catch (error) {
+ logger.error(`Failed to find many authentication records: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Lock authentication account
+ * @param {number|string} id - Authentication ID
+ * @returns {Promise<Authentication>} Updated authentication instance
+ */
+ async lock_account(id) {
+ try {
+ const auth = await new (get_authentication_model())().find_one({ id }, []);
+ if (!auth) throw new Error('Authentication record not found');
+ return await auth.lock_account();
+ } catch (error) {
+ logger.error(`Failed to lock account: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Unlock authentication account
+ * @param {number|string} id - Authentication ID
+ * @returns {Promise<Authentication>} Updated authentication instance
+ */
+ async unlock_account(id) {
+ try {
+ const auth = await new (get_authentication_model())().find_one({ id }, []);
+ if (!auth) throw new Error('Authentication record not found');
+ return await auth.unlock_account();
+ } catch (error) {
+ logger.error(`Failed to unlock account: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Soft delete authentication record
+ * @param {number|string} id - Authentication ID
+ * @param {number|string} deleted_by_id - ID of user performing deletion
+ * @returns {Promise<Authentication>} Updated authentication instance
+ */
+ async soft_delete(id, deleted_by_id) {
+ try {
+ const auth = await new (get_authentication_model())().find_one({ id }, []);
+ if (!auth) throw new Error('Authentication record not found');
+ return await auth.soft_delete(deleted_by_id);
+ } catch (error) {
+ logger.error(`Failed to soft delete authentication: ${error.message}`);
+ throw error;
+ }
+ },
+ /**
+ * Create a new Authentication instance
+ * @returns {Authentication} Authentication instance
+ */
+ instance: () => new (get_authentication_model())()
+ }
+};
+
+module.exports = db;
\ No newline at end of file