FogliPostgrestService
Costruttore
class FogliPostgrestService {
constructor(private readonly baseUrl: string)
}
Service per le operazioni CRUD sullo schema PostgreSQL foglidicalcolo. Tutte le richieste includono header schema profile:
Accept-Profile: foglidicalcolo
Content-Profile: foglidicalcolo
API
listaFogli(filters)
async listaFogli(filters: FoglioFilters): Promise<PaginatedResult<FoglioDiCalcolo>>
Lista paginata. Se filters.searchText è non vuoto, usa v_foglidicalcolo_ricerca con tsv_search=plfts(italian).{q}. Altrimenti v_foglidicalcolo_lista.
Filtri tradotti in query string:
filters.tipo | Query |
|---|---|
'mine' | permesso_effettivo=eq.proprietario |
'shared' | permesso_effettivo=neq.proprietario |
'templates' | istemplate=eq.true |
'all' | (nessun filtro aggiuntivo) |
Paginazione tramite header Range: 0-{end} + Prefer: count=exact. Risposta include Content-Range per il totale.
caricaFoglio(idfolio)
async caricaFoglio(idfolio: number): Promise<FoglioDettaglio | null>
GET su una vista di dettaglio del foglio (metadati + filtriglobali + sorgentierp + info lock). Ritorna null se il foglio non esiste (PostgREST 406 PGRST116).
creaFoglio(request)
async creaFoglio(request: CreateFoglioRequest): Promise<FoglioDettaglio>
POST /foglidicalcolo con Prefer: return=representation. Ritorna il foglio creato con idfolio valorizzato.
aggiornaDati(idfolio, request)
async aggiornaDati(idfolio: number, request: UpdateFoglioRequest): Promise<FoglioDettaglio>
PATCH /foglidicalcolo?idfolio=eq.{id} con Prefer: return=representation. Usato per:
- rinomina (
nome) - aggiornare descrizione/flag template/pubblico
- salvare
filtriglobali - aggiornare
sorgentierp
eliminaFoglio(idfolio)
async eliminaFoglio(idfolio: number): Promise<boolean>
Elimina il foglio. L'implementazione può usare RPC elimina_foglio o DELETE diretto. Cascade del DB pulisce versioni e ACL associate.
duplicaFoglio(idfolio)
async duplicaFoglio(idfolio: number): Promise<number>
RPC POST /rpc/duplica_foglio con { p_idfolio }. Ritorna idfolio del foglio duplicato.
Il duplicato:
- copia metadati,
filtriglobali,sorgentierp - copia l'ultima versione come rev. 1 del nuovo foglio
- imposta
idproprietario = current_user - imposta
nome = '{original.nome} (copia)'
listaVersioni(idfolio)
async listaVersioni(idfolio: number): Promise<FoglioVersioneSummary[]>
GET /foglidicalcoloversioni?idfolio=eq.{id}&order=numerorevisione.desc&select=idversione,idfolio,numerorevisione,idautore,datacreazione.
Non scarica lo snapshot — solo metadata. Lo snapshot è scaricato separatamente.
caricaUltimaVersione(idfolio)
async caricaUltimaVersione(idfolio: number): Promise<FoglioVersione | null>
Carica la versione corrente del foglio con snapshot. Usato all'apertura del foglio.
GET /foglidicalcoloversioni?idfolio=eq.{id}&order=numerorevisione.desc&limit=1
Accept: application/vnd.pgrst.object+json
Ritorna null se il foglio non ha ancora versioni (foglio appena creato).
salvaVersione(request)
async salvaVersione(request: SalvaVersioneRequest): Promise<FoglioVersione>
POST /foglidicalcoloversioni con Prefer: return=representation.
interface SalvaVersioneRequest {
idfolio: number
numerorevisione: number // incrementale
snapshot: FortuneSheetSnapshot
idautore?: number // se omesso, DB usa _get_current_user_id()
}
ripristinaVersione(idversione)
async ripristinaVersione(idversione: number): Promise<number>
RPC POST /rpc/ripristina_versione_foglio con { p_idversione }. Ritorna idversione della nuova versione creata.
Il DB clona lo snapshot della versione passata come nuova versione corrente (non distrugge le versioni intermedie).
listaAcl(idfolio)
async listaAcl(idfolio: number): Promise<FoglioAcl[]>
GET /foglidicalcoloacl?idfolio=eq.{id}. Ritorna le righe ACL associate al foglio (escluso il proprietario, gestito a livello foglidicalcolo.idproprietario).
aggiungiAcl(idfolio, idutente, permesso)
async aggiungiAcl(
idfolio: number,
idutente: number,
permesso: 'lettura' | 'scrittura',
): Promise<FoglioAcl>
POST /foglidicalcoloacl. Richiede che l'utente corrente sia proprietario (verificato server-side).
modificaAcl(idacl, permesso)
async modificaAcl(idacl: number, permesso: 'lettura' | 'scrittura'): Promise<FoglioAcl>
PATCH /foglidicalcoloacl?idacl=eq.{id}.
rimuoviAcl(idacl)
async rimuoviAcl(idacl: number): Promise<void>
DELETE /foglidicalcoloacl?idacl=eq.{id}.
catalogo()
async catalogo(): Promise<SorgenteCatalogo[]>
GET /foglidicalcolosorgenticatalogo?isattivo=eq.true&order=ordinamento.asc. Ritorna le sorgenti ERP attive nel catalogo.
Gestione errori PostgREST
Il service formatta gli errori PostgREST in modo human-readable:
PostgREST 406: PGRST116 — Cannot coerce the result to a single JSON object
PostgREST 403: insufficient_privilege — permission denied for table foglidicalcolo
PostgREST 400: 22P02 — invalid input syntax for type integer
Il messaggio combina status + (message ∪ details ∪ hint) del JSON di risposta. Se il body non è JSON, usa il testo grezzo.
Header schema profile
Tutte le richieste verso lo schema foglidicalcolo richiedono:
Accept-Profile: foglidicalcolo
Content-Profile: foglidicalcolo
Il service li aggiunge automaticamente. Questo permette di esporre le tabelle in uno schema separato da quello pubblico, isolando il modello dati della feature.
Helper interni
| Metodo privato | Cosa fa |
|---|---|
fetchJson<T>(endpoint, options) | Wrapper fetch + JSON parse + error handling |
formatPostgrestError(response) | Parsing/formatting JSON errori PostgREST |
parseTotaleFromContentRange(header) | Estrae il totale da items 0-19/42 |
Tipi correlati
FoglioDiCalcoloFoglioDettaglioFoglioVersioneFoglioAclSorgenteCatalogoLockService— service complementare per i lock
ErpDataService
Service fetch dati ERP da viste PostgREST. Metodo generico fetchSorgente + helper tipizzati per fatture, ordini, DDT, anagrafica, scadenze, calendario.
FortuneSheetAdapter
Adapter che incapsula @fortune-sheet/core. Lifecycle initialize/destroy, snapshot I/O, API celle, undo/redo, funzioni ERP-native, eventi.