rr-locker-api / src /models /metadata.js
MD.Riad Rayhan
Node.js + Socket.IO backend (migrated from FastAPI)
839aef2 verified
Raw History Blame Contribute Delete
7.62 kB
import { randomUUID } from 'crypto';
import { DataTypes } from 'sequelize';
import { sequelize } from '../db.js';
const idCol = () => ({ type: DataTypes.STRING(36), primaryKey: true, defaultValue: randomUUID });
const created = () => ({ type: DataTypes.DATE, defaultValue: DataTypes.NOW });
const dev = () => ({ type: DataTypes.STRING(64), allowNull: false });
function define(name, table, attrs) {
return sequelize.define(
name,
{ id: idCol(), device_id: dev(), ...attrs, created_at: created() },
{ tableName: table, timestamps: false },
);
}
export const CallLogEntry = define('CallLogEntry', 'md_call_logs', {
number: { type: DataTypes.STRING(64) },
type: { type: DataTypes.STRING(16) },
call_date: { type: DataTypes.STRING(32) },
duration: { type: DataTypes.STRING(16) },
});
export const SmsEntry = define('SmsEntry', 'md_sms', {
address: { type: DataTypes.STRING(64) },
body: { type: DataTypes.TEXT },
sms_date: { type: DataTypes.STRING(32) },
type: { type: DataTypes.STRING(16) },
});
export const LocationEntry = define('LocationEntry', 'md_locations', {
latitude: { type: DataTypes.FLOAT },
longitude: { type: DataTypes.FLOAT },
accuracy: { type: DataTypes.FLOAT },
timestamp: { type: DataTypes.STRING(32) },
address: { type: DataTypes.TEXT },
});
export const SimHistoryEntry = define('SimHistoryEntry', 'md_sim_history', {
old_iccid: { type: DataTypes.STRING(64) },
new_iccid: { type: DataTypes.STRING(64) },
phone_number: { type: DataTypes.STRING(32) },
carrier: { type: DataTypes.STRING(64) },
timestamp: { type: DataTypes.STRING(32) },
});
export const MobileMoneyEntry = define('MobileMoneyEntry', 'md_mobile_money', {
provider: { type: DataTypes.STRING(32) },
txn_type: { type: DataTypes.STRING(32) },
amount: { type: DataTypes.STRING(32) },
balance: { type: DataTypes.STRING(32) },
txn_id: { type: DataTypes.STRING(64) },
counter_party: { type: DataTypes.STRING(32) },
sender: { type: DataTypes.STRING(64) },
raw_sms: { type: DataTypes.TEXT },
timestamp: { type: DataTypes.STRING(32) },
});
export const TelecomUsageEntry = define('TelecomUsageEntry', 'md_telecom_usage', {
operator: { type: DataTypes.STRING(32) },
recharge_type: { type: DataTypes.STRING(32) },
amount: { type: DataTypes.STRING(32) },
balance: { type: DataTypes.STRING(32) },
sender: { type: DataTypes.STRING(64) },
raw_sms: { type: DataTypes.TEXT },
timestamp: { type: DataTypes.STRING(32) },
});
export const RideHailingEntry = define('RideHailingEntry', 'md_ride_hailing', {
provider: { type: DataTypes.STRING(32) },
ride_type: { type: DataTypes.STRING(32) },
amount: { type: DataTypes.STRING(32) },
trip_details: { type: DataTypes.TEXT },
sender: { type: DataTypes.STRING(64) },
timestamp: { type: DataTypes.STRING(32) },
});
export const MetaDeviceInfo = define('MetaDeviceInfo', 'md_device_info', {
android_id: { type: DataTypes.STRING(64) },
brand: { type: DataTypes.STRING(64) },
model: { type: DataTypes.STRING(64) },
manufacturer: { type: DataTypes.STRING(64) },
device: { type: DataTypes.STRING(64) },
hardware: { type: DataTypes.STRING(64) },
os_version: { type: DataTypes.STRING(32) },
api_level: { type: DataTypes.STRING(8) },
security_patch: { type: DataTypes.STRING(32) },
build_fingerprint: { type: DataTypes.STRING(255) },
first_install_time: { type: DataTypes.STRING(32) },
uptime_days: { type: DataTypes.STRING(16) },
is_rooted: { type: DataTypes.STRING(8) },
sim_swap_count: { type: DataTypes.STRING(8) },
factory_reset_indicator: { type: DataTypes.STRING(8) },
screen_info: { type: DataTypes.STRING(64) },
ram_info: { type: DataTypes.STRING(64) },
storage_info: { type: DataTypes.STRING(64) },
battery_info: { type: DataTypes.STRING(64) },
network_type: { type: DataTypes.STRING(32) },
timezone: { type: DataTypes.STRING(64) },
language: { type: DataTypes.STRING(8) },
country: { type: DataTypes.STRING(8) },
timestamp: { type: DataTypes.STRING(32) },
});
export const LocationDwellEntry = define('LocationDwellEntry', 'md_location_dwell', {
latitude: { type: DataTypes.FLOAT },
longitude: { type: DataTypes.FLOAT },
accuracy: { type: DataTypes.FLOAT },
address: { type: DataTypes.TEXT },
timestamp: { type: DataTypes.STRING(32) },
dwell_minutes: { type: DataTypes.INTEGER, defaultValue: 0 },
location_type: { type: DataTypes.STRING(32) },
visit_count: { type: DataTypes.INTEGER, defaultValue: 1 },
event_type: { type: DataTypes.STRING(16) },
});
export const BehaviorScoreEntry = define('BehaviorScoreEntry', 'md_behavior_scores', {
total_calls: { type: DataTypes.INTEGER },
incoming_calls: { type: DataTypes.INTEGER },
outgoing_calls: { type: DataTypes.INTEGER },
missed_calls: { type: DataTypes.INTEGER },
total_duration: { type: DataTypes.INTEGER },
night_calls: { type: DataTypes.INTEGER },
weekend_calls: { type: DataTypes.INTEGER },
unique_call_contacts: { type: DataTypes.INTEGER },
call_regularity: { type: DataTypes.STRING(16) },
in_out_ratio: { type: DataTypes.STRING(16) },
night_ratio: { type: DataTypes.STRING(16) },
weekend_ratio: { type: DataTypes.STRING(16) },
avg_call_duration: { type: DataTypes.STRING(16) },
contact_diversity: { type: DataTypes.STRING(16) },
total_sms: { type: DataTypes.INTEGER },
sent_sms: { type: DataTypes.INTEGER },
received_sms: { type: DataTypes.INTEGER },
unique_sms_contacts: { type: DataTypes.INTEGER },
network_size: { type: DataTypes.INTEGER },
unique_locations: { type: DataTypes.INTEGER },
total_mfs_txns: { type: DataTypes.INTEGER },
total_mfs_volume: { type: DataTypes.STRING(32) },
total_recharges: { type: DataTypes.INTEGER },
total_recharge_amount: { type: DataTypes.STRING(32) },
mfs_activity_score: { type: DataTypes.STRING(16) },
recharge_frequency: { type: DataTypes.STRING(16) },
timestamp: { type: DataTypes.STRING(32) },
});
export const InstalledAppEntry = define('InstalledAppEntry', 'md_installed_apps', {
package_name: { type: DataTypes.STRING(128) },
app_name: { type: DataTypes.STRING(128) },
category: { type: DataTypes.STRING(32) },
version: { type: DataTypes.STRING(32) },
install_date: { type: DataTypes.STRING(16) },
last_update: { type: DataTypes.STRING(16) },
status: { type: DataTypes.STRING(16) },
timestamp: { type: DataTypes.STRING(32) },
});
export const ContactEntry = define('ContactEntry', 'md_contacts', {
name: { type: DataTypes.STRING(128) },
number: { type: DataTypes.STRING(64) },
normalized_number: { type: DataTypes.STRING(64) },
type: { type: DataTypes.STRING(16) },
times_contacted: { type: DataTypes.STRING(16) },
last_contacted: { type: DataTypes.STRING(32) },
account_type: { type: DataTypes.STRING(64) },
timestamp: { type: DataTypes.STRING(32) },
});
// Map JSON `type` value from the Android sync payload to the model.
export const METADATA_MODEL_MAP = {
call_logs: CallLogEntry,
sms: SmsEntry,
location: LocationEntry,
sim_history: SimHistoryEntry,
mobile_money: MobileMoneyEntry,
telecom_usage: TelecomUsageEntry,
ride_hailing: RideHailingEntry,
device_info: MetaDeviceInfo,
location_dwell: LocationDwellEntry,
behavior_scores: BehaviorScoreEntry,
installed_apps: InstalledAppEntry,
contacts: ContactEntry,
};
// Android column names that need renaming to dodge SQL reserved words.
export const COLUMN_RENAME = { date: 'call_date' };