1752 lines
28 KiB
Markdown
1752 lines
28 KiB
Markdown
# CondoPay — Documentazione API completa
|
|
|
|
Questa documentazione descrive tutti gli endpoint API disponibili nella soluzione CondoPay.
|
|
|
|
---
|
|
|
|
## Indice
|
|
|
|
1. [Configurazione base](#configurazione-base)
|
|
2. [Autenticazione](#autenticazione)
|
|
3. [Endpoint pubblici](#endpoint-pubblici)
|
|
4. [Autenticazione e profilo](#autenticazione-e-profilo)
|
|
5. [Impostazioni](#impostazioni)
|
|
6. [Condomini](#condomini)
|
|
7. [Famiglie](#famiglie)
|
|
8. [Pagamenti](#pagamenti)
|
|
9. [Utenti](#utenti)
|
|
10. [Avvisi](#avvisi)
|
|
11. [Comunicazioni](#comunicazioni)
|
|
12. [Ticket](#ticket)
|
|
13. [Spese straordinarie](#spese-straordinarie)
|
|
14. [Spese condominiali ordinarie](#spese-condominiali-ordinarie)
|
|
15. [Documenti](#documenti)
|
|
|
|
---
|
|
|
|
## Configurazione base
|
|
|
|
| Proprietà | Valore |
|
|
|-----------|--------|
|
|
| **Base URL** | `/api` (relativo all'host dell'applicazione) |
|
|
| **Content-Type** | `application/json` |
|
|
| **Formato risposta** | JSON |
|
|
|
|
### Header di autenticazione
|
|
|
|
Tutti gli endpoint protetti richiedono l'header:
|
|
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
Il token viene restituito dall'endpoint `POST /api/auth/login`.
|
|
|
|
---
|
|
|
|
## Autenticazione
|
|
|
|
### Token JWT
|
|
|
|
- **Scadenza**: 24 ore
|
|
- **Contenuto**: `{ id, email, role, familyId }`
|
|
- **Ruoli**: `admin`, `poweruser`, `user`
|
|
|
|
### Middleware
|
|
|
|
- **authenticateToken**: richiede un token valido (restituisce 401 se mancante o non valido)
|
|
- **requireAdmin**: richiede ruolo `admin` o `poweruser` (restituisce 403 se insufficiente)
|
|
|
|
---
|
|
|
|
## Endpoint pubblici
|
|
|
|
### GET /api/public/branding
|
|
|
|
Restituisce il branding dell'applicazione (senza autenticazione).
|
|
|
|
**Autenticazione**: Non richiesta
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"appName": "CondoPay",
|
|
"primaryColor": "blue",
|
|
"logoUrl": "",
|
|
"loginBackgroundUrl": ""
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Autenticazione e profilo
|
|
|
|
### POST /api/auth/login
|
|
|
|
Effettua il login con email e password.
|
|
|
|
**Autenticazione**: Non richiesta
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"email": "string",
|
|
"password": "string"
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
"user": {
|
|
"id": "string",
|
|
"email": "string",
|
|
"name": "string",
|
|
"role": "admin | poweruser | user",
|
|
"familyId": "string | null",
|
|
"receiveAlerts": true
|
|
}
|
|
}
|
|
```
|
|
|
|
**Errori**:
|
|
- `401`: Credenziali non valide
|
|
- `500`: Errore server
|
|
|
|
---
|
|
|
|
### PUT /api/profile
|
|
|
|
Aggiorna il profilo dell'utente autenticato.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"name": "string",
|
|
"phone": "string",
|
|
"password": "string (opzionale - solo se si cambia password)",
|
|
"receiveAlerts": true
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"user": {
|
|
"id": "string",
|
|
"email": "string",
|
|
"name": "string",
|
|
"role": "string",
|
|
"phone": "string",
|
|
"family_id": "string",
|
|
"receiveAlerts": true
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Impostazioni
|
|
|
|
### GET /api/settings
|
|
|
|
Restituisce le impostazioni generali dell'applicazione.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"currentYear": 2025,
|
|
"smtpConfig": {
|
|
"host": "string",
|
|
"port": 587,
|
|
"user": "string",
|
|
"pass": "string",
|
|
"secure": false,
|
|
"fromEmail": "string"
|
|
},
|
|
"storageConfig": {
|
|
"provider": "local_db | s3 | google_drive | dropbox | onedrive",
|
|
"apiKey": "string",
|
|
"apiSecret": "string",
|
|
"bucket": "string",
|
|
"region": "string"
|
|
},
|
|
"features": {
|
|
"multiCondo": true,
|
|
"tickets": true,
|
|
"payPal": true,
|
|
"notices": true,
|
|
"reports": true,
|
|
"extraordinaryExpenses": true,
|
|
"condoFinancialsView": false,
|
|
"documents": true
|
|
},
|
|
"branding": {
|
|
"appName": "CondoPay",
|
|
"primaryColor": "blue",
|
|
"logoUrl": "",
|
|
"loginBackgroundUrl": ""
|
|
}
|
|
}
|
|
```
|
|
|
|
**Errori**:
|
|
- `404`: Settings non trovati
|
|
- `500`: Errore server
|
|
|
|
---
|
|
|
|
### PUT /api/settings
|
|
|
|
Aggiorna le impostazioni generali.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"currentYear": 2025,
|
|
"smtpConfig": { },
|
|
"features": { },
|
|
"storageConfig": { },
|
|
"branding": { }
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
**Errori**:
|
|
- `403`: Accesso negato
|
|
- `500`: Errore server
|
|
|
|
---
|
|
|
|
### POST /api/settings/smtp-test
|
|
|
|
Invia un'email di test per verificare la configurazione SMTP.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"host": "smtp.example.com",
|
|
"port": 587,
|
|
"user": "string",
|
|
"pass": "string",
|
|
"secure": false,
|
|
"fromEmail": "string"
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
**Errori**:
|
|
- `400`: Parametri SMTP incompleti o errore invio
|
|
- `403`: Accesso negato
|
|
|
|
---
|
|
|
|
### GET /api/years
|
|
|
|
Restituisce gli anni disponibili per i pagamenti (anni con almeno un pagamento o anno corrente dalle impostazioni).
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[2025, 2024, 2023]
|
|
```
|
|
|
|
---
|
|
|
|
## Condomini
|
|
|
|
### GET /api/condos
|
|
|
|
Elenco di tutti i condomini.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"name": "string",
|
|
"address": "string",
|
|
"streetNumber": "string",
|
|
"city": "string",
|
|
"province": "string",
|
|
"zipCode": "string",
|
|
"notes": "string",
|
|
"iban": "string",
|
|
"paypalClientId": "string",
|
|
"defaultMonthlyQuota": 100.00,
|
|
"image": "string",
|
|
"dueDay": 10
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### POST /api/condos
|
|
|
|
Crea un nuovo condominio.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"name": "string",
|
|
"address": "string",
|
|
"streetNumber": "string",
|
|
"city": "string",
|
|
"province": "string",
|
|
"zipCode": "string",
|
|
"notes": "string",
|
|
"defaultMonthlyQuota": 100.00,
|
|
"paypalClientId": "string",
|
|
"dueDay": 10
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"name": "string",
|
|
"address": "string",
|
|
"streetNumber": "string",
|
|
"city": "string",
|
|
"province": "string",
|
|
"zipCode": "string",
|
|
"notes": "string",
|
|
"defaultMonthlyQuota": 100.00,
|
|
"paypalClientId": "string",
|
|
"dueDay": 10
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### PUT /api/condos/:id
|
|
|
|
Aggiorna un condominio esistente.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID del condominio
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"name": "string",
|
|
"address": "string",
|
|
"streetNumber": "string",
|
|
"city": "string",
|
|
"province": "string",
|
|
"zipCode": "string",
|
|
"notes": "string",
|
|
"defaultMonthlyQuota": 100.00,
|
|
"paypalClientId": "string",
|
|
"dueDay": 10
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### DELETE /api/condos/:id
|
|
|
|
Elimina un condominio.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID del condominio
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Famiglie
|
|
|
|
### GET /api/families
|
|
|
|
Elenco delle famiglie. Per admin/poweruser può essere filtrato per condominio; per utenti normali restituisce solo la propria famiglia.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Query parameters**:
|
|
| Parametro | Tipo | Descrizione |
|
|
|-----------|------|-------------|
|
|
| condoId | string | ID del condominio (opzionale, per admin/poweruser) |
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"condoId": "uuid",
|
|
"name": "string",
|
|
"unitNumber": "string",
|
|
"stair": "string",
|
|
"floor": "string",
|
|
"notes": "string",
|
|
"contactEmail": "string",
|
|
"customMonthlyQuota": 120.00,
|
|
"balance": 0
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### POST /api/families
|
|
|
|
Crea una nuova famiglia.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"condoId": "uuid",
|
|
"name": "string",
|
|
"unitNumber": "string",
|
|
"stair": "string",
|
|
"floor": "string",
|
|
"notes": "string",
|
|
"contactEmail": "string",
|
|
"customMonthlyQuota": 120.00
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"condoId": "uuid",
|
|
"name": "string",
|
|
"unitNumber": "string",
|
|
"stair": "string",
|
|
"floor": "string",
|
|
"notes": "string",
|
|
"contactEmail": "string",
|
|
"customMonthlyQuota": 120.00
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### PUT /api/families/:id
|
|
|
|
Aggiorna una famiglia esistente.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID della famiglia
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"name": "string",
|
|
"unitNumber": "string",
|
|
"stair": "string",
|
|
"floor": "string",
|
|
"notes": "string",
|
|
"contactEmail": "string",
|
|
"customMonthlyQuota": 120.00
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### DELETE /api/families/:id
|
|
|
|
Elimina una famiglia.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID della famiglia
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Pagamenti
|
|
|
|
### GET /api/payments
|
|
|
|
Elenco dei pagamenti (quota condominiale ordinaria).
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Query parameters**:
|
|
| Parametro | Tipo | Descrizione |
|
|
|-----------|------|-------------|
|
|
| familyId | string | Filtra per famiglia |
|
|
| condoId | string | Filtra per condominio |
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"familyId": "uuid",
|
|
"amount": 100.00,
|
|
"datePaid": "2025-01-15T00:00:00.000Z",
|
|
"forMonth": 1,
|
|
"forYear": 2025,
|
|
"notes": "string"
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### POST /api/payments
|
|
|
|
Registra un nuovo pagamento di quota ordinaria.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"familyId": "uuid",
|
|
"amount": 100.00,
|
|
"datePaid": "2025-01-15",
|
|
"forMonth": 1,
|
|
"forYear": 2025,
|
|
"notes": "string"
|
|
}
|
|
```
|
|
|
|
**Restrizioni**: Gli utenti non admin possono registrare pagamenti solo per la propria famiglia (`familyId` deve coincidere con `req.user.familyId`).
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"familyId": "uuid",
|
|
"amount": 100.00,
|
|
"datePaid": "2025-01-15",
|
|
"forMonth": 1,
|
|
"forYear": 2025,
|
|
"notes": "string"
|
|
}
|
|
```
|
|
|
|
**Errori**:
|
|
- `403`: Unauthorized (utente che tenta di registrare per un'altra famiglia)
|
|
|
|
---
|
|
|
|
## Utenti
|
|
|
|
### GET /api/users
|
|
|
|
Elenco degli utenti. Può essere filtrato per condominio.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Query parameters**:
|
|
| Parametro | Tipo | Descrizione |
|
|
|-----------|------|-------------|
|
|
| condoId | string | Restituisce utenti del condominio + admin/poweruser |
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"email": "string",
|
|
"name": "string",
|
|
"role": "admin | poweruser | user",
|
|
"phone": "string",
|
|
"familyId": "uuid | null",
|
|
"receiveAlerts": true
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### POST /api/users
|
|
|
|
Crea un nuovo utente.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"email": "string",
|
|
"password": "string",
|
|
"name": "string",
|
|
"role": "admin | poweruser | user",
|
|
"phone": "string",
|
|
"familyId": "uuid | null",
|
|
"receiveAlerts": true
|
|
}
|
|
```
|
|
|
|
**Nota**: Se `password` non viene fornita, viene usata `"password"`.
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"id": "uuid"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### PUT /api/users/:id
|
|
|
|
Aggiorna un utente esistente.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID dell'utente
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"email": "string",
|
|
"name": "string",
|
|
"role": "admin | poweruser | user",
|
|
"phone": "string",
|
|
"familyId": "uuid | null",
|
|
"receiveAlerts": true,
|
|
"password": "string (opzionale - solo se si cambia password)"
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### DELETE /api/users/:id
|
|
|
|
Elimina un utente.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID dell'utente
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Avvisi
|
|
|
|
Gli avvisi sono definizioni di email automatiche (es. promemoria scadenza quote).
|
|
|
|
### GET /api/alerts
|
|
|
|
Elenco degli avvisi configurati per un condominio.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Query parameters**:
|
|
| Parametro | Tipo | Descrizione |
|
|
|-----------|------|-------------|
|
|
| condoId | string | ID del condominio |
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"subject": "string",
|
|
"body": "string",
|
|
"daysOffset": 1,
|
|
"offsetType": "before_next_month",
|
|
"sendHour": 9,
|
|
"active": true,
|
|
"lastSent": "2025-01-01T09:00:00.000Z"
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### POST /api/alerts
|
|
|
|
Crea un nuovo avviso.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"condoId": "uuid",
|
|
"subject": "string",
|
|
"body": "string",
|
|
"daysOffset": 1,
|
|
"offsetType": "before_next_month",
|
|
"sendHour": 9,
|
|
"active": true
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"subject": "string",
|
|
"body": "string",
|
|
"daysOffset": 1,
|
|
"offsetType": "string",
|
|
"sendHour": 9,
|
|
"active": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### PUT /api/alerts/:id
|
|
|
|
Aggiorna un avviso esistente.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID dell'avviso
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"subject": "string",
|
|
"body": "string",
|
|
"daysOffset": 1,
|
|
"offsetType": "string",
|
|
"sendHour": 9,
|
|
"active": true
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"id": "uuid"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### DELETE /api/alerts/:id
|
|
|
|
Elimina un avviso.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID dell'avviso
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Comunicazioni (Notices)
|
|
|
|
### GET /api/notices
|
|
|
|
Elenco delle comunicazioni/avvisi per un condominio.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Query parameters**:
|
|
| Parametro | Tipo | Descrizione |
|
|
|-----------|------|-------------|
|
|
| condoId | string | ID del condominio |
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"condoId": "uuid",
|
|
"title": "string",
|
|
"content": "string",
|
|
"type": "info | warning | maintenance | event",
|
|
"link": "string",
|
|
"date": "2025-01-15T00:00:00.000Z",
|
|
"active": true,
|
|
"targetFamilyIds": []
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### GET /api/notices/unread
|
|
|
|
Elenco delle comunicazioni non lette per un utente in un condominio.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Query parameters**:
|
|
| Parametro | Tipo | Descrizione |
|
|
|-----------|------|-------------|
|
|
| userId | string | ID dell'utente |
|
|
| condoId | string | ID del condominio |
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"title": "string",
|
|
"content": "string",
|
|
"type": "info",
|
|
"date": "2025-01-15T00:00:00.000Z",
|
|
...
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### GET /api/notices/:id/read-status
|
|
|
|
Stato di lettura di una comunicazione (chi l'ha letta).
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID della comunicazione
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"userId": "uuid",
|
|
"readAt": "2025-01-15T10:00:00.000Z"
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### POST /api/notices
|
|
|
|
Crea una nuova comunicazione.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"condoId": "uuid",
|
|
"title": "string",
|
|
"content": "string",
|
|
"type": "info | warning | maintenance | event",
|
|
"link": "string",
|
|
"active": true,
|
|
"targetFamilyIds": ["uuid1", "uuid2"]
|
|
}
|
|
```
|
|
|
|
**Nota**: `targetFamilyIds` vuoto = comunicazione visibile a tutte le famiglie.
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"id": "uuid"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### PUT /api/notices/:id
|
|
|
|
Aggiorna una comunicazione esistente.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID della comunicazione
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"title": "string",
|
|
"content": "string",
|
|
"type": "info | warning | maintenance | event",
|
|
"link": "string",
|
|
"active": true,
|
|
"targetFamilyIds": []
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### DELETE /api/notices/:id
|
|
|
|
Elimina una comunicazione.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID della comunicazione
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### POST /api/notices/:id/read
|
|
|
|
Segna una comunicazione come letta per un utente.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Parametri percorso**: `id` — ID della comunicazione
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"userId": "uuid"
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Ticket
|
|
|
|
### GET /api/tickets
|
|
|
|
Elenco dei ticket. Gli utenti non admin vedono solo i propri ticket.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Query parameters**:
|
|
| Parametro | Tipo | Descrizione |
|
|
|-----------|------|-------------|
|
|
| condoId | string | ID del condominio |
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"condoId": "uuid",
|
|
"userId": "uuid",
|
|
"title": "string",
|
|
"description": "string",
|
|
"status": "OPEN | IN_PROGRESS | SUSPENDED | RESOLVED | CLOSED",
|
|
"priority": "LOW | MEDIUM | HIGH | URGENT",
|
|
"category": "MAINTENANCE | ADMINISTRATIVE | NOISE | CLEANING | OTHER",
|
|
"createdAt": "2025-01-15T00:00:00.000Z",
|
|
"updatedAt": "2025-01-15T00:00:00.000Z",
|
|
"userName": "string",
|
|
"userEmail": "string",
|
|
"attachments": [
|
|
{
|
|
"id": "uuid",
|
|
"fileName": "string",
|
|
"fileType": "string"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### POST /api/tickets
|
|
|
|
Crea un nuovo ticket.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"condoId": "uuid",
|
|
"title": "string",
|
|
"description": "string",
|
|
"priority": "LOW | MEDIUM | HIGH | URGENT",
|
|
"category": "MAINTENANCE | ADMINISTRATIVE | NOISE | CLEANING | OTHER",
|
|
"attachments": [
|
|
{
|
|
"fileName": "string",
|
|
"fileType": "string",
|
|
"data": "base64-string"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"id": "uuid"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### PUT /api/tickets/:id
|
|
|
|
Aggiorna stato e priorità di un ticket.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Parametri percorso**: `id` — ID del ticket
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"status": "OPEN | IN_PROGRESS | SUSPENDED | RESOLVED | CLOSED",
|
|
"priority": "LOW | MEDIUM | HIGH | URGENT"
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### DELETE /api/tickets/:id
|
|
|
|
Elimina un ticket.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Parametri percorso**: `id` — ID del ticket
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### GET /api/tickets/:id/attachments/:attId
|
|
|
|
Scarica un allegato di un ticket.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Parametri percorso**:
|
|
- `id` — ID del ticket
|
|
- `attId` — ID dell'allegato
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"fileName": "string",
|
|
"fileType": "string",
|
|
"data": "base64-string"
|
|
}
|
|
```
|
|
|
|
**Errori**: `404` — Allegato non trovato
|
|
|
|
---
|
|
|
|
### GET /api/tickets/:id/comments
|
|
|
|
Elenco dei commenti di un ticket.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Parametri percorso**: `id` — ID del ticket
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"ticketId": "uuid",
|
|
"userId": "uuid",
|
|
"userName": "string",
|
|
"text": "string",
|
|
"createdAt": "2025-01-15T00:00:00.000Z"
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### POST /api/tickets/:id/comments
|
|
|
|
Aggiunge un commento a un ticket.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Parametri percorso**: `id` — ID del ticket
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"text": "string"
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Spese straordinarie
|
|
|
|
### GET /api/expenses
|
|
|
|
Elenco delle spese straordinarie di un condominio.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Query parameters**:
|
|
| Parametro | Tipo | Descrizione |
|
|
|-----------|------|-------------|
|
|
| condoId | string | ID del condominio |
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"condoId": "uuid",
|
|
"title": "string",
|
|
"description": "string",
|
|
"startDate": "2025-01-01",
|
|
"endDate": "2025-06-30",
|
|
"contractorName": "string",
|
|
"totalAmount": 5000.00
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### GET /api/expenses/:id
|
|
|
|
Dettaglio di una spesa straordinaria (con voci, quote per famiglia, allegati).
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Parametri percorso**: `id` — ID della spesa
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"condoId": "uuid",
|
|
"title": "string",
|
|
"description": "string",
|
|
"startDate": "2025-01-01",
|
|
"endDate": "2025-06-30",
|
|
"contractorName": "string",
|
|
"totalAmount": 5000.00,
|
|
"items": [
|
|
{
|
|
"description": "string",
|
|
"amount": 2500.00
|
|
}
|
|
],
|
|
"shares": [
|
|
{
|
|
"id": "uuid",
|
|
"familyId": "uuid",
|
|
"familyName": "string",
|
|
"percentage": 10.00,
|
|
"amountDue": 500.00,
|
|
"amountPaid": 0,
|
|
"status": "UNPAID | PARTIAL | PAID"
|
|
}
|
|
],
|
|
"attachments": [
|
|
{
|
|
"id": "uuid",
|
|
"fileName": "string",
|
|
"fileType": "string"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Errori**: `404` — Spesa non trovata
|
|
|
|
---
|
|
|
|
### POST /api/expenses
|
|
|
|
Crea una nuova spesa straordinaria.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"condoId": "uuid",
|
|
"title": "string",
|
|
"description": "string",
|
|
"startDate": "2025-01-01",
|
|
"endDate": "2025-06-30",
|
|
"contractorName": "string",
|
|
"items": [
|
|
{
|
|
"description": "string",
|
|
"amount": 2500.00
|
|
}
|
|
],
|
|
"shares": [
|
|
{
|
|
"familyId": "uuid",
|
|
"percentage": 10.00,
|
|
"amountDue": 500.00
|
|
}
|
|
],
|
|
"attachments": [
|
|
{
|
|
"fileName": "string",
|
|
"fileType": "string",
|
|
"data": "base64-string"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Nota**: `totalAmount` è calcolato automaticamente dalla somma di `items`.
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"id": "uuid"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### DELETE /api/expenses/:id
|
|
|
|
Elimina una spesa straordinaria.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID della spesa
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### GET /api/expenses/:id/attachments/:attId
|
|
|
|
Scarica un allegato di una spesa straordinaria.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Parametri percorso**:
|
|
- `id` — ID della spesa
|
|
- `attId` — ID dell'allegato
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"fileName": "string",
|
|
"fileType": "string",
|
|
"data": "base64-string"
|
|
}
|
|
```
|
|
|
|
**Errori**: `404` — File non trovato
|
|
|
|
---
|
|
|
|
### GET /api/my-expenses
|
|
|
|
Elenco delle quote straordinarie assegnate alla famiglia dell'utente loggato.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Query parameters**:
|
|
| Parametro | Tipo | Descrizione |
|
|
|-----------|------|-------------|
|
|
| condoId | string | ID del condominio |
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"title": "string",
|
|
"startDate": "2025-01-01",
|
|
"totalAmount": 5000.00,
|
|
"contractorName": "string",
|
|
"myShare": {
|
|
"percentage": 10.00,
|
|
"amountDue": 500.00,
|
|
"amountPaid": 0,
|
|
"status": "UNPAID"
|
|
}
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### POST /api/expenses/:id/pay
|
|
|
|
Registra un pagamento per una quota straordinaria.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Parametri percorso**: `id` — ID della spesa straordinaria
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"amount": 250.00,
|
|
"notes": "string",
|
|
"familyId": "uuid (opzionale - solo admin/poweruser)"
|
|
}
|
|
```
|
|
|
|
**Nota**: Gli utenti normali pagano per la propria famiglia; admin/poweruser possono specificare `familyId`.
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
**Errori**:
|
|
- `400`: Famiglia non trovata
|
|
- `500`: Share non trovata o errore
|
|
|
|
---
|
|
|
|
### GET /api/expenses/:id/shares/:familyId/payments
|
|
|
|
Elenco dei pagamenti effettuati per una quota straordinaria di una famiglia.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Parametri percorso**:
|
|
- `id` — ID della spesa
|
|
- `familyId` — ID della famiglia
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"amount": 250.00,
|
|
"datePaid": "2025-01-15T00:00:00.000Z",
|
|
"notes": "string"
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### DELETE /api/expenses/payments/:paymentId
|
|
|
|
Elimina un pagamento straordinario (annulla il pagamento e aggiorna lo stato della quota).
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `paymentId` — ID del pagamento
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
**Errori**:
|
|
- `400`: Pagamento non trovato o non è un pagamento straordinario
|
|
|
|
---
|
|
|
|
## Spese condominiali ordinarie
|
|
|
|
Gestione delle uscite ordinarie del condominio (utenze, fornitori, ecc.).
|
|
|
|
### GET /api/condo-expenses
|
|
|
|
Elenco delle spese ordinarie del condominio.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Query parameters**:
|
|
| Parametro | Tipo | Descrizione |
|
|
|-----------|------|-------------|
|
|
| condoId | string | ID del condominio |
|
|
| year | number | Anno (opzionale) |
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"condoId": "uuid",
|
|
"description": "string",
|
|
"supplierName": "string",
|
|
"amount": 500.00,
|
|
"paymentDate": "2025-01-15",
|
|
"status": "PAID | UNPAID | SUSPENDED",
|
|
"paymentMethod": "string",
|
|
"invoiceNumber": "string",
|
|
"notes": "string",
|
|
"createdAt": "2025-01-15T00:00:00.000Z",
|
|
"attachments": [
|
|
{
|
|
"id": "uuid",
|
|
"fileName": "string",
|
|
"fileType": "string"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### POST /api/condo-expenses
|
|
|
|
Crea una nuova spesa ordinaria.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"condoId": "uuid",
|
|
"description": "string",
|
|
"supplierName": "string",
|
|
"amount": 500.00,
|
|
"paymentDate": "2025-01-15",
|
|
"status": "PAID | UNPAID | SUSPENDED",
|
|
"paymentMethod": "string",
|
|
"invoiceNumber": "string",
|
|
"notes": "string",
|
|
"attachments": [
|
|
{
|
|
"fileName": "string",
|
|
"fileType": "string",
|
|
"data": "base64-string"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"id": "uuid"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### PUT /api/condo-expenses/:id
|
|
|
|
Aggiorna una spesa ordinaria esistente.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID della spesa
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"description": "string",
|
|
"supplierName": "string",
|
|
"amount": 500.00,
|
|
"paymentDate": "2025-01-15",
|
|
"status": "PAID | UNPAID | SUSPENDED",
|
|
"paymentMethod": "string",
|
|
"invoiceNumber": "string",
|
|
"notes": "string"
|
|
}
|
|
```
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### DELETE /api/condo-expenses/:id
|
|
|
|
Elimina una spesa ordinaria.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID della spesa
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### GET /api/condo-expenses/:id/attachments/:attId
|
|
|
|
Scarica un allegato di una spesa ordinaria.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Parametri percorso**:
|
|
- `id` — ID della spesa
|
|
- `attId` — ID dell'allegato
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"fileName": "string",
|
|
"fileType": "string",
|
|
"data": "base64-string"
|
|
}
|
|
```
|
|
|
|
**Errori**: `404` — File non trovato
|
|
|
|
---
|
|
|
|
## Documenti
|
|
|
|
Gestione documenti del condominio con supporto per storage locale (DB) e cloud (S3, Google Drive, Dropbox, OneDrive).
|
|
|
|
### GET /api/documents
|
|
|
|
Elenco dei documenti di un condominio.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Query parameters**:
|
|
| Parametro | Tipo | Descrizione |
|
|
|-----------|------|-------------|
|
|
| condoId | string | ID del condominio |
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"condoId": "uuid",
|
|
"title": "string",
|
|
"description": "string",
|
|
"fileName": "string",
|
|
"fileType": "string",
|
|
"fileSize": 1024,
|
|
"tags": ["tag1", "tag2"],
|
|
"storageProvider": "local_db | s3 | google_drive | dropbox | onedrive",
|
|
"uploadDate": "2025-01-15T00:00:00.000Z"
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### POST /api/documents
|
|
|
|
Carica un nuovo document.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Body**:
|
|
```json
|
|
{
|
|
"condoId": "uuid",
|
|
"title": "string",
|
|
"description": "string",
|
|
"fileName": "string",
|
|
"fileType": "string",
|
|
"fileSize": 1024,
|
|
"tags": ["tag1", "tag2"],
|
|
"fileData": "base64-string o data:...;base64,...",
|
|
"storageConfig": {
|
|
"provider": "local_db | s3 | google_drive | dropbox | onedrive",
|
|
"apiKey": "string",
|
|
"apiSecret": "string",
|
|
"bucket": "string",
|
|
"region": "string"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Nota**: `storageConfig` viene solitamente passato dalle impostazioni correnti (`/api/settings`). Per `local_db` il file viene salvato nel database; per cloud viene caricato sul provider configurato.
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"id": "uuid"
|
|
}
|
|
```
|
|
|
|
**Errori**:
|
|
- `500`: Errore caricamento cloud
|
|
|
|
---
|
|
|
|
### GET /api/documents/:id/download
|
|
|
|
Scarica un document.
|
|
|
|
**Autenticazione**: Richiesta
|
|
|
|
**Parametri percorso**: `id` — ID del document
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"fileName": "string",
|
|
"fileType": "string",
|
|
"data": "base64-string o URL firmato (se isUrl: true)",
|
|
"isUrl": false
|
|
}
|
|
```
|
|
|
|
**Nota**: Per storage cloud, `data` può essere una URL firmata (es. S3) con `isUrl: true`, oppure base64 per altri provider.
|
|
|
|
**Errori**:
|
|
- `404`: Document non trovato
|
|
- `500`: Errore download da storage cloud
|
|
|
|
---
|
|
|
|
### DELETE /api/documents/:id
|
|
|
|
Elimina un document.
|
|
|
|
**Autenticazione**: Richiesta (admin/poweruser)
|
|
|
|
**Parametri percorso**: `id` — ID del document
|
|
|
|
**Risposta** `200 OK`:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Codici di errore HTTP
|
|
|
|
| Codice | Descrizione |
|
|
|--------|-------------|
|
|
| 400 | Bad Request — Parametri mancanti o non validi |
|
|
| 401 | Unauthorized — Token mancante o non valido |
|
|
| 403 | Forbidden — Accesso negato (ruolo insufficiente o risorsa non accessibile) |
|
|
| 404 | Not Found — Risorsa non trovata |
|
|
| 500 | Internal Server Error — Errore lato server |
|
|
|
|
---
|
|
|
|
## Note finali
|
|
|
|
- **Limite body**: La richiesta supporta fino a 50MB per gestire upload di file in base64 (ticket, spese, documenti).
|
|
- **Database**: L'applicazione supporta MySQL e PostgreSQL; lo schema è compatibile con entrambi.
|
|
- **ID**: Gli ID delle entità sono UUID v4.
|
|
- **Date**: Le date sono in formato ISO 8601.
|