Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
d3e2dea
TAB #18 Ajout d'une page de connexion pour l'utilisateur
GuillaumeDelferiere Mar 13, 2025
2d9fde3
TAB #17 création utilisateur au niveau du backend
GuillaumeDelferiere Mar 19, 2025
902db80
TAB #17 création utilisateur au niveau du frontend
GuillaumeDelferiere Mar 19, 2025
c14e410
TAB #17 création utilisateur au niveau du frontend
GuillaumeDelferiere Mar 19, 2025
2e1083a
TAB #19 création utilisateur au niveau du frontend
GuillaumeDelferiere Mar 19, 2025
6697c17
TAB #19 création utilisateur au niveau du frontend
GuillaumeDelferiere Mar 27, 2025
81090af
update ui shadcn
GuillaumeDelferiere Mar 27, 2025
2ae0224
Merge branch 'developement' into Authentification
GuillaumeDelferiere Mar 28, 2025
b01e06c
Merge branch 'developement' into Authentification
GuillaumeDelferiere Mar 28, 2025
e94bd32
TAB #21 création de la table interets
GuillaumeDelferiere Mar 28, 2025
862c202
✨Creation of the reservation page. #23 #24
CianCode Mar 28, 2025
0ba2646
Merge pull request #47 from Tablify-Developement/feature_home_page
CianCode Mar 28, 2025
ebdd7de
Merge branch 'developement' into feature_reservation_page
CianCode Mar 28, 2025
1b67c67
TAB #19 update controller, model, routes et services
GuillaumeDelferiere Mar 28, 2025
c5afb1f
TAB #19 update date naissance
GuillaumeDelferiere Mar 28, 2025
64ec45f
✨Modification of the home page for the booking systhem. #44
CianCode Mar 28, 2025
4e3ec41
Merge pull request #48 from Tablify-Developement/Authentification
GuillaumeDelferiere Mar 28, 2025
3219694
✨Creation of the UI for the login and register page. #19
CianCode Mar 28, 2025
a3f4be7
TAB #20 page frontend pour l'update des informations utilisateur
GuillaumeDelferiere Mar 28, 2025
4995ac6
Merge pull request #49 from Tablify-Developement/feature_authentifica…
CianCode Mar 28, 2025
26bdef0
Merge pull request #50 from Tablify-Developement/features/settings-an…
GuillaumeDelferiere Mar 28, 2025
ebb0d03
✨Securisation des route et implementation du compte dans le dashboard
CianCode Mar 28, 2025
118375f
Merge pull request #51 from Tablify-Developement/feature_authentifica…
CianCode Mar 28, 2025
56dcaaf
Merge branch 'developement' into feature_reservation_page
CianCode Mar 28, 2025
75c836b
✨Affichage de tout les restaurants dans la base de donner
CianCode Mar 28, 2025
befd7d4
✨Changement du systhem de reservation avec selection de table
CianCode Mar 28, 2025
ec2af72
Merge pull request #52 from Tablify-Developement/feature_reservation_…
CianCode Mar 28, 2025
5125889
✨Migration pour avoir une base en local et creation des fichier pour …
CianCode Mar 29, 2025
0b74e5b
Merge pull request #53 from Tablify-Developement/feature_migration_lo…
CianCode Mar 29, 2025
8cb85c3
Create .env.example
CianCode Mar 31, 2025
7850436
✨Modification du Dockerfile
CianCode Mar 31, 2025
ad28d3f
Merge remote-tracking branch 'origin/production' into production
CianCode Mar 31, 2025
c038bb4
✨Modification des api url
CianCode Mar 31, 2025
13a2f69
✨Modification du systheme de data fetching
CianCode Apr 3, 2025
7610c47
✨Reservation #35 #36
CianCode Apr 10, 2025
188873f
Merge pull request #55 from Tablify-Developement/production
CianCode Apr 10, 2025
4294b59
✨Fix reservation Tab #35 #36
CianCode Apr 10, 2025
6207875
feat: ajout du service de confirmation par e-mail (fixes #25)
seignif Apr 28, 2025
66c1f03
feat: ajout de l'envoi d'email lors de l'annulation de réservation(fi…
seignif Apr 29, 2025
bf05038
vérification email #59
seignif May 10, 2025
963a02a
On ne push pas des build du site
CianCode May 13, 2025
c9e5a77
Merge pull request #57 from Tablify-Developement/mail_reservation
CianCode May 13, 2025
6261c1c
✨Update PostgreSQL image in docker-compose.yml
CianCode May 14, 2025
ecd64d7
Merge remote-tracking branch 'origin/developement' into developement
CianCode May 14, 2025
d94ea31
Merge pull request #62 from Tablify-Developement/developement
CianCode May 15, 2025
091809c
✨Update PostgreSQL image in docker-compose.yml
CianCode May 15, 2025
3199fe3
Merge pull request #63 from Tablify-Developement/developement
CianCode May 15, 2025
2046130
Merge pull request #60 from Tablify-Developement/email_check
CianCode May 15, 2025
5d0827c
Merge pull request #64 from Tablify-Developement/developement
CianCode May 15, 2025
29e5cd4
✨Update PostgreSQL image in docker-compose.yml
CianCode May 15, 2025
4b65742
Merge pull request #65 from Tablify-Developement/developement
CianCode May 15, 2025
1c16bf4
TAB #20 page frontend pour l'update des informations utilisateur
GuillaumeDelferiere May 20, 2025
382b39c
✨Add restaurant image upload and management functionality
CianCode May 20, 2025
7eb1615
Merge pull request #66 from Tablify-Developement/developement
CianCode May 20, 2025
c379544
TAB modification mail obligatoire réservation
GuillaumeDelferiere May 20, 2025
e526bb1
✨Refactor restaurant image upload methods to use custom FileRequest i…
CianCode May 20, 2025
6e8582b
Merge remote-tracking branch 'origin/developement' into developement
CianCode May 20, 2025
3f6bc38
Merge pull request #67 from Tablify-Developement/developement
CianCode May 20, 2025
987ed7d
✨Refactor restaurant image upload methods to use custom FileRequest i…
CianCode May 20, 2025
f25120a
Merge pull request #68 from Tablify-Developement/developement
CianCode May 20, 2025
91527e8
✨Update Dockerfile to install all dependencies and build TypeScript
CianCode May 20, 2025
e5f6fca
Merge remote-tracking branch 'origin/production' into production
CianCode May 20, 2025
850f9ca
✨Update Dockerfile to install all dependencies and build TypeScript
CianCode May 20, 2025
3747889
✨Update database schema and Docker configuration for restaurant manag…
CianCode May 20, 2025
9860cb9
TAB modification mail obligatoire réservation
GuillaumeDelferiere May 20, 2025
ef315e5
Merge remote-tracking branch 'origin/developement' into developement
GuillaumeDelferiere May 20, 2025
3b47886
Ajout de l'endpoint pour les réservations ouvertes et correction du p…
manunar May 22, 2025
a27bbb7
US009 endpoint
manunar May 22, 2025
6e1e381
✨Enhance reservation date handling with improved validation and initi…
CianCode May 22, 2025
0715818
Merge branch 'production' into developement
CianCode May 22, 2025
6e6ed18
#US010 Implémentation du système de matching basé sur les centres d'i…
manunar May 22, 2025
4f7fb72
Amélioration de la vérification d'email et de la réservation de resta…
seignif May 24, 2025
a876351
#US010 Implémentation des centres d'intérêt par catégories
manunar May 26, 2025
e4f27d6
✨Implement unauthorized access page and enhance ProtectedRoute for ro…
CianCode May 27, 2025
979f4cb
Merge remote-tracking branch 'origin/developement' into developement
CianCode May 27, 2025
2a73316
TAB #20 Modification de la langue dans les settings
GuillaumeDelferiere May 28, 2025
c614c32
Implémentation des toasts (#71)
seignif May 28, 2025
2aa60e6
TAB #20 Modification boutons settings et langue sur l'interface
GuillaumeDelferiere May 28, 2025
3f9b6f7
#US10 implémentation du système de matching utilisateur-utilisateur a…
manunar May 28, 2025
0cb1fc3
fix: replace real secrets with placeholders in .env.example
manunar May 28, 2025
7b652b9
✨Add admin dashboard layout, routes, and middleware for user and rest…
CianCode May 29, 2025
c862114
✨Update database connection settings and add express-rate-limit depen…
CianCode May 30, 2025
9b39701
✨Update database connection settings and add express-rate-limit depen…
CianCode May 30, 2025
ab1fa08
Merge branch 'developement' into mail_end
CianCode May 30, 2025
263f148
Merge pull request #70 from Tablify-Developement/mail_end
CianCode May 30, 2025
1872e3b
Merge pull request #72 from Tablify-Developement/Feature_Toast
CianCode May 30, 2025
7f40cf0
✨Update dependencies and improve restaurant fetching logic for public…
CianCode May 30, 2025
ef8d3e7
Correction: Empêcher les doublons de participation aux réservations e…
manunar May 30, 2025
b61864b
#US10 Rejoindre social matching réservation fonctionnel
manunar May 31, 2025
2152422
#US10 Affichage des boutons pour aller et sortir de la page de matchi…
manunar May 31, 2025
71a4839
#US10 Petit problème d'affichage réglé
manunar May 31, 2025
eddc06a
#US10 meilleur affichage des centres d'interets
manunar May 31, 2025
f155450
Fix: Résolution des conflits de dépendances et correction après fusion
manunar May 31, 2025
c46dd5b
modification de l'algo v3
manunar Aug 23, 2025
7ee39d5
debug auth et quelques boutons
manunar Aug 23, 2025
dd929bd
ajout de resto reservation + matching
manunar Aug 23, 2025
bfda948
algo matching v3
manunar Aug 23, 2025
7f1fff4
frontend afficher les interets communs sur les reservations
manunar Aug 23, 2025
65303cd
fix confirm reservation
manunar Aug 24, 2025
f350c61
fixed responsive on dashboard
manunar Aug 24, 2025
27b564f
fixed social matching page
manunar Aug 24, 2025
77e7d9c
final commit fixed images and settings
manunar Aug 25, 2025
bd28692
Fix route
manunar Aug 31, 2025
7072630
Fix api
manunar Aug 31, 2025
bc4fc59
backend
manunar Aug 31, 2025
5eab3ad
modifier variable
manunar Aug 31, 2025
b21ed2d
fix
manunar Aug 31, 2025
c1315a9
edit url
manunar Aug 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM node:20-alpine

WORKDIR /app

# Copy package files
COPY package*.json ./

# Install ALL dependencies (including dev dependencies needed for build)
RUN npm install

# Copy the rest of the application
COPY . .

# Build TypeScript (without ignoring errors)
RUN npm run build

# For production, you can remove dev dependencies after build
# RUN npm prune --production

# Expose the port
EXPOSE 3001

# Start the application
CMD ["node", "dist/index.js"]
34 changes: 34 additions & 0 deletions backend/Dockerfile.prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Étape de construction
FROM node:18-alpine AS builder

WORKDIR /app

# Copier les fichiers de dépendances
COPY package*.json ./

# Installer les dépendances de développement
RUN npm ci

# Copier le reste des fichiers
COPY . .

# Construire l'application
RUN npm run build

# Étape de production
FROM node:18-alpine

WORKDIR /app

# Copier les dépendances de production
COPY --from=builder /app/package*.json ./
RUN npm ci --only=production

# Copier les fichiers construits
COPY --from=builder /app/dist ./dist

# Exposer le port
EXPOSE 3001

# Changer main.js en index.js
CMD ["node", "dist/index.js"]
12 changes: 12 additions & 0 deletions backend/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
rootDir: './',
testMatch: [
'**/__tests__/**/*.ts',
'**/*.test.ts'
],
transform: {
'^.+\.ts$': 'ts-jest'
}
};
21 changes: 17 additions & 4 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,35 @@
"license": "ISC",
"description": "",
"dependencies": {
"@sendgrid/mail": "^8.1.5",
"@supabase/supabase-js": "^2.49.1",
"@types/express": "^5.0.0",
"@types/node": "^22.13.4",
"bcryptjs": "^3.0.0",
"chalk": "^5.4.1",
"chalk": "^4.1.2",
"cors": "^2.8.5",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express-rate-limit": "^7.5.0",
"jsonwebtoken": "^9.0.2",
"multer": "^2.0.0",
"pg": "^8.14.1",
"pg-format": "^1.0.4",
"ts-node": "^10.9.2",
"typescript": "^5.7.3"
"typescript": "^5.7.3",
"uuid": "^11.1.0"
},
"devDependencies": {
"@jest/globals": "30.0.0-beta.3",
"@types/bcryptjs": "^2.4.6",
"@types/cors": "^2.8.17",
"@types/express": "^5.0.0",
"@types/jest": "^29.5.14",
"@types/jsonwebtoken": "^9.0.8",
"nodemon": "^3.1.9"
"@types/multer": "^1.4.12",
"@types/pg": "^8.11.11",
"@types/uuid": "^10.0.0",
"jest": "^29.7.0",
"nodemon": "^3.1.9",
"ts-jest": "^29.3.4"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
216 changes: 216 additions & 0 deletions backend/src/config/database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
import { Pool, PoolClient, QueryResult, QueryResultRow } from 'pg';
import dotenv from 'dotenv';
import { logger } from '../utils/logger';

// Load environment variables
dotenv.config();

// Build the connection string from environment variables or use the DATABASE_URL directly
const connectionString = process.env.DATABASE_URL || buildConnectionString();

function buildConnectionString(): string {
const user = process.env.POSTGRES_USER || 'postgres';
const password = process.env.POSTGRES_PASSWORD;
const host = process.env.POSTGRES_HOST || 'localhost';
const port = process.env.POSTGRES_PORT || '5432';
const database = process.env.POSTGRES_DB || 'tablify';

if (!password) {
logger.warn('No POSTGRES_PASSWORD set in environment variables');
}

return `postgres://${user}:${password}@${host}:${port}/${database}`;
}

// Configure SSL based on environment
const sslConfig = process.env.NODE_ENV === 'production'
? { rejectUnauthorized: false }
: false;

// Create a new PostgreSQL connection pool
const pool = new Pool({
connectionString,
ssl: false,
// Connection pool settings
max: parseInt(process.env.PG_MAX_POOL_SIZE || '30'), // Increased from 10
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 10000, // Increased from 5000
});

// Monitor the pool events
pool.on('connect', () => {
logger.info('New client connected to PostgreSQL database');
});

pool.on('error', (err) => {
logger.error(`Unexpected error on idle PostgreSQL client: ${err.message}`);
process.exit(-1); // Exit on fatal error
});

// Test database connection on startup
async function testConnection() {
let client: PoolClient | null = null;
try {
client = await pool.connect();
const result = await client.query('SELECT NOW() as now');
logger.success(`Connected to PostgreSQL database (${connectionString.replace(/:[^:]*@/, ':****@')})`);
logger.info(`Connection time: ${result.rows[0].now}`);
return true;
} catch (err: any) {
logger.error(`Database connection error: ${err.message}`);
if (err.message.includes('ENOTFOUND')) {
logger.error(`Could not resolve host. Please check your database host configuration.`);
} else if (err.message.includes('password authentication failed')) {
logger.error(`Authentication failed. Please check your database credentials.`);
} else if (err.message.includes('database') && err.message.includes('does not exist')) {
logger.error(`Database does not exist. Please create it first.`);
}
return false;
} finally {
if (client) client.release();
}
}

// Perform initial connection test (can be awaited by server startup)
const connectionPromise = testConnection();

// Log query details in development
const logQuery = (text: string, params?: any[], duration?: number) => {
if (process.env.NODE_ENV !== 'production' && process.env.LOG_QUERIES === 'true') {
const maskedParams = params?.map(param =>
typeof param === 'string' && param.length > 20
? `${param.substring(0, 20)}...`
: param
);

const message = `Query${duration ? ` (${duration}ms)` : ''}: ${text}, Params: ${JSON.stringify(maskedParams)}`;
if (duration && duration > 500) {
logger.warn(`SLOW ${message}`);
} else {
logger.info(message);
}
}
};

/**
* Enhanced PostgreSQL database interface
*/
export default {
/**
* Execute a query with optional parameters
* @param text - SQL query
* @param params - Query parameters
*/
query: async <T extends QueryResultRow = any>(text: string, params?: any[]): Promise<QueryResult<T>> => {
try {
const start = Date.now();
const res = await pool.query<T>(text, params);
const duration = Date.now() - start;

logQuery(text, params, duration);

return res;
} catch (error: any) {
logger.error(`Query error: ${error.message}`);
logger.error(`Query: ${text}`);
logger.error(`Params: ${JSON.stringify(params)}`);
throw error;
}
},

/**
* Get a client from the pool
* Used for transactions
*/
getClient: async (): Promise<PoolClient> => {
const client = await pool.connect();
const originalQuery = client.query.bind(client);
const originalRelease = client.release.bind(client);

// Create a type-safe wrapper function
const wrappedQuery = async <T extends QueryResultRow = any>(
textOrConfig: string | any,
values?: any[]
): Promise<QueryResult<T>> => {
const start = Date.now();
let queryText: string;
let queryParams: any[] | undefined;

if (typeof textOrConfig === 'string') {
queryText = textOrConfig;
queryParams = values;
} else {
queryText = textOrConfig.text;
queryParams = textOrConfig.values;
}

try {
const result = await originalQuery(textOrConfig, values);
const duration = Date.now() - start;
logQuery(queryText, queryParams, duration);
return result as unknown as QueryResult<T>;
} catch (err: any) {
logger.error(`Transaction query error: ${err.message}`);
logger.error(`Query: ${queryText}`);
logger.error(`Params: ${JSON.stringify(queryParams)}`);
throw err;
}
};

// Override the client's query method with our wrapped version
(client as any).query = wrappedQuery;

// Override release method to restore original methods
client.release = () => {
(client as any).query = originalQuery;
client.release = originalRelease;
return originalRelease();
};

return client;
},

/**
* Execute a transaction with a callback
* @param callback - Function that gets a client and executes transaction queries
*/
transaction: async <T = any>(
callback: (client: PoolClient) => Promise<T>
): Promise<T> => {
const client = await pool.connect();

try {
await client.query('BEGIN');
const result = await callback(client);
await client.query('COMMIT');
return result;
} catch (error) {
await client.query('ROLLBACK');
throw error;
} finally {
client.release();
}
},

/**
* Close all pool connections
* Should be called when shutting down the application
*/
close: async (): Promise<void> => {
await pool.end();
logger.info('Database connection pool has been closed');
},

/**
* Wait for database connection to be established
* Useful for server startup
*/
waitForConnection: async (): Promise<boolean> => {
return connectionPromise;
},

/**
* Get the connection pool for direct access
*/
getPool: (): Pool => pool
};
9 changes: 0 additions & 9 deletions backend/src/config/supabase.ts

This file was deleted.

Loading