Implement a complete notifications system using Socket.IO for real-time delivery.
Backend:
- Add notifications table migration with userId, title, message, type, category, metadata, readAt fields
- Create Notification model extending TenantBaseModel with modifiers for filtering
- Add GetNotificationsService and CreateNotificationService for CRUD operations
- Create NotificationsController with endpoints for listing, marking as read, and deleting
- Extend SocketGateway with emitNotification() and user room management
- Add InventoryCostNotificationsSubscriber for item cost calculation completion events
- Register NotificationsModule in AppModule
Frontend:
- Add notification query keys (NOTIFICATIONS, NOTIFICATIONS_UNREAD_COUNT)
- Create notification hooks: useNotifications, useNotificationsUnreadCount, useMarkNotificationAsRead, useMarkAllNotificationsAsRead, useDeleteNotification
- Create NotificationsDrawer component with tabs for All/Unread notifications
- Add NotificationItem component with type icons, timestamps, and actions
- Update DashboardTopbar with notification button badge showing unread count
- Extend DashboardSockets to listen for NOTIFICATION events and show toasts
- Register NotificationsDrawer in DrawersContainer
The first notification triggers when item cost calculation finishes, notifying
users of completed inventory cost computations in real-time.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
GET /api/attachments/:id crashes with "Cannot read properties of
undefined (reading extension)" when the S3 object has no ContentType
metadata. This happens when files are uploaded without explicit content
type (e.g., via API integrations).
mime.extension(undefined) returns undefined, which then causes the
Content-Disposition header template to fail.
Fix: fallback to "application/octet-stream" when ContentType is missing,
and "bin" when mime.extension() returns undefined.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Prettier scripts to webapp package for code formatting, consistent
with the existing server package setup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: bulk uncategorize transactions - fix API endpoint and error handling
* refactor: use params object instead of URLSearchParams for delete request
Simplifies the API call by passing params object directly to the delete
method instead of manually building URLSearchParams.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Ahmed Bouhuolia <a.bouhuolia@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The NestJS app requires database and Redis connections to bootstrap.
Added GitHub Actions services for MySQL and Redis with necessary
environment variables for the openapi:export command to work.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The server depends on @bigcapital/email-components and other shared
packages. Build them before running openapi:export to fix module
resolution errors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds workflow that triggers on server code changes to:
- Export OpenAPI spec from NestJS Swagger module
- Generate TypeScript types with openapi-typescript
- Build the SDK package
- Create PR with changes if any exist
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add fetchLatestExchangeRate function to retrieve exchange rates
- Add ExchangeRateLatestQuery and ExchangeRateLatestResponse types
- Export exchange-rates module from SDK index
Refactor the GetRefundCreditNoteTransaction service to use TransformerInjectable
instead of directly injecting RefundCreditNoteTransformer, following the standard
NestJS DI pattern used throughout the codebase.
Also includes SDK TypeScript updates:
- Add new type exports for bank-rules operations
- Update organization SDK utilities with proper types
- Add accounts list filtering params to schema (customViewId, filterRoles, etc.)
- Remove export module from SDK index
- Sync openapi.json with latest API changes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>