Add structured logging, navigation bar, and code cleanup

## Backend
- Add Pino logging framework with timestamps and structured output
- Replace all console.error statements (49+) with proper logging levels
- Fix Drizzle ORM bug: replace invalid .get() calls with .limit(1)
- Remove unused auth routes file (already in index.js)
- Make internal functions private (remove unnecessary exports)
- Simplify code by removing excessive debug logging

## Frontend
- Add navigation bar to layout with:
  - User's callsign display
  - Navigation links (Dashboard, QSOs, Settings)
  - Logout button with red color distinction
- Navigation only shows when user is logged in
- Dark themed design matching footer

## Documentation
- Update README.md with new project structure
- Update docs/DOCUMENTATION.md with logging and nav bar info
- Add logger.js to configuration section

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-16 08:11:57 +01:00
parent 512f4f682e
commit d959235cdd
13 changed files with 388 additions and 683 deletions

View File

@@ -2,6 +2,7 @@ import { Elysia, t } from 'elysia';
import { cors } from '@elysiajs/cors';
import { jwt } from '@elysiajs/jwt';
import { JWT_SECRET } from './config/jwt.js';
import logger from './config/logger.js';
import {
registerUser,
authenticateUser,
@@ -229,24 +230,16 @@ const app = new Elysia()
*/
.post('/api/lotw/sync', async ({ user, set }) => {
if (!user) {
console.error('[/api/lotw/sync] No user found in request');
logger.warn('/api/lotw/sync: Unauthorized access attempt');
set.status = 401;
return { success: false, error: 'Unauthorized' };
}
console.error('[/api/lotw/sync] User authenticated:', user.id);
try {
// Get user's LoTW credentials from database
const userData = await getUserById(user.id);
console.error('[/api/lotw/sync] User data from DB:', {
id: userData?.id,
lotwUsername: userData?.lotwUsername ? '***' : null,
hasPassword: !!userData?.lotwPassword
});
if (!userData || !userData.lotwUsername || !userData.lotwPassword) {
console.error('[/api/lotw/sync] Missing LoTW credentials');
logger.debug('/api/lotw/sync: Missing LoTW credentials', { userId: user.id });
set.status = 400;
return {
success: false,
@@ -254,13 +247,11 @@ const app = new Elysia()
};
}
// Enqueue the sync job (enqueueJob will check for existing active jobs)
const result = await enqueueJob(user.id, 'lotw_sync', {
lotwUsername: userData.lotwUsername,
lotwPassword: userData.lotwPassword,
});
// If enqueueJob returned existingJob, format the response
if (!result.success && result.existingJob) {
return {
success: true,
@@ -271,7 +262,7 @@ const app = new Elysia()
return result;
} catch (error) {
console.error('Error in /api/lotw/sync:', error);
logger.error('Error in /api/lotw/sync', { error: error.message });
set.status = 500;
return {
success: false,
@@ -488,7 +479,7 @@ const app = new Elysia()
// Start server
.listen(3001);
console.log(`🦊 Backend server running at http://localhost:${app.server?.port}`);
console.log(`📡 API endpoints available at http://localhost:${app.server?.port}/api`);
logger.info(`Backend server running`, { port: app.server?.port, url: `http://localhost:${app.server?.port}` });
logger.info(`API endpoints available`, { url: `http://localhost:${app.server?.port}/api` });
export default app;