Commit Graph

91 Commits

Author SHA1 Message Date
richardtekula
240dd5f4c8 refactor: Split company.controller.js into focused controllers
Split company.controller.js (461 lines, 5 concerns) into:
- company.controller.js: CRUD + email (134 lines)
- company-note.controller.js: note operations
- company-reminder.controller.js: reminder operations
- company-team.controller.js: user assignment operations

Update company.routes.js to import from new controllers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 07:41:31 +01:00
richardtekula
3aba6c2955 refactor: Move audit logging from controllers into services
Add auditContext parameter to service mutating functions. Services now
call audit log functions internally when auditContext is provided.
Controllers pass { userId, ipAddress, userAgent } and no longer import
audit service or fetch extra data for audit purposes.

Files modified:
- 10 service files: added audit imports and auditContext parameter
- 9 controller files: removed audit imports and calls

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 07:39:41 +01:00
richardtekula
caab86079e refactor: Deduplicate event-notifier.js (603 -> 418 lines)
Extract shared helpers:
- getEventsInRange(start, end) replaces getTomorrowEvents + getUpcomingEvents
- groupEventsByUser() deduplicates event grouping logic from 3 functions
- sendNotificationsToUsers() deduplicates notification loop from 3 functions
- buildJmapConfig() removes repeated JMAP config construction

Remove unused standalone range helper functions (getTomorrowRange,
getOneHourRange) — date ranges computed inline where needed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 07:25:35 +01:00
richardtekula
d4883480b2 refactor: Deduplicate time-tracking.service.js (1045 -> 876 lines)
Extract shared helpers:
- validateProjectExists, validateTodoExists, validateCompanyExists,
  validateRelatedEntities (replaces 4x copy-pasted validation blocks)
- generateTimesheetWorkbook (shared workbook creation logic)
- addDailySummary (shared daily totals section)
- saveTimesheetFile (shared file save + DB insert)
- computeDailyTotals, getUserNamePrefix

