diff --git a/fems-api/package.json b/fems-api/package.json index d783b38..26efe7e 100644 --- a/fems-api/package.json +++ b/fems-api/package.json @@ -11,6 +11,7 @@ "test": "jest" }, "dependencies": { + "axios": "^1.7.7", "bcryptjs": "^2.4.3", "cors": "^2.8.5", "crypto": "^1.0.1", diff --git a/fems-api/yarn.lock b/fems-api/yarn.lock index ea09a38..4de7e0a 100644 --- a/fems-api/yarn.lock +++ b/fems-api/yarn.lock @@ -856,6 +856,15 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +axios@^1.7.7: + version "1.7.7" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f" + integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -1739,6 +1748,11 @@ fn.name@1.x.x: resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== +follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + form-data@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48" @@ -3203,6 +3217,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + pstree.remy@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" diff --git a/fems-realtime-api/src/models/SensorData.js b/fems-realtime-api/src/models/SensorData.js new file mode 100644 index 0000000..c569ab5 --- /dev/null +++ b/fems-realtime-api/src/models/SensorData.js @@ -0,0 +1,46 @@ +// realtime-backend/src/models/SensorData.js +class SensorDataModel { + constructor(pool) { + this.pool = pool; + } + + async initialize() { + await this.pool.query(` + CREATE TABLE IF NOT EXISTS sensor_data ( + time TIMESTAMPTZ NOT NULL, + company_id UUID NOT NULL, + device_id VARCHAR(50) NOT NULL, + data_type VARCHAR(50) NOT NULL, + value DOUBLE PRECISION NOT NULL, + metadata JSONB, + CONSTRAINT sensor_data_pk PRIMARY KEY (time, company_id, device_id) + ); + + SELECT create_hypertable('sensor_data', 'time', + chunk_time_interval => INTERVAL '1 day', + if_not_exists => TRUE + ); + + CREATE INDEX IF NOT EXISTS idx_sensor_company_device + ON sensor_data (company_id, device_id, time DESC); + `); + } + + async insert(data) { + const query = ` + INSERT INTO sensor_data (time, company_id, device_id, data_type, value, metadata) + VALUES ($1, $2, $3, $4, $5, $6) + `; + + await this.pool.query(query, [ + data.time, + data.companyId, + data.deviceId, + data.dataType, + data.value, + data.metadata, + ]); + } +} + +module.exports = SensorDataModel;