feat: basic db connection
This commit is contained in:
@@ -19,7 +19,7 @@
|
|||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
<!-- Transaction Item -->
|
<!-- Transaction Item -->
|
||||||
@for (transaction of transactions; track transaction.date) {
|
@for (transaction of transactions; track $index) {
|
||||||
<div class="list-group-item">
|
<div class="list-group-item">
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export class ScreenProfile implements OnInit{
|
|||||||
constructor(private api: APIService){}
|
constructor(private api: APIService){}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
// FIXME transactions displaying delayed (only on second nav click)
|
||||||
this.api.getTransactions().subscribe({
|
this.api.getTransactions().subscribe({
|
||||||
next: (transactions) => {
|
next: (transactions) => {
|
||||||
this.transactions = transactions;
|
this.transactions = transactions;
|
||||||
|
|||||||
51
package-lock.json
generated
51
package-lock.json
generated
@@ -8614,14 +8614,14 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/pg": {
|
"node_modules/pg": {
|
||||||
"version": "8.19.0",
|
"version": "8.20.0",
|
||||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz",
|
||||||
"integrity": "sha512-QIcLGi508BAHkQ3pJNptsFz5WQMlpGbuBGBaIaXsWK8mel2kQ/rThYI+DbgjUvZrIr7MiuEuc9LcChJoEZK1xQ==",
|
"integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pg-connection-string": "^2.11.0",
|
"pg-connection-string": "^2.12.0",
|
||||||
"pg-pool": "^3.12.0",
|
"pg-pool": "^3.13.0",
|
||||||
"pg-protocol": "^1.12.0",
|
"pg-protocol": "^1.13.0",
|
||||||
"pg-types": "2.2.0",
|
"pg-types": "2.2.0",
|
||||||
"pgpass": "1.0.5"
|
"pgpass": "1.0.5"
|
||||||
},
|
},
|
||||||
@@ -8648,11 +8648,23 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"node_modules/pg-connection-string": {
|
"node_modules/pg-connection-string": {
|
||||||
"version": "2.11.0",
|
"version": "2.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.12.0.tgz",
|
||||||
"integrity": "sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==",
|
"integrity": "sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/pg-hstore": {
|
||||||
|
"version": "2.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.4.tgz",
|
||||||
|
"integrity": "sha512-N3SGs/Rf+xA1M2/n0JBiXFDVMzdekwLZLAO0g7mpDY9ouX+fDI7jS6kTq3JujmYbtNSJ53TJ0q4G98KVZSM4EA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"underscore": "^1.13.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/pg-int8": {
|
"node_modules/pg-int8": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
|
||||||
@@ -8663,18 +8675,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pg-pool": {
|
"node_modules/pg-pool": {
|
||||||
"version": "3.12.0",
|
"version": "3.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.13.0.tgz",
|
||||||
"integrity": "sha512-eIJ0DES8BLaziFHW7VgJEBPi5hg3Nyng5iKpYtj3wbcAUV9A1wLgWiY7ajf/f/oO1wfxt83phXPY8Emztg7ITg==",
|
"integrity": "sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"pg": ">=8.0"
|
"pg": ">=8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pg-protocol": {
|
"node_modules/pg-protocol": {
|
||||||
"version": "1.12.0",
|
"version": "1.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz",
|
||||||
"integrity": "sha512-uOANXNRACNdElMXJ0tPz6RBM0XQ61nONGAwlt8da5zs/iUOOCLBQOHSXnrC6fMsvtjxbOJrZZl5IScGv+7mpbg==",
|
"integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/pg-types": {
|
"node_modules/pg-types": {
|
||||||
@@ -10209,6 +10221,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/underscore": {
|
||||||
|
"version": "1.13.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz",
|
||||||
|
"integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "7.22.0",
|
"version": "7.22.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz",
|
||||||
@@ -10870,7 +10888,8 @@
|
|||||||
"cors": "^2.8.6",
|
"cors": "^2.8.6",
|
||||||
"dotenv": "^17.3.1",
|
"dotenv": "^17.3.1",
|
||||||
"express": "^5.2.1",
|
"express": "^5.2.1",
|
||||||
"pg": "^8.19.0",
|
"pg": "^8.20.0",
|
||||||
|
"pg-hstore": "^2.3.4",
|
||||||
"sequelize": "^6.37.7"
|
"sequelize": "^6.37.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
17
server/compose.yml
Normal file
17
server/compose.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: pass
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
|
||||||
|
adminer:
|
||||||
|
image: adminer
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
ADMINER_DEFAULT_SERVER: postgres # Automatically connect to the "postgres" service
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
depends_on:
|
||||||
|
- postgres # Ensure PostgreSQL starts first
|
||||||
@@ -8,16 +8,20 @@
|
|||||||
"main": "../dist/out-tsc/server/index.js",
|
"main": "../dist/out-tsc/server/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"dev": "nodemon",
|
"node": "nodemon",
|
||||||
"start": "ts-node src/index.ts",
|
"start": "ts-node src/index.ts",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"serve": "node ../dist/out-tsc/server/index.js"
|
"serve": "node ../dist/out-tsc/server/index.js",
|
||||||
|
"setup": "docker compose up -d",
|
||||||
|
"teardown": "docker compose down",
|
||||||
|
"dev": "npm run setup && npm run node; npm run teardown"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cors": "^2.8.6",
|
"cors": "^2.8.6",
|
||||||
"dotenv": "^17.3.1",
|
"dotenv": "^17.3.1",
|
||||||
"express": "^5.2.1",
|
"express": "^5.2.1",
|
||||||
"pg": "^8.19.0",
|
"pg": "^8.20.0",
|
||||||
|
"pg-hstore": "^2.3.4",
|
||||||
"sequelize": "^6.37.7"
|
"sequelize": "^6.37.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,7 +1,26 @@
|
|||||||
const { Pool } = require("pg");
|
import { Sequelize } from 'sequelize';
|
||||||
|
|
||||||
const pool = new Pool({
|
// Initialize Sequelize
|
||||||
connectionString: process.env.DATABASE_URL,
|
const db = new Sequelize({
|
||||||
|
dialect: 'postgres',
|
||||||
|
host: process.env.DB_HOST || 'localhost',
|
||||||
|
port: parseInt(process.env.DB_PORT || '5432'),
|
||||||
|
database: process.env.DB_NAME || 'postgres',
|
||||||
|
username: process.env.DB_USER || 'postgres',
|
||||||
|
password: process.env.DB_PASSWORD || 'pass',
|
||||||
|
logging: false, // Disable logging in production
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = pool;
|
// Test the connection
|
||||||
|
async function testConnection() {
|
||||||
|
try {
|
||||||
|
await db.authenticate();
|
||||||
|
console.log('✅ Database connection established.');
|
||||||
|
} catch (err) {
|
||||||
|
console.error('❌ Unable to connect to the database:', err);
|
||||||
|
process.exit(1); // Exit if DB connection fails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export Sequelize instance and models
|
||||||
|
export { db, testConnection };
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import express, { Express, Request, Response } from "express";
|
|||||||
import cors from "cors";
|
import cors from "cors";
|
||||||
import * as dotenv from "dotenv";
|
import * as dotenv from "dotenv";
|
||||||
import transactionsRouter from './routes/transactions';
|
import transactionsRouter from './routes/transactions';
|
||||||
|
import { db, testConnection } from "./db";
|
||||||
|
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
@@ -17,6 +18,19 @@ app.get("/api/health", (req: Request, res: Response) => {
|
|||||||
app.use('/api/transactions', transactionsRouter);
|
app.use('/api/transactions', transactionsRouter);
|
||||||
|
|
||||||
const PORT: number = parseInt(process.env.PORT as string) || 3000;
|
const PORT: number = parseInt(process.env.PORT as string) || 3000;
|
||||||
|
|
||||||
|
// Start server after DB connection is established
|
||||||
|
async function startServer() {
|
||||||
|
await testConnection(); // Test DB connection first
|
||||||
|
|
||||||
|
// Sync models (use migrations in production!)
|
||||||
|
await db.sync({ alter: true }); // Use { force: true } to drop and recreate tables (development only!)
|
||||||
|
|
||||||
app.listen(PORT, () => {
|
app.listen(PORT, () => {
|
||||||
console.log(`Server running on port ${PORT}`);
|
console.log(`🚀 Backend Server running on http://localhost:${PORT}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
startServer().catch((err) => {
|
||||||
|
console.error('Failed to start server:', err);
|
||||||
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user