generateMonthlyTimesheet and generateCompanyTimesheet now use shared
helpers instead of duplicating ~370 lines each.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 07:24:23 +01:00
richardtekula
4629f1903b refactor: Move inline Zod schemas from routes to validator files
Create ai-kurzy.validators.js and service.validators.js with schemas
extracted from their respective route files. Routes now import schemas
instead of defining them inline.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 07:22:33 +01:00
richardtekula
f463467264 refactor: Extract shared multer/upload config from routes
Create src/config/upload.js with createUpload() factory and shared
ALLOWED_FILE_TYPES constant. Replace duplicated multer configs in 5
route files with calls to the shared factory.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 07:21:35 +01:00
richardtekula
01ce2fc7ad refactor: Remove unused exports
Remove setPrimaryAccountSchema from email-account.validators.js and
requireOwnerOrAdmin from roleMiddleware.js — both have zero imports.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 07:20:00 +01:00
richardtekula
938a8d1478 refactor: Delete unused utility files
Remove queryBuilder.js and pagination.js — zero imports anywhere in codebase.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 07:19:39 +01:00
richardtekula
883d3fa533 chore: Commit current state before refactoring
Includes deleted sql/ files, seeds, and documentation files.
Prepares master for refactoring branch.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 07:19:23 +01:00
richardtekula
95688be45b feat: Add pause/resume functionality to time tracking
Add pausedAt and pausedDuration columns to time_entries table.
New pause/resume endpoints with audit logging. Duration calculations
now correctly exclude paused time across start, stop, auto-stop,
and edit flows.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 07:15:57 +01:00
richardtekula
d26e537244 fix: Harden security - CORS, XSS, file uploads, error handling
- Restrict no-origin CORS bypass to development only
- Activate xss-clean middleware for input sanitization
- Add MIME type whitelist and filename sanitization to file uploads
- Reduce project upload limit from 50MB to 20MB
- Stop leaking stack traces in error responses

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 15:21:44 +01:00
richardtekula
929d0b461f fix: Allow project team members to update projects, handle empty companyId
- Relax project PATCH route from requireAdmin to checkProjectAccess
- Normalize empty string companyId to null in updateProject service to prevent UUID parse error

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 11:41:36 +01:00
richardtekula
dd15be93a9 feat: Add refresh token endpoint and remember me support
- Add POST /auth/refresh endpoint for token renewal
- Only set refresh token cookie when rememberMe is true
- Add rememberMe field to login validator schema

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 07:21:58 +01:00
richardtekula
d85f6761cf fix validator in create cpompany schema 2026-01-23 06:28:56 +01:00
richardtekula
4c4c9accae fix: Add pricingTiers to service Zod validators
- pricingTiers field was missing from createServiceSchema
- pricingTiers field was missing from updateServiceSchema
- This caused the field to be stripped during validation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 11:40:48 +01:00
richardtekula
5dde025855 fix: Services pricing tiers and timesheet naming
- Add pricingTiers field handling in createService/updateService
- Fix timesheet filename to use firstName-lastName-vykazprace-YYYY-MM.xlsx
- Fix company timesheet filename format similarly
- Removed timestamp from filename for cleaner naming

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 11:30:17 +01:00
richardtekula
5ade261cb2 fix: Timesheet naming and todo auto-assign fixes
- Fix timesheet filename to use firstName-lastName format with username fallback
- Remove auto-assign creator to todos (user must manually select assignees)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 11:20:10 +01:00
richardtekula
e5a88c36a9 Merge branch 'hotfix/part2' into hotfix/final 2026-01-22 08:00:47 +01:00
richardtekula
284d905d18 feat: Add notes search endpoint for enhanced global search
- Add searchNotes service function with company/project info
- Add /notes/search endpoint for searching notes content
- Returns matching notes with linked company/project names

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 07:49:10 +01:00
richardtekula
a0a6656a49 feat: Hotfix Part1 - Backend support for company postal code, service tiers, timesheet naming
- Add postal_code column to companies table
- Add pricing_tiers column to services table for tiered pricing
- Update timesheet upload to generate filename in format {firstname}-{lastname}-timesheet-{date}

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 07:46:50 +01:00
richardtekula
826fd467bc feat: Add farba field and company details to AI Kurzy module
- Add farba (color) field to kurzy schema and Zod validation
- Add company detail fields (firma_ico, firma_dic, firma_ic_dph, firma_sidlo) to ucastnici
- Remove console logs from ai-kurzy service
- Add SQL migration scripts for schema updates and data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:27:03 +01:00
richardtekula
4089bb4be2 feat: AI Kurzy module, project/service documents, services SQL import
- Add AI Kurzy module with courses, participants, and registrations management
- Add project documents and service documents features
- Add service folders for document organization
- Add SQL import queries for services from firmy.slovensko.ai
- Update todo notifications and group messaging
- Various API improvements and bug fixes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 11:32:49 +01:00
richardtekula
d9f16ad0a6 feat: Group chat and push notifications
- Add group chat tables (chat_groups, chat_group_members, group_messages)
- Add push subscriptions table for web push notifications
- Add group service, controller, routes
- Add push service, controller, routes
- Integrate push notifications with todos, messages, group messages

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 07:27:13 +01:00
richardtekula
73a3c6bf95 hotfix: Security, performance, and code cleanup
- Remove hardcoded database password fallback
- Add encryption salt validation (min 32 chars)
- Separate EMAIL_ENCRYPTION_KEY from JWT_SECRET
- Fix command injection in status.service.js (use execFileSync)
- Remove unnecessary SQL injection regex middleware
- Create shared utilities (queryBuilder, pagination, emailAccountHelper)
- Fix N+1 query problems in contact and todo services
- Merge duplicate JMAP config functions
- Add database indexes migration
- Standardize error responses with error codes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 07:17:23 +01:00
richardtekula
0523087961 feat: Add email signature feature
- Add email_signatures table to schema
- Add email signature service, controller, routes
- Users can create/edit signature in Profile
- Toggle to include signature when sending email replies

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 19:11:51 +01:00
richardtekula
514b6c8a92 feat: Add services, company documents, company timesheet export
- Add services table and CRUD endpoints (/api/services)
- Add company documents upload/download functionality
- Add company timesheet XLSX export endpoint
- Remove admin requirement from event routes (all authenticated users can manage events)
- Add service validators

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 18:45:01 +01:00
richardtekula
b542d1d635 fix: Remove phone from required fields in contact controller
Phone was incorrectly required in the controller validation
even though schema and database allow null.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 10:31:43 +01:00
richardtekula
d13442a979 fix: Accept null for all optional contact fields
lastName and secondaryEmail schemas now accept null values
sent from frontend, matching other optional fields pattern.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 10:20:50 +01:00
richardtekula
c1657ac37b fix: Allow empty string for phone in contact validation
The Zod schema was rejecting empty strings sent from the frontend.
Changed from z.string().optional().nullable() to z.union pattern
to properly handle "", null, and undefined values.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 10:07:46 +01:00
richardtekula
47b68e672b feat: Member permissions, optional phone, public users endpoint
- Allow members to create todos, companies, projects
- Auto-assign creator to resources (companyUsers, projectUsers, todoUsers)
- Add public /api/users endpoint for all authenticated users
- Make phone field optional in personal contacts (schema + validation)
- Update todo routes to use checkTodoAccess for updates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 07:08:42 +01:00
richardtekula
3e8cd7b6ce fix: Add description field to personal contacts
- Add description to Zod validation schema
- Add description to controller normalizePayload function

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 10:34:35 +01:00
richardtekula
2a9377ce3d feat: Add internal chat system and network access support
- Add messages table schema with soft delete support
- Add message service, controller and routes
- Update CORS to allow local network IPs
- Update server to listen on 0.0.0.0
- Fix cookie sameSite for local network development

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 10:13:14 +01:00
richardtekula
70fa080455 feat: Add user management APIs, status enum, enhanced notifications
- Add updateUser and resetUserPassword admin endpoints
- Change company status from boolean to enum (registered, lead, customer, inactive)
- Add 'important' event type to calendar validators and email templates
- Add 1-hour-before event notifications cron job
- Add 18:00 evening notifications for next-day events
- Add contact description field support
- Fix count() function usage in admin service
- Add SQL migrations for schema changes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 09:41:29 +01:00
richardtekula
5d01fc9542 add license.txt 2025-12-29 09:02:24 +01:00
richardtekula
794d300746 add test to gitignore & jest settings 2025-12-17 10:54:59 +01:00
richardtekula
3cd2531f6b fix: Improve logging - fix LOG_LEVEL filter, reduce HTTP noise
- Fix LOG_LEVEL filtering logic (was inverted)
- HTTP logs now only show errors (4xx, 5xx) by default
- Add database connection check at startup
- Cron jobs logged on separate lines
- LOG_LEVEL=debug shows all HTTP requests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 09:54:07 +01:00
richardtekula
095a3a5b03 refactor: Clean up cron initialization logs
Single summary line instead of verbose duplicates:
[INFO] Cron jobs initialized: Calendar (07:00), Audit cleanup (00:00)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 09:50:03 +01:00
richardtekula
2dadc67013 refactor: Move verbose email sync logs to debug level
Email sync operations now only show in LOG_LEVEL=debug mode.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 09:47:47 +01:00
richardtekula
bd44458c32 refactor: Clean up logging system with LOG_LEVEL filtering
- Add LOG_LEVEL env variable support (debug, info, warn, error)
- Default to 'info' level for production-ready logs
- Integrate Morgan HTTP logging with custom logger
- Remove console.logs and replace with custom logger
- Remove sensitive password debug logs from email service
- Remove noisy warn logs from email sync and event notifier
- Add gray color for timestamps to improve readability

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 09:45:00 +01:00
richardtekula
f8d8bb2330 feat: Add cron job for audit logs cleanup
- Add cleanupAuditLogs.js with daily cleanup job
- Delete audit logs older than 7 days
- Runs every day at midnight (00:00)
- Export cleanupOldAuditLogs for manual triggers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 07:42:48 +01:00
richardtekula
0585e51b25 feat: Add comprehensive audit logging system
- Add audit logging for contacts (link company, create company from contact)
- Add audit logging for notes (create, update, delete)
- Add audit logging for companies (update, user assign/remove, reminder CRUD)
- Add audit logging for projects (update, user assign/remove)
- Add audit logging for todos (update, uncomplete)
- Add audit logging for time entries (update, delete)
- Add audit logging for timesheets (upload, delete)
- Add audit logging for user deletion
- Add pagination and filters to audit logs API (userId, action, resource, dateFrom, dateTo)
- Add endpoints for distinct actions and resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 07:19:40 +01:00
richardtekula
548a8effdb feat: Add manual event notification endpoint for admins
- POST /api/events/:eventId/notify - send notifications from admin's email
- sendSingleEventNotification() uses admin's primary email account
- getSenderAccountByUserId() to get admin's email credentials

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 09:06:30 +01:00
richardtekula
2d6198b5f8 fix: Add admin-only protection to sensitive routes
- GET /admin/users now requires admin role
- GET /time-tracking/running-all now requires admin role
- GET /notes now requires admin role
- GET /audit-logs now requires admin role

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 08:39:21 +01:00
richardtekula
232b8608e5 docs: Add cron jobs and notifications documentation
- Add section 12: Cron Jobs a Notifikácie
- Update project structure with cron/ folder
- Add admin trigger-notifications endpoint to API docs
- Add notification env variables to config section
- Include examples, logs, and extension guide

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 16:04:54 +01:00
richardtekula
8c9912db9d feat: Add NOTIFICATION_TEST_MODE for cron testing
When NOTIFICATION_TEST_MODE=true, cron runs every minute instead of
at the scheduled time. Useful for testing email notifications.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 15:57:19 +01:00
richardtekula
77754d0668 feat: Add daily event notification emails via cron job
- Add node-cron for scheduled tasks
- Create cron/calendar structure with:
  - email-template.js: HTML email template for event notifications
  - event-notifier.js: Logic to query tomorrow's events and send emails
  - index.js: Cron scheduler (runs daily at configurable time)
