9.2 KiB
Storage Schema
Ce document décrit les données persistées dans IndexedDB pour les toolboxes. Il doit être mis à jour à chaque ajout ou modification d'outil.
IndexedDB
Base : sokkog
Object stores :
kv: données globales simples.modules: données des outils, séparées par toolbox et par module.
Clés principales dans kv :
{
"toolboxes": [],
"links": {},
"setting:toolboxOrder": [],
"setting:storageBudgetBytes": 536870912,
"setting:toastPosition": "right"
}
Entrée type dans modules :
{
"key": "tbx1:mod1",
"data": {}
}
Toolbox
Les toolboxes sont stockées dans kv/toolboxes.
{
"id": "tbx1",
"name": "Monster Hunter Wilds",
"gameId": "mhwilds",
"icon": "/static/img/toolbox-icons/toolbox.png",
"modules": [
{
"id": "mod1",
"type": "checklist",
"title": "Armures"
}
],
"layout": "two",
"updatedAt": "2026-07-25T12:00:00.000Z"
}
Notes :
gameIdest vide pour une toolbox libre.iconest utilisé uniquement pour les toolboxes libres.layoutvaut généralementoneoutwo.- Les données lourdes des outils ne sont pas stockées dans la toolbox, mais dans
modules.
Liens Jeu / Toolbox
Les associations entre pages jeux et toolboxes sont stockées dans kv/links.
{
"mhwilds": "tbx1",
"diablo4": "tbx2"
}
Outil Bloc Notes
Type : notepad
{
"text": "Notes rapides..."
}
Stockage compact :
- si
textest vide, l'entrée de module peut être supprimée.
Outil Checklist
Type : checklist
Format simple, sans catégorie :
{
"items": [
{
"id": "item1",
"label": "Potion",
"qtyTarget": 10,
"qtyCurrent": 3
}
]
}
Format avec catégories :
{
"hideCompletedSections": true,
"hideCompletedSectionsFully": false,
"sections": [
{
"id": "section1",
"title": "Rey Dau alpha",
"hideWhenComplete": false,
"collapsed": false,
"items": [
{
"id": "item1",
"label": "Casque",
"qtyTarget": 1,
"qtyCurrent": 0
}
]
}
]
}
Stockage compact :
qtyTargetest omis si la valeur vaut1.qtyCurrentest omis si la valeur vaut0.hideCompletedSectionsest omis sifalse.hideCompletedSectionsFullyest omis sifalse.titleest omis si vide.hideWhenCompleteest omis si non défini.collapsedest omis sifalse.
Outil Images
Type : images
{
"images": [
{
"id": "image1",
"label": "Map zone nord",
"dataUrl": "data:image/webp;base64,..."
}
]
}
Stockage compact :
labelest facultatif.labelest omis si vide.createdAtn'est pas stocké.- Le nom de fichier original n'est pas stocké.
Outil Annotation d'images
Type : imageAnnotation
{
"image": "data:image/webp;base64,...",
"markers": [
{
"id": "marker1",
"x": 42.5,
"y": 68,
"label": "Entrée"
}
]
}
Stockage compact :
- un seul visuel par outil.
xetysont des pourcentages entre0et100.labelest facultatif.labelest omis si vide.
Outil Timer
Type : timer
Structure initiale :
{
"activeTab": "stopwatch",
"scrollResults": true,
"sortResults": true,
"stopwatch": {
"elapsedMs": 12000,
"startedAt": 1760000000000,
"laps": [
{
"id": "timer1",
"label": "Phase 1",
"elapsedMs": 9000
}
]
},
"countdowns": [
{
"id": "timer2",
"label": "Boss",
"type": "daily_time",
"alertMode": "visible",
"time": "12:03:00",
"targetAt": 1760000000000
},
{
"id": "timer3",
"label": "Event",
"type": "time_pattern",
"pattern": "X:45:00"
},
{
"id": "timer4",
"label": "Event",
"type": "interval",
"intervalMs": 1800000,
"anchorAt": 1760000000000
}
]
}
Types de compte à rebours :
duration: durée ponctuelle, avecdurationMsettargetAt.daily_time: occurrence ponctuelle à une heure précise, avectimeau formatHH:MM:SSettargetAt.time_pattern: prochaine occurrence automatique correspondant à un patternHH:MM:SS, où chaque segment peut valoirX.interval: prochaine occurrence automatique toutes les X millisecondes, avecintervalMsetanchorAt.
Pour time_pattern, un segment X situé après un segment plus large fixé cible le premier instant de l'occurrence. Exemple : X:24:X cible hh:24:00 et se répète toutes les heures.
Stockage compact :
activeTabest omis si la valeur vautstopwatch.scrollResultsest omis sifalse.sortResultsest omis sifalse.stopwatchest omis tant que le chrono est à zéro et qu'aucune étape n'est enregistrée.elapsedMsest omis si0.startedAtest omis si le chrono n'est pas lancé.lapsest omis tant qu'aucune étape n'est enregistrée.countdownsest omis tant qu'aucun compte à rebours n'est configuré.countdowns[].alertModevautoff,visibleousite, et est omis sioff.- L'activation d'une alerte est bloquée dans l'interface si la fréquence configurée est inférieure à 5 minutes pour les comptes à rebours récurrents (
time_patternetinterval). Le blocage ne dépend pas du temps restant avant la prochaine échéance.
Outil Task Planner
Type : taskPlanner
{
"sortMode": "manual",
"weeklyResetDay": 1,
"resetTime": "00:00",
"lastResetAt": 1760000000000,
"tasks": [
{
"id": "task1",
"title": "Quête 1",
"description": "Préparer la route.",
"type": "daily",
"checked": true,
"checkedAt": 1760000000000
},
{
"id": "task2",
"title": "Quête 2",
"type": "weekly",
"weeklyResetDay": 3
}
],
"relations": [
{
"id": "relation1",
"fromTaskId": "task1",
"toTaskId": "task2"
},
{
"id": "relation2",
"fromTaskId": "task2",
"toTaskId": "task1",
"dependency": true
}
]
}
Notes :
typevautunique,dailyouweekly.sortModevautmanualoutype. Le tri par type affiche quotidiennes, hebdo, puis uniques.weeklyResetDaysuit les jours JavaScript :0dimanche,1lundi, ...,6samedi.resetTimeest global à l'outil et vautHH:MM.weeklyResetDaysur une tâche hebdo surcharge le jour global.relationsstocke les parents directionnels.fromTaskIddésigne la tâche enfant,toTaskIdson parent.- une tâche ne conserve qu'un seul parent.
dependency: truemarque aussi ce parent comme pré requis.- Les pré requis sont non bloquants : ils affichent un avertissement si le parent requis n'est pas effectué.
Stockage compact :
sortModeest omis si la valeur vautmanual.weeklyResetDayglobal est omis si la valeur vaut1.resetTimeest omis si la valeur vaut00:00.lastResetAtest omis si la valeur vaut0.descriptionest omis si vide.checkedetcheckedAtsont omis si la tâche n'est pas effectuée.weeklyResetDayunitaire est omis si non défini.relationsest omis si vide.relations[].dependencyest omis sifalse.
Outil Liens
Type : links
{
"links": [
{
"id": "link1",
"title": "Build rogue",
"url": "https://example.com/build"
}
]
}
Stockage compact :
titleest facultatif.titleest omis si vide.urlest obligatoire.
Outil Compteurs
Type : counters
{
"counters": [
{
"id": "counter1",
"label": "Victoire",
"value": 12
},
{
"id": "counter2",
"label": "Défaite",
"value": -2
}
]
}
Notes :
valueest numérique.- Les valeurs négatives sont acceptées.
- Les compteurs sans libellé ne sont pas conservés.
Outil Calculateur
Type : calculator
{
"scrollResults": true,
"entries": [
{
"id": "calc1",
"label": "Lingots de fer",
"value": 100
},
{
"id": "calc2",
"parentId": "calc1",
"label": "Minerais de fer",
"value": 500
}
]
}
Stockage compact :
scrollResultsest omis sifalse.parentIdest omis si vide.labelpeut être vide.valueest numérique.- Si un
parentIdne pointe vers aucune entrée existante, il est réinitialisé à vide.
Export
L'export d'une toolbox remappe les identifiants pour produire des IDs courts et indépendants.
Exemple :
{
"toolbox": {
"id": "t1",
"name": "MHW",
"modules": [
{
"id": "m1",
"type": "checklist",
"title": "Armures"
}
],
"updatedAt": "2026-07-25T12:00:00.000Z"
},
"modules": {
"m1": {
"items": [
{
"id": "i1",
"label": "Casque"
}
]
}
}
}
A maintenir à chaque update
Quand un outil change de structure :
- mettre à jour ce document ;
- mettre à jour les normalisations dans
website/src/features/toolboxes/storage/toolboxStorage.js; - mettre à jour les textes dans
website/public/data/site.jsonsi nécessaire ; - mettre à jour la validation dans
tests/helpers/data-validation.mjssi nécessaire ; - vérifier import/export ;
- lancer
npm run check.