@@ -7,12 +7,15 @@ const pool = new Pool({
77 database : process . env . POSTGRES_DB ,
88 password : process . env . POSTGRES_PASSWORD ,
99 port : Number ( process . env . POSTGRES_PORT || 5432 ) ,
10- max : 20 ,
11- min : 5 ,
12- idleTimeoutMillis : 30000 ,
13- connectionTimeoutMillis : 10000 ,
14- statement_timeout : 30000 ,
10+ max : 100 ,
11+ min : 10 ,
12+ idleTimeoutMillis : 10000 ,
13+ connectionTimeoutMillis : 3000 ,
14+ statement_timeout : 5000 ,
15+ query_timeout : 5000 ,
1516 application_name : "simradar24-api" ,
17+ keepAlive : true ,
18+ keepAliveInitialDelayMillis : 10000 ,
1619} ) ;
1720
1821pool . on ( "error" , ( err ) => {
@@ -41,40 +44,39 @@ export async function pgShutdown(): Promise<void> {
4144}
4245
4346export async function pgInitTrackPointsTable ( ) {
44- const createTableQuery = `
47+ try {
48+ await pool . query ( `
4549 CREATE TABLE IF NOT EXISTS track_points (
46- id TEXT NOT NULL,
50+ id VARCHAR(10) NOT NULL,
4751 timestamp TIMESTAMPTZ NOT NULL,
4852 latitude DOUBLE PRECISION NOT NULL,
4953 longitude DOUBLE PRECISION NOT NULL,
50- altitude_agl DOUBLE PRECISION ,
51- altitude_ms DOUBLE PRECISION ,
52- groundspeed DOUBLE PRECISION ,
53- vertical_speed DOUBLE PRECISION ,
54- heading DOUBLE PRECISION ,
54+ altitude_agl INTEGER ,
55+ altitude_ms INTEGER ,
56+ groundspeed INTEGER ,
57+ vertical_speed INTEGER ,
58+ heading INTEGER ,
5559 PRIMARY KEY (id, timestamp)
5660 );
57- ` ;
58-
59- try {
60- await pool . query ( `CREATE EXTENSION IF NOT EXISTS timescaledb;` ) ;
61- await pool . query ( createTableQuery ) ;
62- await pool . query ( `SELECT create_hypertable('track_points', 'timestamp', if_not_exists => TRUE);` ) ;
61+ ` ) ;
6362
64- const res = await pool . query ( `
65- SELECT job_id
66- FROM timescaledb_information.jobs
67- WHERE hypertable_name = 'track_points'
68- AND proc_name = 'policy_retention'
63+ // Critical: Create index on id column for fast lookups
64+ await pool . query ( `
65+ CREATE INDEX IF NOT EXISTS idx_track_points_id_timestamp
66+ ON track_points (id, timestamp DESC);
6967 ` ) ;
7068
71- if ( res . rows . length === 0 ) {
72- await pool . query ( `SELECT add_retention_policy('track_points', INTERVAL '2 days')` ) ;
73- }
69+ // Convert to hypertable
70+ await pool . query ( `
71+ SELECT create_hypertable('track_points', 'timestamp',
72+ chunk_time_interval => INTERVAL '1 day',
73+ if_not_exists => TRUE
74+ );
75+ ` ) ;
7476
75- console . log ( "track_points table is ready ✅ " ) ;
77+ console . log ( "✅ Track points table initialized with index " ) ;
7678 } catch ( err ) {
77- console . error ( "Error initializing track_points table:" , err ) ;
79+ console . error ( "❌ Error initializing track_points table:" , err ) ;
7880 throw err ;
7981 }
8082}
@@ -122,12 +124,15 @@ export async function pgGetTrackPointsByid(id: string): Promise<TrackPoint[]> {
122124 throw new Error ( "Invalid track ID" ) ;
123125 }
124126
127+ // Use pool.query instead of getting a client
128+ // This is faster for simple queries
125129 const query = `
126- SELECT id, timestamp, latitude, longitude, altitude_agl, altitude_ms, groundspeed, vertical_speed, heading
130+ SELECT id, timestamp, latitude, longitude, altitude_agl, altitude_ms,
131+ groundspeed, vertical_speed, heading
127132 FROM track_points
128133 WHERE id = $1
129134 ORDER BY timestamp ASC
130- LIMIT 100000
135+ LIMIT 5000
131136 ` ;
132137
133138 const { rows } = await pool . query ( query , [ id ] ) ;
0 commit comments