- Send notifications via JMAP using sender email from database
- Add admin endpoint POST /api/admin/trigger-notifications for testing
- Add env variables: NOTIFICATION_TIME, NOTIFICATION_SENDER_EMAIL

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 14:27:53 +01:00
richardtekula
3eb2f6ea02 feat: Replace Meetings with Calendar - events with types and assigned users
- Rename meetings table to events with type field (meeting/event)
- Add eventUsers junction table for user assignments
- Members see only events they're assigned to
- Calendar endpoint returns events + todos for month
- Add migration SQL for database changes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-15 10:50:31 +01:00
richardtekula
f828af562d feat: Add dueDate (date+time) to notes and update reminders to datetime
- Add dueDate timestamp field to notes schema
- Update note validators to accept dueDate
- Update note service to handle dueDate in CRUD operations
- Fix company and project controllers to pass dueDate
- Fix route validations to include dueDate field

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 07:03:29 +01:00
richardtekula
8770a98db8 feat: Add company linking to personal contacts
- Add companyId column to personal_contacts table
- Update personal-contact service to include companyName in list
- Add getContactsByCompanyId function for company contacts endpoint
- Add GET /companies/:companyId/contacts endpoint
- Add companyId to contact validation schema

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 08:03:29 +01:00
richardtekula
8656fb1db0 feat: Add creator info, team management for companies, and member access control
- Add creator info (username) to companies, projects, and notes responses
- Add company_users table for team management on companies
- Add resourceAccessMiddleware for member access control
- Members can only see resources they are directly assigned to
- Companies, projects, and todos are now filtered by user assignments
- Add personal contacts feature

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 07:41:57 +01:00