feat: Add JWT auth and nomenclature sync to data-entry-app

Integrate shared JWT authentication into data-entry-app:
- Add Oracle pool initialization for auth service
- Add AuthenticationMiddleware to protect API routes
- Update all receipt endpoints to use CurrentUser from JWT
- Add shared auth router (/api/auth/login, /api/auth/refresh)

Add nomenclature synchronization feature:
- Create SQLite models for synced suppliers, local suppliers, and cash registers
- Add nomenclature router with sync triggers and CRUD endpoints
- Add sync service for Oracle → SQLite nomenclature data
- Update nomenclature_service to use synced SQLite data with fallbacks

Create shared frontend components:
- Add shared/frontend/ with LoginView.vue, auth store factory, login.css
- Integrate shared login and auth into data-entry-app frontend
- Add axios-based API service with token refresh interceptor

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-14 18:36:24 +02:00
parent 682a4b64b9
commit c5fde510a8
37 changed files with 28907 additions and 903 deletions

View File

@@ -1,35 +1,42 @@
import { createRouter, createWebHistory } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
const routes = [
{
path: '/login',
name: 'Login',
component: () => import('../views/LoginView.vue'),
meta: { title: 'Conectare', requiresAuth: false }
},
{
path: '/',
name: 'ReceiptsList',
component: () => import('../views/receipts/ReceiptsListView.vue'),
meta: { title: 'Lista Bonuri' }
meta: { title: 'Lista Bonuri', requiresAuth: true }
},
{
path: '/create',
name: 'ReceiptCreate',
component: () => import('../views/receipts/ReceiptCreateView.vue'),
meta: { title: 'Bon Nou' }
meta: { title: 'Bon Nou', requiresAuth: true }
},
{
path: '/receipt/:id',
name: 'ReceiptDetail',
component: () => import('../views/receipts/ReceiptDetailView.vue'),
meta: { title: 'Detalii Bon' }
meta: { title: 'Detalii Bon', requiresAuth: true }
},
{
path: '/receipt/:id/edit',
name: 'ReceiptEdit',
component: () => import('../views/receipts/ReceiptCreateView.vue'),
meta: { title: 'Editare Bon' }
meta: { title: 'Editare Bon', requiresAuth: true }
},
{
path: '/approval',
name: 'ReceiptApproval',
component: () => import('../views/receipts/ReceiptApprovalView.vue'),
meta: { title: 'Aprobare Bonuri' }
meta: { title: 'Aprobare Bonuri', requiresAuth: true }
}
]
@@ -38,12 +45,26 @@ const router = createRouter({
routes
})
// Update page title
// Authentication guard and page title
router.beforeEach((to, from, next) => {
// Update page title
document.title = to.meta.title
? `${to.meta.title} | Data Entry`
: 'Data Entry - Bonuri Fiscale'
next()
// Check authentication
const authStore = useAuthStore()
const requiresAuth = to.meta.requiresAuth !== false
if (requiresAuth && !authStore.isAuthenticated) {
// Redirect to login if not authenticated
next({ name: 'Login', query: { redirect: to.fullPath } })
} else if (to.name === 'Login' && authStore.isAuthenticated) {
// Redirect to home if already authenticated
next({ name: 'ReceiptsList' })
} else {
next()
}
})
export default router