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"
|
||||||
}
|
}
|
||||||
|
|||||||
+88
-58
@@ -36,57 +36,61 @@ 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.run(`CREATE TABLE IF NOT EXISTS user_stats (
|
db.serialize(() => {
|
||||||
wallet_hash TEXT PRIMARY KEY,
|
db.run(`CREATE TABLE IF NOT EXISTS user_stats (
|
||||||
photo_count INTEGER DEFAULT 0,
|
wallet_hash TEXT PRIMARY KEY,
|
||||||
last_upload DATETIME DEFAULT CURRENT_TIMESTAMP
|
photo_count INTEGER DEFAULT 0,
|
||||||
)`);
|
last_upload DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
|
)`);
|
||||||
|
|
||||||
db.run(`CREATE TABLE IF NOT EXISTS banned_wallets (
|
db.run(`CREATE TABLE IF NOT EXISTS banned_wallets (
|
||||||
wallet_hash TEXT PRIMARY KEY,
|
wallet_hash TEXT PRIMARY KEY,
|
||||||
reason TEXT,
|
reason TEXT,
|
||||||
banned_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
banned_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
banned_by TEXT DEFAULT 'Admin'
|
banned_by TEXT DEFAULT 'Admin'
|
||||||
)`);
|
)`);
|
||||||
|
|
||||||
db.run(`CREATE TABLE IF NOT EXISTS upload_logs (
|
db.run(`CREATE TABLE IF NOT EXISTS upload_logs (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
|
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
session_id TEXT,
|
session_id TEXT,
|
||||||
wallet_hash TEXT,
|
wallet_hash TEXT,
|
||||||
image_filename TEXT,
|
image_filename TEXT,
|
||||||
json_filename TEXT,
|
json_filename TEXT,
|
||||||
file_size INTEGER,
|
file_size INTEGER,
|
||||||
ip_address TEXT,
|
ip_address TEXT,
|
||||||
user_agent TEXT,
|
user_agent TEXT,
|
||||||
device_model TEXT,
|
device_model TEXT,
|
||||||
device_os TEXT,
|
device_os TEXT,
|
||||||
target_type TEXT,
|
target_type TEXT,
|
||||||
weapon TEXT,
|
weapon TEXT,
|
||||||
distance_meters INTEGER,
|
distance_meters INTEGER,
|
||||||
impacts_count INTEGER DEFAULT 0,
|
impacts_count INTEGER DEFAULT 0,
|
||||||
status TEXT DEFAULT 'SUCCESS',
|
status TEXT DEFAULT 'SUCCESS',
|
||||||
target_valid INTEGER DEFAULT 1,
|
target_valid INTEGER DEFAULT 1,
|
||||||
target_status TEXT DEFAULT 'VALID',
|
target_status TEXT DEFAULT 'VALID',
|
||||||
target_confidence REAL DEFAULT 1.0,
|
target_confidence REAL DEFAULT 1.0,
|
||||||
target_rings_count INTEGER DEFAULT 0,
|
target_rings_count INTEGER DEFAULT 0,
|
||||||
target_details TEXT,
|
target_details TEXT,
|
||||||
error_message TEXT,
|
error_message TEXT,
|
||||||
raw_metadata TEXT
|
raw_metadata TEXT
|
||||||
)`);
|
)`);
|
||||||
|
|
||||||
// Migration safe des colonnes OpenCV si la table existait déjà
|
// Migration safe des colonnes OpenCV si la table existait déjà
|
||||||
const migrations = [
|
const migrations = [
|
||||||
"ALTER TABLE upload_logs ADD COLUMN target_valid INTEGER DEFAULT 1",
|
"ALTER TABLE upload_logs ADD COLUMN target_valid INTEGER DEFAULT 1",
|
||||||
"ALTER TABLE upload_logs ADD COLUMN target_status TEXT DEFAULT 'VALID'",
|
"ALTER TABLE upload_logs ADD COLUMN target_status TEXT DEFAULT 'VALID'",
|
||||||
"ALTER TABLE upload_logs ADD COLUMN target_confidence REAL DEFAULT 1.0",
|
"ALTER TABLE upload_logs ADD COLUMN target_confidence REAL DEFAULT 1.0",
|
||||||
"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');
|
||||||
console.log(`=================================`);
|
const dev = process.env.NODE_ENV !== 'production';
|
||||||
console.log(`Serveur Backend IA démarré`);
|
|
||||||
console.log(`Port: ${PORT}`);
|
let nextApp;
|
||||||
console.log(`Dossiers:`);
|
try {
|
||||||
console.log(` - Images: ${imagesDir}`);
|
const next = require('next');
|
||||||
console.log(` - Data : ${dataDir}`);
|
nextApp = next({ dev, dir: dashboardDir });
|
||||||
console.log(` - Export: ${exportsDir}`);
|
} catch (e) {
|
||||||
console.log(`=================================`);
|
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(`Serveur Backend IA & Dashboard démarré`);
|
||||||
|
console.log(`Port: ${PORT}`);
|
||||||
|
console.log(`Dossiers:`);
|
||||||
|
console.log(` - Images: ${imagesDir}`);
|
||||||
|
console.log(` - Data : ${dataDir}`);
|
||||||
|
console.log(` - Export: ${exportsDir}`);
|
||||||
|
console.log(`=================================`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
startServer();
|
||||||
|
|||||||
Reference in New Issue
Block a user