Add vue-router, login/setup flow and backend logging

Refactor frontend to route-based navigation with vue-router, add
system setup and login pages with API integration. Add structured
logging, access-log middleware and startup lifecycle to FastAPI
backend.
This commit is contained in:
2026-05-06 22:23:42 +08:00
parent 83d7da3d62
commit ae63766c91
35 changed files with 3762 additions and 404 deletions

View File

@@ -1,20 +1,34 @@
from sqlalchemy.orm import Session
from app.core.logging import get_logger
from app.models.employee import Employee
from app.repositories.employee import EmployeeRepository
from app.schemas.employee import EmployeeCreate
logger = get_logger("app.services.employee")
class EmployeeService:
def __init__(self, db: Session) -> None:
self.repository = EmployeeRepository(db)
def list_employees(self) -> list[Employee]:
return self.repository.list()
employees = self.repository.list()
logger.info("Listed employees (count=%d)", len(employees))
return employees
def get_employee(self, employee_id: str) -> Employee | None:
return self.repository.get(employee_id)
employee = self.repository.get(employee_id)
if employee:
logger.info("Fetched employee id=%s name=%s", employee_id, employee.name)
else:
logger.warning("Employee not found id=%s", employee_id)
return employee
def create_employee(self, payload: EmployeeCreate) -> Employee:
employee = Employee(**payload.model_dump())
return self.repository.create(employee)
created = self.repository.create(employee)
logger.info(
"Created employee id=%s no=%s name=%s", created.id, created.employee_no, created.name
)
return created

View File

@@ -1,20 +1,37 @@
from sqlalchemy.orm import Session
from app.core.logging import get_logger
from app.models.reimbursement import ReimbursementRequest
from app.repositories.reimbursement import ReimbursementRepository
from app.schemas.reimbursement import ReimbursementCreate
logger = get_logger("app.services.reimbursement")
class ReimbursementService:
def __init__(self, db: Session) -> None:
self.repository = ReimbursementRepository(db)
def list_reimbursements(self) -> list[ReimbursementRequest]:
return self.repository.list()
items = self.repository.list()
logger.info("Listed reimbursements (count=%d)", len(items))
return items
def get_reimbursement(self, request_id: str) -> ReimbursementRequest | None:
return self.repository.get(request_id)
request = self.repository.get(request_id)
if request:
logger.info("Fetched reimbursement id=%s no=%s", request_id, request.request_no)
else:
logger.warning("Reimbursement not found id=%s", request_id)
return request
def create_reimbursement(self, payload: ReimbursementCreate) -> ReimbursementRequest:
request = ReimbursementRequest(**payload.model_dump(), status="draft")
return self.repository.create(request)
created = self.repository.create(request)
logger.info(
"Created reimbursement id=%s no=%s amount=%s",
created.id,
created.request_no,
created.amount,
)
return created