- max-width 960px auf Kontakt-Detailseite
- M365-Sektion umbenannt zu "Outlook Daten", default eingeklappt
- Aufgaben-Tab entfernt (nur noch E-Mails + Kalender)
- "In Outlook speichern"-Button: pusht/aktualisiert Kontakt in Outlook-Kontakte via MS Graph POST/PATCH /me/contacts
- Kontaktdaten: Typ, Status immer sichtbar, Bundesland (state) in Adresse
- Backend: GraphService exportiert, pushContactToOutlook-Methode, POST /crm/contacts/:id/push-to-outlook
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Neue Felder im Benutzerprofil (analog Microsoft 365 /me):
- Stellenbezeichnung (jobTitle), Abteilung (department)
- Firma (companyName), Standort (officeLocation)
Changes:
- Core: Prisma-Migration + neue Felder in User-Model, UpdateUserDto,
findById/update/updateProfile
- CRM: M365UserProfile-Interface + getM365Profile um neue Felder erweitert;
neue Methode getM365Photo() lädt 96x96 JPEG als Base64 Data-URL;
neuer Endpoint GET /crm/office365/photo
- Frontend: AuthContext User-Interface, M365UserProfile-Typ, office365Api.getM365Photo()
ProfilePage: Neues Formular-Fieldset "Organisation" mit 4 Feldern;
manueller Sync-Button übernimmt auch Profilbild (immer überschreiben);
useO365ProfileSync: Auto-Sync lädt Foto nur wenn noch kein INSIGHT-Avatar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Graph API: getCalendarEventsForRange() für beliebigen Datumsbereich,
GET /crm/office365/calendar/range?startDate=&endDate= Endpoint
(vor bestehenden calendar-Route definiert um Routing-Konflikt zu vermeiden)
- Graph API: wellKnownName aus mailFolders $select entfernt (400-Fehler auf
Exchange-Tenants die das OData-Property nicht unterstützen)
- Frontend: DashboardCalendarTab mit MonthView (6×7 Grid), WeekView (7 Spalten)
und DayAgenda (rechts 1/3), Navigation vor/zurück + Heute-Button,
deterministisches Event-Coloring, Klick öffnet Termin in Outlook Online
- Frontend: DashboardEmailTab Ordner-Sortierung auf Display-Name-Basis
(wellKnownName optional, isInboxFolder() erkennt Posteingang/Inbox)
- Frontend: M365MailFolder.wellKnownName als optional markiert
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Neues GraphModule mit GraphService + GraphController
- GET /crm/contacts/:id/emails → MS Graph Emails (Search nach Kontakt-E-Mail)
- GET /crm/contacts/:id/calendar → Kalender-Termine (naechste 90 Tage)
- GET /crm/contacts/:id/tasks → Microsoft To Do Listen + Aufgaben
- GraphService: JWT an Core-Service weiterleiten, M365-Token holen, Graph aufrufen
- Redis-Cache 5 Minuten fuer alle Graph-Responses
- CORE_SERVICE_URL env var + docker-compose.crm.yml Eintrag
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend (CRM expert): Custom field definitions CRUD, bulk value upsert,
7 endpoints, Prisma schema with CustomFieldDef + CustomFieldValue tables.
Frontend: Types, API, hooks, admin settings page with field management,
CustomFieldsDisplay for detail pages, CustomFieldsForm for edit modals.
Also fix Vite allowedHosts for insight.xinion.lan.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend: TradeEvent Prisma model, NestJS CRUD module with date validation
and tenant isolation. Frontend: Admin Events page with create/edit/delete
modals, dashboard countdown tiles showing upcoming/ongoing/ended events
with progress bars, and useEventCountdown hook for live timer updates.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Companies with linked contacts now show an expand arrow. Clicking it
lazy-loads and displays contacts as indented sub-rows with name,
position, email, phone, type badge and status. Backend gains companyId
filter on GET /contacts for efficient per-company querying.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The voucherlist endpoint returns items with 'id' field, but our interface
defined it as 'voucherId', causing undefined IDs when fetching voucher details.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Lexware Office API requires voucherStatus as a mandatory parameter
for the /v1/voucherlist endpoint. Without it, the API returns 400 Bad
Request. Using 'any' fetches vouchers regardless of status.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- TenantGuard: remove PLATFORM_ADMIN bypass, require tenantId for all users
- lexware-contacts.service: add defensive tenantId check in importAsCompany
and importAsContact with clear BadRequestException message
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Backend: new CRUD services/controllers for Industries, AccountTypes,
RelationshipTypes, CompanyRelationships with Prisma schema migration
- Frontend: new hooks, API functions, and types for all config entities
- CompanyDetailPage redesign with ActivityFeed, RelationshipsCard
- CompanyFormModal extended with industry, account type, owner fields
- Activities service now supports companyId filter + includeContacts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update INSIGHT-CRM.md with complete Company API documentation,
Contact/Deal changes (companyId, position), and frontend integration
suggestions. Update Summarize.md with current test results.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New Company model with full CRUD under /api/v1/crm/companies
- Contact now has companyId relation + position field
- Deal now has companyId relation
- Company detail includes contacts (top 20) and deals (top 10)
- All endpoints include company in responses
- Swagger tags renamed: Deals -> Vorgaenge (Deals)
- Error messages use "Vorgang" instead of "Deal"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New PATCH /pipelines/:id/stages/:stageId endpoint to update
stage name, color, and sortOrder
- Added HTTPS (websecure) Traefik router for CRM service
- Both requested by frontend developer via INSIGHT-CRM.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>