Files
crm-server/FRESH_START_README.md
richardtekula bb851639b8 Add Timesheets API with file upload and role-based access
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>
2025-11-21 08:35:30 +01:00

297 lines
7.4 KiB
Markdown

# 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
```bash
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
```bash
node src/scripts/seed-admin.js
```
**Admin credentials:**
- Username: `admin`
- Password: `admin123`
⚠️ **DÔLEŽITÉ:** Zmeň heslo po prvom prihlásení!
### 3. Spusť server
```bash
npm run dev
```
### 4. Prihlás sa a začni používať
1. Otvor frontend aplikáciu
2. Prihlás sa ako admin (admin / admin123)
3. Vytvor používateľov
4. 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` - UNIQUE
- `added_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 kontaktu
- `sent_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
```
1. Admin 1 pridá `firma@example.com` → Vytvorí sa nový email account
2. Admin 2 pridá `firma@example.com` (s rovnakým heslom) → Automaticky sa pridá k existujúcemu accountu
3. Obaja vidia rovnaké kontakty a emaily pre `firma@example.com`
4. 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.com` už 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
```javascript
// 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
```javascript
// 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)
```javascript
// 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.createEmailAccount` s 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 `accountId` parameter
**Bug č.4:** Nepoužívané stĺpce v `users` tabuľke
- **Opravené:** `email`, `emailPassword`, `jmapAccountId` odstránené z users tabuľky
---
## 🧪 Testovanie
### Test 1: Vytvorenie používateľa s emailom
```bash
# 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
```bash
# 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
```bash
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:**
1. User nemá link v `user_email_accounts` tabuľke
2. Email account neexistuje v `email_accounts` tabuľke
**Riešenie:**
```sql
-- 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:
1. Skontrolujte logs: `tail -f logs/server.log`
2. Skontrolujte databázu: `psql -U username -d database`
3. Re-run fresh database script
---
Vytvoril: Claude Code
Dátum: 2025-11-20
Verzia: 2.0 (Many-to-many)