feat(import): bring the account's own mood vocabulary along

A full backup carries the account's own mood tags, rated factors and
tag groups, and the JSON import left them out: a mood entry imported
into another account landed without every link to a tag the person had
made.

Before the entries are written, every key they or the file name is
resolved once. A catalogue tag or one the account owns is used as it
is; an own tag whose label the file states differently is kept, never
overwritten, and named in keptMoodTagKeys (keptMoodCategoryKeys for a
group). A tag the file defines and the account lacks is created in its
group, the group created the same way, within the account's caps of 50
tags and 12 groups. A key another account of the server holds comes
over under a key derived from the account and the file's key, so a
second import of the same file finds the copy instead of minting
another. The links are written through that resolution, own rated
factors included, inside the entry's transaction; anything unresolved
is still dropped and named. The import card names kept keys in all
nine locales.

The field-coverage guard now holds the backup's customMoodTags and
customMoodTagCategories to the import schema. The round trip moves a
backup to another server (the same seeded catalogue, none of the
account's rows), imports it into a fresh account and compares the
re-export, own tags, group and rated factor included; a second case
imports into another account of the same server, and a third keeps a
renamed own tag.
This commit is contained in:
Marc-André Bombeck committed 2026-10-23 22:41:36 +02:00
1 parent d1545cf554
commit 2357807706
25 files changed
+995 -67

No files matched your search

+122 -6
View File
@@ -33209,8 +33209,18 @@ components:
type: array
items:
$ref: "#/components/schemas/JsonImportMoodEntry"
description: "JSON import payload: the measurements and mood entries of the JSON export or the portable full backup.
Both sections optional; up to 10 000 rows each."
customMoodTagCategories:
maxItems: 10000
type: array
items:
$ref: "#/components/schemas/JsonImportMoodTagCategory"
customMoodTags:
maxItems: 10000
type: array
items:
$ref: "#/components/schemas/JsonImportMoodTag"
description: "JSON import payload: the measurements and mood entries of the JSON export or the portable full backup, and
the backup's own mood vocabulary the entries link to. Every section optional; up to 10 000 rows each."
JsonImportMeasurement:
type: object
properties:
@@ -33346,8 +33356,9 @@ components:
type: string
maxLength: 64
factors:
description: Rated factors by catalogue key; replaces the entry's rated links. A key the account cannot resolve is
dropped and named in `droppedFactorKeys`; a rating outside the factor's own scale skips the entry.
description: Rated factors by key (the catalogue's, or the account's own as for `structuredTags`); replaces the entry's
rated links. A key the account cannot resolve is dropped and named in `droppedFactorKeys`; a rating outside
the factor's own scale skips the entry.
maxItems: 30
type: array
items:
@@ -33364,8 +33375,8 @@ components:
- key
- rating
structuredTags:
description: Ticked tags by key (the catalogue or the account's own); replaces the entry's tag links. An unresolvable
key is dropped and named in `droppedTagKeys`.
description: Ticked tags by key (the catalogue, the account's own, or one the file's `customMoodTags` brings); replaces
the entry's tag links. An unresolvable key is dropped and named in `droppedTagKeys`.
maxItems: 30
type: array
items:
@@ -33538,6 +33549,100 @@ components:
- mood
- score
description: One mood-entry row of a JSON import file.
JsonImportMoodTagCategory:
type: object
properties:
id:
description: The file's own id, read only to find the group a tag names in `categoryId`.
type: string
maxLength: 120
key:
type: string
minLength: 1
maxLength: 80
labelKey:
type: string
minLength: 1
maxLength: 120
icon:
type: string
maxLength: 60
sortOrder:
type: integer
minimum: -9007199254740991
maximum: 9007199254740991
isActive:
type: boolean
label:
description: The group's own name.
type: string
maxLength: 200
labelEncrypted:
description: A disaster-recovery file's sealed name, used only when this server's keys open it.
type: string
maxLength: 2000
required:
- key
- labelKey
description: "A mood-tag group the account made itself. Matched by `key`: a group the account has is used as it is, a
missing one is created."
JsonImportMoodTag:
type: object
properties:
key:
type: string
minLength: 1
maxLength: 80
labelKey:
type: string
minLength: 1
maxLength: 120
categoryId:
type: string
minLength: 1
maxLength: 120
description: The group's id in the file; a group the file does not carry falls back to the seeded `custom` group.
kind:
type: string
enum:
- BINARY
- RATED
isActive:
type: boolean
icon:
type: string
maxLength: 60
sortOrder:
type: integer
minimum: -9007199254740991
maximum: 9007199254740991
label:
description: The tag's own name.
type: string
maxLength: 200
labelEncrypted:
description: A disaster-recovery file's sealed name, used only when this server's keys open it.
type: string
maxLength: 2000
scaleMin:
type: integer
minimum: 0
maximum: 10
scaleMax:
type: integer
minimum: 0
maximum: 10
inverse:
type: boolean
required:
- key
- labelKey
- categoryId
- kind
description: "A mood tag the account made itself, a rated factor included. Matched by `key`: the account's own tag of
that key is used and never overwritten (a different label is named in `keptMoodTagKeys`); a missing one is
created, within the account's custom-tag cap; a key another account of this server holds comes over under a key
derived from the account and the file's key, so a second import of the same file finds it."
MeasurementReminderCreate:
type: object
properties:
@@ -74085,6 +74190,17 @@ components:
type: array
items:
type: string
keptMoodTagKeys:
description: Keys of the account's own tags the file names differently. The account's tag is kept as it is. Present only
when non-empty.
type: array
items:
type: string
keptMoodCategoryKeys:
description: The same, for the account's own tag groups.
type: array
items:
type: string
required:
- measurements
- moodEntries