7e8d63fcc4
GRO-218: Customer portal now fetches real data via impersonation session. Backend (portal.ts): - Add GET /portal/me, /portal/services, /portal/appointments, /portal/pets, /portal/invoices - Add getClientIdFromSession() helper for DRY auth validation - Add imports: lte, clients, pets, services, staff, invoices, invoiceLineItems, groomingVisitLogs Frontend (portal sections): - Dashboard: fetches appointments, pets, invoices, branding from API - Appointments: fetches from /portal/appointments; booking submits to /portal/waitlist - PetProfiles: fetches pets and appointments from API; no vaccinations tab (no DB table) - BillingPayments: fetches invoices from /portal/invoices; uses totalCents not amount - Communication: local-only messages/notifications; fetches branding from /api/branding - AccountSettings: fetches personal info from /portal/me and pets from /portal/pets - ReportCards: fetches appointments with reportCardId; empty state when none Stubbed features (no DB tables): loyalty points, messages, signed agreements, vaccinations. Co-Authored-By: Paperclip <noreply@paperclip.ing>