feat: initialize backend service with Express, SQLite logging, and API utilities
Deploy Backendia / deploy (push) Successful in 5m0s
Deploy Backendia / deploy (push) Successful in 5m0s
This commit is contained in:
@@ -10,10 +10,16 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm ci --omit=dev && npm rebuild sqlite3 --build-from-source
|
COPY dashboard/package*.json ./dashboard/
|
||||||
|
|
||||||
|
RUN npm install && npm rebuild sqlite3 --build-from-source
|
||||||
|
RUN cd dashboard && npm install
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
# Build du Dashboard Next.js
|
||||||
|
RUN cd dashboard && npm run build
|
||||||
|
|
||||||
# Dossiers nécessaires
|
# Dossiers nécessaires
|
||||||
RUN mkdir -p uploads/images uploads/data exports
|
RUN mkdir -p uploads/images uploads/data exports
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
export const API_BASE_URL = 'http://127.0.0.1:3000';
|
const isServer = typeof window === 'undefined';
|
||||||
|
export const API_BASE_URL = isServer
|
||||||
|
? `http://127.0.0.1:${process.env.PORT || 3000}`
|
||||||
|
: '';
|
||||||
|
|
||||||
export async function fetchApi(endpoint: string) {
|
export async function fetchApi(endpoint: string) {
|
||||||
const res = await fetch(`${API_BASE_URL}${endpoint}`, {
|
const res = await fetch(`${API_BASE_URL}${endpoint}`, {
|
||||||
|
|||||||
@@ -18,6 +18,9 @@
|
|||||||
"dotenv": "^17.4.2",
|
"dotenv": "^17.4.2",
|
||||||
"express": "^5.2.1",
|
"express": "^5.2.1",
|
||||||
"multer": "^2.1.1",
|
"multer": "^2.1.1",
|
||||||
|
"next": "^16.2.4",
|
||||||
|
"react": "^19.2.4",
|
||||||
|
"react-dom": "^19.2.4",
|
||||||
"sharp": "^0.35.3",
|
"sharp": "^0.35.3",
|
||||||
"sqlite3": "^6.0.1"
|
"sqlite3": "^6.0.1"
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-5
@@ -36,6 +36,7 @@ const db = new sqlite3.Database(dbPath, (err) => {
|
|||||||
console.error('Erreur de connexion à SQLite:', err.message);
|
console.error('Erreur de connexion à SQLite:', err.message);
|
||||||
} else {
|
} else {
|
||||||
console.log('Connecté à la base de données SQLite.');
|
console.log('Connecté à la base de données SQLite.');
|
||||||
|
db.serialize(() => {
|
||||||
db.run(`CREATE TABLE IF NOT EXISTS user_stats (
|
db.run(`CREATE TABLE IF NOT EXISTS user_stats (
|
||||||
wallet_hash TEXT PRIMARY KEY,
|
wallet_hash TEXT PRIMARY KEY,
|
||||||
photo_count INTEGER DEFAULT 0,
|
photo_count INTEGER DEFAULT 0,
|
||||||
@@ -83,10 +84,13 @@ const db = new sqlite3.Database(dbPath, (err) => {
|
|||||||
"ALTER TABLE upload_logs ADD COLUMN target_rings_count INTEGER DEFAULT 0",
|
"ALTER TABLE upload_logs ADD COLUMN target_rings_count INTEGER DEFAULT 0",
|
||||||
"ALTER TABLE upload_logs ADD COLUMN target_details TEXT"
|
"ALTER TABLE upload_logs ADD COLUMN target_details TEXT"
|
||||||
];
|
];
|
||||||
migrations.forEach(sql => db.run(sql, () => {}));
|
migrations.forEach(sql => {
|
||||||
|
db.run(sql, () => {});
|
||||||
|
});
|
||||||
|
|
||||||
db.run(`CREATE INDEX IF NOT EXISTS idx_upload_logs_wallet ON upload_logs(wallet_hash)`);
|
db.run(`CREATE INDEX IF NOT EXISTS idx_upload_logs_wallet ON upload_logs(wallet_hash)`);
|
||||||
db.run(`CREATE INDEX IF NOT EXISTS idx_upload_logs_timestamp ON upload_logs(timestamp)`);
|
db.run(`CREATE INDEX IF NOT EXISTS idx_upload_logs_timestamp ON upload_logs(timestamp)`);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -814,14 +818,40 @@ app.use((err, req, res, next) => {
|
|||||||
res.status(500).json({ error: err.message || 'Une erreur inattendue est survenue' });
|
res.status(500).json({ error: err.message || 'Une erreur inattendue est survenue' });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Démarrer le serveur
|
// Intégration du Dashboard Next.js
|
||||||
app.listen(PORT, () => {
|
const dashboardDir = path.join(__dirname, 'dashboard');
|
||||||
|
const dev = process.env.NODE_ENV !== 'production';
|
||||||
|
|
||||||
|
let nextApp;
|
||||||
|
try {
|
||||||
|
const next = require('next');
|
||||||
|
nextApp = next({ dev, dir: dashboardDir });
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Module 'next' non disponible, mode API seule.");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function startServer() {
|
||||||
|
if (nextApp) {
|
||||||
|
try {
|
||||||
|
await nextApp.prepare();
|
||||||
|
const handle = nextApp.getRequestHandler();
|
||||||
|
app.all('*', (req, res) => handle(req, res));
|
||||||
|
console.log("Dashboard Next.js initialisé avec succès.");
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Erreur d'initialisation du Dashboard Next.js:", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.listen(PORT, () => {
|
||||||
console.log(`=================================`);
|
console.log(`=================================`);
|
||||||
console.log(`Serveur Backend IA démarré`);
|
console.log(`Serveur Backend IA & Dashboard démarré`);
|
||||||
console.log(`Port: ${PORT}`);
|
console.log(`Port: ${PORT}`);
|
||||||
console.log(`Dossiers:`);
|
console.log(`Dossiers:`);
|
||||||
console.log(` - Images: ${imagesDir}`);
|
console.log(` - Images: ${imagesDir}`);
|
||||||
console.log(` - Data : ${dataDir}`);
|
console.log(` - Data : ${dataDir}`);
|
||||||
console.log(` - Export: ${exportsDir}`);
|
console.log(` - Export: ${exportsDir}`);
|
||||||
console.log(`=================================`);
|
console.log(`=================================`);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
startServer();
|
||||||
|
|||||||
Reference in New Issue
Block a user