Split the person card into overview, clothes, carry and now tabs.

Today's history is a paged HTTP log on the worker, not on the card or in people.json.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-20 04:00:38 +03:00
co-authored by Cursor
parent 69106cb48b
commit 6be4fa75ab
27 changed files with 1551 additions and 109 deletions
+46 -6
View File
@@ -255,10 +255,13 @@ is that def in the request locale. HTTP JSON is additive — no protocol version
`skills` lists only keys the person has, not every `SkillDef` in the catalog. A first-year has
no Chemistry; a related tongue from the name set may sit beside the native at a low value.
`worn` is what is on the body right now: def, colour, and the layers it occupies. `carried` is
the bag — textbooks include `subject`. `carryMass` / `carryCapacity` are kilograms; overload
does not slow walking. Home and locker stay in `people.json` and are not on this card. The
people list does not include any of these fields.
`worn` is what is on the body right now: def, colour, the layers it occupies, and `condition`
(01). `conditionLabel` is the catalog band when phase 34 has filled it; otherwise `null`
the client does not invent a caption from the number. `carried` is the bag — textbooks include
`subject`. `carryMass` / `carryCapacity` are kilograms; overload does not slow walking.
`hasLocker` is true when anything sits in a locker; `homeCount` is how many items remain at
home, not the list. The people list does not include any of these fields. Today's history is
a separate GET.
```json
{
@@ -289,7 +292,9 @@ people list does not include any of these fields.
"label": "Рубашка",
"color": "White",
"colorLabel": "Белый",
"layers": [{ "defName": "Top", "label": "Верх" }]
"layers": [{ "defName": "Top", "label": "Верх" }],
"condition": 1,
"conditionLabel": null
}
],
"carried": [
@@ -304,7 +309,42 @@ people list does not include any of these fields.
}
],
"carryMass": 1.2,
"carryCapacity": 14
"carryCapacity": 14,
"hasLocker": false,
"homeCount": 3
}
```
### `GET /api/schools/{id}/people/{personId}/log`
Today's history for one person: search, sort by time, page. Goes through the school's mailbox
because the log lives on the worker, not in `people.json` and not on a published snapshot.
Unknown school is `404` `unknown-school`; unknown person is `404` `unknown-person`. This is
not a socket feed and not a school-wide event list.
The day boundary is six in the morning — the same hour skip lands on. Crossing that hour, or
skipping an empty night, drops yesterday's rows. `?lang=ru|en` labels the captions. `q` is a
substring of the caption or type. `sort` is `time`. `dir` is `asc` or `desc` (default `desc`).
`page` starts at 1; `pageSize` defaults to 20 and is at most 100. A thousand rows do not
arrive in one response.
Row `type` values: `action-started`, `action-ended`, `apparel-replaced` (morning issue, when
phase 34 appends it), `apparel-changed` (dressing, when phase 35 appends it). `thingDef` is
the action or apparel def the caption was built from.
```json
{
"total": 2,
"page": 1,
"pageSize": 20,
"entries": [
{
"time": "2012-04-03T12:00:00Z",
"type": "action-started",
"label": "начал: Обед",
"thingDef": "EatLunch"
}
]
}
```