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>
47 lines
1.9 KiB
Python
47 lines
1.9 KiB
Python
"""Nomenclature models for synced and local data."""
|
|
|
|
from typing import Optional
|
|
from datetime import datetime
|
|
from sqlmodel import SQLModel, Field
|
|
|
|
|
|
class SyncedSupplier(SQLModel, table=True):
|
|
"""Suppliers synced from Oracle NOM_PARTENERI."""
|
|
__tablename__ = "synced_suppliers"
|
|
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
oracle_id: int = Field(index=True) # Original Oracle ID
|
|
company_id: int = Field(index=True) # Company this supplier belongs to
|
|
name: str = Field(max_length=200)
|
|
fiscal_code: Optional[str] = Field(default=None, max_length=50, index=True) # CUI/CIF
|
|
address: Optional[str] = Field(default=None, max_length=500)
|
|
synced_at: datetime = Field(default_factory=datetime.utcnow)
|
|
|
|
|
|
class LocalSupplier(SQLModel, table=True):
|
|
"""Suppliers created locally from OCR (not in Oracle)."""
|
|
__tablename__ = "local_suppliers"
|
|
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
company_id: int = Field(index=True)
|
|
name: str = Field(max_length=200)
|
|
fiscal_code: Optional[str] = Field(default=None, max_length=50, index=True)
|
|
address: Optional[str] = Field(default=None, max_length=500)
|
|
created_by: str = Field(max_length=100) # Username who created it
|
|
created_at: datetime = Field(default_factory=datetime.utcnow)
|
|
# Flag to indicate if it should be synced to Oracle later
|
|
pending_oracle_sync: bool = Field(default=True)
|
|
|
|
|
|
class SyncedCashRegister(SQLModel, table=True):
|
|
"""Cash registers and bank accounts synced from Oracle."""
|
|
__tablename__ = "synced_cash_registers"
|
|
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
oracle_id: int = Field(index=True)
|
|
company_id: int = Field(index=True)
|
|
name: str = Field(max_length=100)
|
|
account_code: str = Field(max_length=20) # 5311, 5121, etc.
|
|
register_type: str = Field(max_length=10) # 'cash' or 'bank'
|
|
synced_at: datetime = Field(default_factory=datetime.utcnow)
|