]> PHS Git Server - phs-api.git/commitdiff
Setting up model and route indexes.
authorcharleswrayjr <charleswrayjr@gmail.com>
Fri, 12 Sep 2025 03:23:37 +0000 (22:23 -0500)
committercharleswrayjr <charleswrayjr@gmail.com>
Fri, 12 Sep 2025 03:23:37 +0000 (22:23 -0500)
src/models/index.js [new file with mode: 0644]
src/routes/index.js

diff --git a/src/models/index.js b/src/models/index.js
new file mode 100644 (file)
index 0000000..1fd4fd5
--- /dev/null
@@ -0,0 +1,611 @@
+/**
+ * @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
index db18efa37efeb5b02a105d192a8fea703c24278c..70693808c3a0ba764e1736e82f7a719879fe0bc3 100755 (executable)
@@ -7,11 +7,9 @@ module.exports.APIRoutes = ( passport ) => {
   router.use( '/docker', require( './docker.routes' )( passport ) );
   router.use( '/vpn', require( './vpn.routes' )( passport ) );
   router.use( '/users', require( './user.routes' )( passport ) );
-  router.use( '/phone_numbers', require( './phone_numbers.routes' )( passport ) );
+  router.use( '/phone_number', require( './phone_number.routes' )( passport ) );
   router.use( '/user_phone_numbers', require( './user_phone_numbers.routes' )( passport ) );
-  router.use( '/nicknames', require( './nicknames.routes' )( passport ) );
-  router.use( '/user_nicknames', require( './user_nicknames.routes' )( passport ) );
-  router.use( '/addresses', require( './addresses.routes' )( passport ) );
+  router.use( '/address', require( './address.routes' )( passport ) );
   router.use( '/user_addresses', require( './user_addresses.routes' )( passport ) );
   router.use( '/authentication', require( './authentication.routes' )( passport ) );
   return router;