Backend Features:
- Timesheets database table (id, userId, fileName, filePath, fileType, fileSize, year, month, timestamps)
- File upload with multer (memory storage, 10MB limit, PDF/Excel validation)
- Structured file storage: uploads/timesheets/{userId}/{year}/{month}/
- RESTful API endpoints:
* POST /api/timesheets/upload - Upload timesheet
* GET /api/timesheets/my - Get user's timesheets (with filters)
* GET /api/timesheets/all - Get all timesheets (admin only)
* GET /api/timesheets/:id/download - Download file
* DELETE /api/timesheets/:id - Delete timesheet
- Role-based permissions: users access own files, admins access all
- Proper error handling and file cleanup on errors
- Database migration for timesheets table
Technical:
- Uses req.user.role for permission checks
- Automatic directory creation for user/year/month structure
- Blob URL cleanup and proper file handling
- Integration with existing auth middleware
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
7.4 KiB
Fresh Start - Nový CRM systém so zdieľanými email účtami
🎯 Čo je nové?
Kompletne refaktorovaný CRM systém s many-to-many vzťahom medzi používateľmi a emailovými účtami.
Hlavné vylepšenia:
✅ Zdieľané emailové účty - Viacero používateľov môže mať prístup k jednému email účtu ✅ Jednoduchý dizajn - Žiadne zbytočné role (owner/member) ✅ Izolované kontakty - Kontakty patria k email účtu, nie k používateľovi ✅ Tracking odpovedí - Vidíte kto poslal odpoveď (sentByUserId)
🚀 Rýchly štart (Fresh Database)
1. Drop a vytvor databázu od nula
cd /home/richardtekula/Documents/WORK/crm-server
node src/scripts/fresh-database.js
Čo tento script robí:
- Vymaže všetky existujúce tabuľky
- Vytvorí nové tabuľky s many-to-many vzťahmi
- Vytvorí potrebné indexy
2. Vytvor admin používateľa
node src/scripts/seed-admin.js
Admin credentials:
- Username:
admin - Password:
admin123
⚠️ DÔLEŽITÉ: Zmeň heslo po prvom prihlásení!
3. Spusť server
npm run dev
4. Prihlás sa a začni používať
- Otvor frontend aplikáciu
- Prihlás sa ako admin (admin / admin123)
- Vytvor používateľov
- Pridaj emailové účty
📊 Databázová schéma
users
Používatelia systému (admini a členovia).
email_accounts
Emailové účty - môžu byť zdieľané medzi viacerými používateľmi.
email- UNIQUE (jeden email = jeden záznam v systéme)
user_email_accounts
Junction table - many-to-many medzi users a email_accounts.
user_id+email_account_id- UNIQUE (každý user môže mať account len raz)is_primary- primárny účet pre daného usera
contacts
Kontakty patriace k emailovému účtu (nie k používateľovi!).
email_account_id+email- UNIQUEadded_by- kto pridal kontakt (nullable)
emails
Emaily patriace k emailovému účtu.
email_account_id- k akému accountu patrícontact_id- od ktorého kontaktusent_by_user_id- kto poslal odpoveď (null ak prijatý email)
🔄 Ako fungujú zdieľané účty?
Scenár 1: Dva admini, jeden email account
Admin 1: richardtekula@example.com
Admin 2: peterkolar@example.com
Oba majú prístup k: firma@example.com
- Admin 1 pridá
firma@example.com→ Vytvorí sa nový email account - Admin 2 pridá
firma@example.com(s rovnakým heslom) → Automaticky sa pridá k existujúcemu accountu - Obaja vidia rovnaké kontakty a emaily pre
firma@example.com - Keď Admin 1 odpovie na email, Admin 2 vidí že odpoveď poslal Admin 1 (
sentByUserId)
Scenár 2: Admin vytvorí používateľa s emailom
Admin vytvorí usera "jan" s emailom firma@example.com
- Ak
firma@example.comuž existuje → jan sa automaticky pripojí k existujúcemu accountu (zdieľanie) - Ak neexistuje → vytvorí sa nový account a jan je prvý používateľ
🎨 API zmeny
Email Accounts
// Get user's email accounts
GET /api/email-accounts
// Returns: [{ id, email, jmapAccountId, isActive, isPrimary, addedAt }]
// Add email account
POST /api/email-accounts
Body: { email, emailPassword }
// Automaticky vytvorí many-to-many link
// Ak account už existuje, pripojí usera k existujúcemu
// Remove email account
DELETE /api/email-accounts/:accountId
// Odstráni link pre daného usera
// Ak je to posledný user, vymaže aj samotný email account
// Set primary account
POST /api/email-accounts/:accountId/set-primary
Contacts
// Get contacts for email account
GET /api/contacts?accountId=xxx (REQUIRED)
// Add contact
POST /api/contacts
Body: { email, name, notes, accountId }
// Remove contact
DELETE /api/contacts/:contactId?accountId=xxx (REQUIRED)
// Update contact
PATCH /api/contacts/:contactId?accountId=xxx (REQUIRED)
Body: { name, notes }
DÔLEŽITÉ: accountId je teraz povinný parameter pre všetky contact operácie!
Users (Admin)
// Create user with email
POST /api/admin/users
Body: {
username,
firstName,
lastName,
email, // Optional
emailPassword // Optional
}
// Ak email existuje, user sa automaticky pripojí k existujúcemu accountu
🐛 Opravené bugy
✅ Bug č.1: Keď admin vytvoril používateľa s emailom, credentials išli do users tabuľky namiesto email_accounts
- Opravené: Používa
emailAccountService.createEmailAccounts many-to-many
✅ Bug č.2: Duplikátne kontakty keď viacero používateľov pridalo rovnaký email
- Opravené: Kontakty patria k
email_account, nie k jednotlivým používateľom - UNIQUE constraint:
(email_account_id, email)
✅ Bug č.3: Chýbajúci "mark as read" button
- Funguje: Frontend dostáva správne
accountIdparameter
✅ Bug č.4: Nepoužívané stĺpce v users tabuľke
- Opravené:
email,emailPassword,jmapAccountIdodstránené z users tabuľky
🧪 Testovanie
Test 1: Vytvorenie používateľa s emailom
# Ako admin:
1. Vytvor usera "jan" s emailom jan@firma.sk
2. Overiť že email account bol vytvorený
3. Prihlás sa ako jan
4. Overiť že vidíš jan@firma.sk v sidebari
Test 2: Zdieľanie email accountu
# Ako admin:
1. Vytvor usera "peter" s emailom jan@firma.sk (rovnaký ako vyššie!)
2. Overiť že peter sa pripojil k existujúcemu accountu
3. Prihlás sa ako peter
4. Overiť že peter vidí rovnaké kontakty ako jan
5. Peter pridá nový kontakt
6. Prihlás sa ako jan → overiť že jan vidí nový kontakt
Test 3: Odpoveď na email
1. Jan odpovie na email od kontaktu
2. Prihlás sa ako peter
3. Overiť že peter vidí odpoveď
4. Overiť že vidíš indikáciu "Sent by Jan" (sentByUserId)
📝 Poznámky pre vývojárov
Many-to-many vzťah
users ←→ user_email_accounts ←→ email_accounts
- Jeden user môže mať viacero email accounts
- Jeden email account môže patriť viacerým userom
Kontakty a emaily patria k email accountu
email_accounts → contacts → emails
- Kontakty sú zdieľané medzi všetkými usermi s prístupom k danému email accountu
- Emaily sú zdieľané rovnako
Tracking odpovedí
emails.sent_by_user_id- kto poslal odpoveď- NULL = prijatý email (nie odpoveď)
- UUID = user, ktorý poslal odpoveď
🔒 Bezpečnosť
- Email heslá sú encrypted (nie hashed), lebo potrebujeme decryption pre JMAP
- Používateľské heslá sú bcrypt hashed
- Access control: User môže pristupovať len k email accountom, kde má link v
user_email_accounts
🚨 Troubleshooting
Problem: "Email účet nenájdený"
Možné príčiny:
- User nemá link v
user_email_accountstabuľke - Email account neexistuje v
email_accountstabuľke
Riešenie:
-- Check links
SELECT * FROM user_email_accounts WHERE user_id = 'your-user-id';
-- Check accounts
SELECT * FROM email_accounts;
Problem: "Kontakt už existuje"
Príčina: Kontakt s týmto emailom už existuje pre daný email account.
Riešenie: Kontakty sú zdieľané medzi všetkými usermi. Jeden email môže byť len raz per email account.
📞 Podpora
Ak narazíte na problémy:
- Skontrolujte logs:
tail -f logs/server.log - Skontrolujte databázu:
psql -U username -d database - Re-run fresh database script
Vytvoril: Claude Code Dátum: 2025-11-20 Verzia: 2.0 (Many-to-many)