Assegniamo alcuni thread ai gruppi e poi i gruppi (in teoria) assegnano i thread agli individui per la gestione.
Abbiamo creato un report per mostrare il tempo (durata) di riassegnazione.
report per mostrare il tempo di riassegnazione
-- obiettivo: trovare il tempo dall'assegnazione al gruppo
-- alla chiusura del topic / non assegnazione / riassegnazione a sottogruppo o individuo
-- Per i post che non sono stati riassegnati, il tempo scorre ancora,
-- quindi usa il timestamp corrente nella differenza di date
--
-- NOTA che questo report omette le assegnazioni ancora in sospeso effettuate prima dell'inizio dell'intervallo di date
-- [parametri]
-- data :data_inizio = 2023-01-01
WITH
-- trova i post di assegnazione di gruppo nell'intervallo di date
group_assignment AS (
SELECT p.topic_id
, p.created_at as assign_date
, pcf.value as group_name
, post_number
FROM posts p
JOIN post_custom_fields pcf on pcf.post_id = p.id
WHERE p.action_code in ('assigned_group', 'reassigned_group')
AND p.created_at >= :start_date AND p.created_at < :start_date::date + INTERVAL '90 day'
ORDER BY topic_id
),
-- trova il numero di post del più basso post di "cambio assegnazione" dopo l'assegnazione al gruppo
assignment_change_post_number AS (
SELECT min(p.post_number) as post_number
, p.topic_id
, ga.post_number as initial_assignment -- passa avanti per l'uso nel join successivo
FROM posts p
JOIN group_assignment ga ON ga.topic_id = p.topic_id AND ga.post_number < p.post_number
WHERE p.action_code in ('reassigned_group', 'reassigned', 'unassigned', 'unassigned_group'
, 'assigned' -- probabilmente questo non apparirà qui, ma per sicurezza...
, 'closed.enabled','autoclosed.enabled') -- probabilmente ridondante con unassign*...
GROUP BY p.topic_id, ga.post_number
),
-- cerca la data di cambio per il numero di post
assignment_change_date AS (
SELECT p.created_at as change_date
, p.topic_id
, acpn.initial_assignment -- passa avanti per l'uso nel join successivo
FROM posts p
JOIN assignment_change_post_number acpn on p.topic_id=acpn.topic_id and p.post_number=acpn.post_number
),
-- esegui la matematica delle date tra assegnazione e cambio di assegnazione
date_math AS (
SELECT ga.group_name
-- per i post ancora assegnati al gruppo, usa il timestamp corrente come "data di riassegnazione"
, extract(epoch from (coalesce(acd.change_date, NOW()) - ga.assign_date)/86400) as days
FROM group_assignment ga
LEFT JOIN assignment_change_date acd on acd.topic_id = ga.topic_id
AND ga.post_number=acd.initial_assignment
)
SELECT group_name as "Team"
, count(*) as "Assegnazioni"
, round(avg(days)::numeric,2) as "Giorni medi alla riassegnazione"
, round(max(days)::numeric,2) as "Massimo"
, round(min(days)::numeric,5) as "Minimo"
FROM date_math
GROUP BY group_name
ORDER BY "Giorni medi alla riassegnazione" desc
Questo ha funzionato bene finché i gruppi hanno iniziato a rinominarsi (per … ragioni.)
Poiché i record di assegnazione dei thread memorizzano i nomi dei gruppi - al momento dell’assegnazione - anziché gli ID dei gruppi, ora abbiamo più righe nel report per alcuni gruppi (a seconda che l’intervallo di tempo del report includa record sia da prima che da dopo la rinomina).
Vorrei sia consolidare i multipli che rendere questo report a prova di futuro (quindi codificare solo gli insiemi di sinonimi non sarà sufficiente).
C’è un record da qualche parte di vecchi nomi di gruppo / ridenominazioni? O… qualcos’altro?
@Falco Se non ricordo male, la tabella assignment contiene lo stato corrente. Se voglio dati storici (e li voglio) devo guardare in post_custom_fields per ottenere il valore di assegnazione degli stati di assegnazione precedenti
SELECT p.topic_id
, p.created_at as assign_date
, pcf.value as group_name
, post_number
FROM posts p
JOIN post_custom_fields pcf on pcf.post_id = p.id
WHERE p.action_code in ('assigned_group', 'reassigned_group')
AND p.created_at >= :start_date AND p.created_at < :start_date::date + INTERVAL '90 day'
ORDER BY topic_id
Ohhh capisco ora, devi tracciare tutte le modifiche storiche dello stato delle assegnazioni! Questo è effettivamente un problema difficile, e un anno fa abbiamo avuto un cliente che ha commissionato un modo per affrontare questo problema correttamente, quindi ho scritto un’intera specifica per questo:
Questo è quasi un lavoro in due parti.
Innanzitutto, dobbiamo memorizzare le transizioni di stato delle assegnazioni in una tabella (nuova assegnazione, assegnazione modificata (assegnatario o cambio di stato), eliminazione assegnazione).
Quindi dobbiamo utilizzare tali informazioni per alimentare una nuova vista che sia una dashboard con grafici e tabelle.
Nuove Impostazioni
abilita report assegnazioni
tipo: booleano
predefinito: falso
Nuova UI
Questa sarà una nuova pagina, o sotto /admin/dashboard/assignments se è estensibile o sotto /admin/plugins/assign.
Lì gli utenti potranno visualizzare grafici ed esportare dati sulle assegnazioni, filtrando per periodo di tempo, utente/gruppi e stato.
Persistenza della transizione di stato delle assegnazioni
La tabella assignments memorizza già le vecchie assegnazioni, ma dovremo anche tracciare lo Stato dell’assegnazione, quindi non sono sicuro se dovremmo estenderla o semplicemente trovare una tabella più semplice dedicata agli stati storici delle assegnazioni. Sarei tentato di scegliere quest’ultima opzione in modo da non gonfiare la tabella che viene effettivamente unita ai nostri serializer “caldi”.
Stima dello sforzo
Da 2,5 a 3 settimane per il lavoro completo con UI
1 settimana solo per la nuova tabella
Sfortunatamente il cliente ha de-prioritizzato questo lavoro prima che potessimo occuparcene, ma questo risolverebbe le tue esigenze.
Report aggiornato per chiunque sia interessato. La modifica è l’aggiunta della query group_aliases (e del suo utilizzo):
-- obiettivo: trovare il tempo dall'assegnazione al gruppo
-- alla chiusura del topic / annullamento dell'assegnazione / riassegnazione a sottogruppo o individuo
-- Per i post che non sono stati riassegnati, il tempo scorre ancora,
-- quindi usa il timestamp corrente nella differenza di date
--
-- NOTA che questo report omette le assegnazioni ancora in sospeso effettuate prima dell'inizio dell'intervallo di date
-- [parametri]
-- data :start_date = 2023-01-01
WITH
-- alias di gruppo
group_aliases AS (
SELECT group_id,
-- trasforma le colonne in righe
UNNEST (array[prev_value, new_value]) AS "alias"
FROM group_histories
WHERE action = 1 AND subject='name'
UNION
SELECT id as group_id
, name
FROM groups
),
-- trova i post di assegnazione al gruppo nell'intervallo di date
group_assignment AS (
SELECT p.topic_id
, p.created_at as assign_date
, ga.group_id as group_id
, post_number
FROM posts p
JOIN post_custom_fields pcf on pcf.post_id = p.id
JOIN group_aliases ga on pcf.value = ga.alias
WHERE p.action_code in ('assigned_group', 'reassigned_group')
AND p.created_at >= :start_date AND p.created_at < :start_date::date + INTERVAL '90 day'
ORDER BY topic_id
),
-- trova il numero del post di "cambio assegnazione" più basso dopo l'assegnazione al gruppo
assignment_change_post_number AS (
SELECT min(p.post_number) as post_number
, p.topic_id
, ga.post_number as initial_assignment -- passa avanti per l'uso nel join successivo
FROM posts p
JOIN group_assignment ga ON ga.topic_id = p.topic_id AND ga.post_number < p.post_number
WHERE p.action_code in ('reassigned_group', 'reassigned', 'unassigned', 'unassigned_group'
, 'assigned' -- probabilmente questo non apparirà qui, ma per sicurezza...
, 'closed.enabled','autoclosed.enabled') -- probabilmente ridondante con unassign*...
GROUP BY p.topic_id, ga.post_number
),
-- cerca la data di modifica per il numero del post
assignment_change_date AS (
SELECT p.created_at as change_date
, p.topic_id
, acpn.initial_assignment -- passa avanti per l'uso nel join successivo
FROM posts p
JOIN assignment_change_post_number acpn on p.topic_id=acpn.topic_id and p.post_number=acpn.post_number
),
-- esegui calcoli di date tra assegnazione e modifica dell'assegnazione
date_math AS (
SELECT ga.group_id as group_id
-- per i post ancora assegnati al gruppo, usa il timestamp corrente come "data di riassegnazione"
, extract(epoch from (coalesce(acd.change_date, NOW()) - ga.assign_date)/86400) as days
FROM group_assignment ga
LEFT JOIN assignment_change_date acd on acd.topic_id = ga.topic_id
AND ga.post_number=acd.initial_assignment
)
SELECT date_math.group_id
, count(*) as "Assegnazioni"
, round(avg(days)::numeric,2) as "Giorni medi alla riassegnazione"
, round(max(days)::numeric,2) as "Massimo"
, round(min(days)::numeric,5) as "Minimo"
FROM date_math
GROUP BY group_id
ORDER BY "Giorni medi alla riassegnazione" desc