feat: nature des échanges — catégorisation et détail des commentaires de transactions
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Nouveau commentParser.ts : ~80 règles regex multilingues, 11 catégories - SubsquidAdapter : fetch du champ comment.remark depuis SubSquid - Transaction et TransactionArc : champs comment et category - StatsPanel : section Nature des échanges avec barres cliquables (détail inline) - FlowMap : tooltip au survol des arcs avec répartition catégories + commentaires - InfoPanel mis à jour Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
|
||||
import { fetchTransfers, buildIdentityKeyMap, fetchCurrentUD, ss58ToDuniterKey, fetchActiveMemberKeys } from './adapters/SubsquidAdapter';
|
||||
import { resolveGeoByKeys, resolveGeoByKeysBatched, cleanCityName } from './adapters/CesiumAdapter';
|
||||
import { parseComment } from '../data/commentParser';
|
||||
import {
|
||||
getTransactionsForPeriod,
|
||||
computeStats,
|
||||
@@ -112,6 +113,8 @@ async function fetchLiveTransactions(periodDays: number): Promise<{
|
||||
countryCode: fromGeo.countryCode,
|
||||
fromKey: t.fromId,
|
||||
toKey: t.toId,
|
||||
comment: t.comment,
|
||||
category: parseComment(t.comment),
|
||||
});
|
||||
|
||||
// Arc : les deux extrémités géolocalisées + villes différentes
|
||||
@@ -133,6 +136,8 @@ async function fetchLiveTransactions(periodDays: number): Promise<{
|
||||
toLat: toGeo.lat, toLng: toGeo.lng,
|
||||
toCity, toCountry: toGeo.countryCode,
|
||||
toKey: t.toId,
|
||||
comment: t.comment,
|
||||
category: parseComment(t.comment),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -192,6 +197,8 @@ export interface PeriodStats {
|
||||
transactionCount: number; // total blockchain (y compris non-géolocalisés)
|
||||
geoCount: number; // transactions visibles sur la carte
|
||||
topCities: { name: string; volume: number; count: number; countryCode: string }[];
|
||||
categoryBreakdown: { category: import('../data/commentParser').TxCategory; count: number; volume: number }[];
|
||||
commentedCount: number; // nb de transactions avec un commentaire
|
||||
}
|
||||
|
||||
export interface DataResult {
|
||||
@@ -233,6 +240,8 @@ export async function fetchData(periodDays: number): Promise<DataResult> {
|
||||
transactionCount: totalCount,
|
||||
geoCount: geolocated.length,
|
||||
topCities: base.topCities,
|
||||
categoryBreakdown: base.categoryBreakdown,
|
||||
commentedCount: base.commentedCount,
|
||||
},
|
||||
source: 'live',
|
||||
currentUD,
|
||||
|
||||
@@ -29,6 +29,7 @@ const SubsquidTransferNodeSchema = z.object({
|
||||
from: z.object({
|
||||
linkedIdentity: z.object({ name: z.string() }).nullable(),
|
||||
}).nullable(),
|
||||
comment: z.object({ remark: z.string() }).nullable().optional(),
|
||||
});
|
||||
|
||||
const SubsquidResponseSchema = z.object({
|
||||
@@ -52,6 +53,7 @@ export interface RawTransfer {
|
||||
fromId: string;
|
||||
toId: string;
|
||||
fromName: string; // nom d'identité Ğ1 de l'émetteur (peut être vide)
|
||||
comment: string | null;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -77,6 +79,9 @@ const TRANSFERS_QUERY = `
|
||||
name
|
||||
}
|
||||
}
|
||||
comment {
|
||||
remark
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,6 +258,7 @@ export async function fetchTransfers(
|
||||
fromId: node.fromId ?? '',
|
||||
toId: node.toId ?? '',
|
||||
fromName: node.from?.linkedIdentity?.name ?? '',
|
||||
comment: node.comment?.remark ?? null,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user