mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-28 19:01:34 +00:00
docs(hygiene): свести дубли документов подсистем и снять устаревшее (#679)
Волна 2 эпика #674 — у каждого правила один дом, остальные места ссылаются. DECOR-EDITOR.md ← BACKDROP.md + LIVE-TEXT.md: один документ с нумерованными разделами (§3 подложка, §5 текст с живыми значениями), на которые теперь указывают комментарии кода вместо несуществовавших «BACKDROP §2/§3»; исправлено утверждение, что space-card не рисует декор (он рисует подложку и картинки декора, но не фигуры, мебель и текст). LIGHT.md ← матрица настроек света (перевод, тест назван явно: test/devices.test.mjs «issues 84/88»). DEVICE-PRESENTATION.md ← правила «что показывает маркер» из FILTERING.md (порядок cover → light sources → device role, шторы, медиаплееры); «в одном pull request» → «в одном коммите». CANVAS.md: §9.5 «Оптимизировать планы» → CONFIG-COMPATIBILITY.md, overlay и планарные грани Walls → WALL-THICKNESS.md §10–11, таблицы «было/стало» сняты. TESTING-DEMO.md → demo/stand/README.md: карта демо-дома и «чего на стенде нет», ручной чек-лист снят (ручной фазы в процессе нет). ISOMETRIC.md — только текущее; история Stage 2/4 — docs/adr/570-isometric-stage4-visual-handoff.md. SUN.md: удалённый контракт фона снят, правило бумаги — в текущем разделе. UX-MODES.md: декор над заливками, а не «под комнатами»; «hidden isometric»; follow-up из #3 — все выпущены. Шапки VACUUM, WARM-REMOUNT («Выровнять всё по сетке» → «Оптимизировать планы»), WALL-THICKNESS, STYLING-HOOKS, CONFIG-COMPATIBILITY (#33), PDF-EXPORT — без устаревших статусов и планов. README EN/RU: абзац про пересъёмку скриншотов → CONTRIBUTING.md, RADAR и PDF-EXPORT в списке документации, RU догнал EN (2.5D, повторное использование загруженного изображения, STAIRS). Один список канонических документов подсистем в AGENTS.md и промпте ревьюера (_process.yml). WALL-THICKNESS.md ссылается на ADR 282. Правки src/** и validation.py — только пути документов в комментариях. Issue: #679 User-Visible: no Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Backdrop image (docs/BACKDROP.md) — two shots for the owner:
|
||||
// Backdrop image (docs/DECOR-EDITOR.md §3) — two shots for the owner:
|
||||
// backdrop_frame — the transform frame mid-gesture: dashed outline, four
|
||||
// finger-sized corner handles, and the live "W × H" badge
|
||||
// stating the picture's real size through cell_cm;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Backdrop image: move, uniform scale, and the new paper rule (docs/BACKDROP.md).
|
||||
* Backdrop image: move, uniform scale, and the new paper rule (docs/DECOR-EDITOR.md §3).
|
||||
*
|
||||
* The whole contract, on the demo's f1 — which IS an image plan, so every
|
||||
* assertion here lands on exactly the case that used to behave differently:
|
||||
@@ -234,7 +234,7 @@ check('reset_button_gone_again', await q('.editor-secondary .bdreset'), 0);
|
||||
|
||||
// ---------- 5b) the SELECT tool still pans right over the picture ---------
|
||||
// The body of the picture is most of the screen; claiming it outside its own
|
||||
// tool would take away the one-finger pan (docs/BACKDROP.md §2), which is why
|
||||
// tool would take away the one-finger pan (docs/DECOR-EDITOR.md §3.2), which is why
|
||||
// moving is a tool. smoke_pan_any_zoom guards the same thing from the outside.
|
||||
await tool('select');
|
||||
await settle();
|
||||
|
||||
@@ -211,7 +211,7 @@ checkAll(res);
|
||||
// .hp-paper shapes sit under everything the plan draws. Since v1.58.0 the
|
||||
// paper is the ROOM CONTOURS and ONLY them — one shape per room, never their
|
||||
// bounding box (section 12), and never the backdrop image rect either
|
||||
// (docs/BACKDROP.md §3). The demo's f1 IS an image plan, so this section now
|
||||
// (docs/DECOR-EDITOR.md §3.3). The demo's f1 IS an image plan, so this section now
|
||||
// asserts the new rule on exactly the case that used to be the exception.
|
||||
// The scene colour is visible ONLY around the paper. The four-phase
|
||||
// environment changes only outside it and adds an alpha-aware outer outline.
|
||||
|
||||
@@ -151,8 +151,8 @@ const out = await page.evaluate(async () => {
|
||||
// the cover, which is what this section pins.) Same cause, same helper:
|
||||
// _stateClass and
|
||||
// the icon morph read d.primary, so the plan reported the state of
|
||||
// `switch.*_reverse_direction`. The rule (docs/FILTERING.md «What a marker
|
||||
// SHOWS»): the marker indicates the entity its tap ACTS ON — the cover
|
||||
// `switch.*_reverse_direction`. The rule (docs/DEVICE-PRESENTATION.md «Source precedence: what a marker
|
||||
// shows»): the marker indicates the entity its tap ACTS ON — the cover
|
||||
// exactly when the owner has explicitly chosen «Открыть/закрыть».
|
||||
const devEl = (dev) => {
|
||||
// The viewport may refit asynchronously after an editor transition. Use
|
||||
|
||||
@@ -225,7 +225,7 @@ const res = await page.evaluate(async () => {
|
||||
await popoverPicker?.updateComplete;
|
||||
// seven tools (the six drawing ones + «Мебель», docs/FURNITURE.md) plus
|
||||
// «Картинка-подложка», which f1 offers because it HAS a picture
|
||||
// (docs/BACKDROP.md §2); a hand-drawn space still shows seven
|
||||
// (docs/DECOR-EDITOR.md §3.2); a hand-drawn space still shows seven
|
||||
out.toolBtns = sr().querySelectorAll('.decorbar .btn.dtool').length === 8;
|
||||
// 2) нарисовать прямоугольник drag-ом (через прямые вызовы)
|
||||
c._decorTool = 'rect'; c._decorStyle = { color: '#ff0000', width: 3, fill: true }; await c.updateComplete;
|
||||
|
||||
@@ -89,7 +89,7 @@ const res = await page.evaluate(async () => {
|
||||
const y0 = tsp[0] ? +tsp[0].getAttribute('y') : NaN;
|
||||
const y1 = tsp[1] ? +tsp[1].getAttribute('y') : NaN;
|
||||
out.blockCentredVertically = Math.abs((y0 + y1) / 2 - ay) < 0.01 && y1 > y0;
|
||||
// длинная строка НЕ переносится сама (docs/LIVE-TEXT.md: никаких автопереносов)
|
||||
// длинная строка НЕ переносится сама (docs/DECOR-EDITOR.md §5: никаких автопереносов)
|
||||
open(multi); await c.updateComplete;
|
||||
c._decorTextDialog = { ...c._decorTextDialog, text: 'x'.repeat(120) };
|
||||
c._decorSaveText(); await c.updateComplete;
|
||||
@@ -109,7 +109,7 @@ const res = await page.evaluate(async () => {
|
||||
&& frame().querySelectorAll('.dthandle').length === 5
|
||||
&& !!frame().querySelector('.dtrot');
|
||||
|
||||
// --- визуал в 4 раза меньше, хит-зона прежняя (docs/LIVE-TEXT.md §3) ---
|
||||
// --- визуал в 4 раза меньше, хит-зона прежняя (docs/DECOR-EDITOR.md §5.3) ---
|
||||
out.fiveVisibleKnobs = frame()?.querySelectorAll('.dtknob').length === 5;
|
||||
const rOf = (sel) => { const e = frame()?.querySelector(sel); return e ? +e.getAttribute('r') : NaN; };
|
||||
const hitR = rOf('.dthandle.dtrot');
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Живой текст в декоре (docs/LIVE-TEXT.md): все связи с HA живут прямо в
|
||||
// Живой текст в декоре (docs/DECOR-EDITOR.md §5): все связи с HA живут прямо в
|
||||
// тексте как {entity} / {entity:attribute}. Один блок может смешивать обычный
|
||||
// текст и несколько переменных; выбор значения вставляет токен в позицию
|
||||
// курсора. Старые entity/attr/unit читаются, но первое сохранение мигрирует их.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Значения форматирует HOME ASSISTANT (docs/STYLING-HOOKS.md §6, docs/LIVE-TEXT.md §2.1).
|
||||
// Значения форматирует HOME ASSISTANT (docs/STYLING-HOOKS.md §6, docs/DECOR-EDITOR.md §5.2).
|
||||
// Везде, где карточка печатает состояние ОДНОЙ сущности, она зовёт
|
||||
// hass.formatEntityState (и hass.formatEntityAttributeValue для атрибута) —
|
||||
// значит, работают display_precision, локальный разделитель дробной части и
|
||||
|
||||
+51
-2
@@ -9,8 +9,7 @@ of the shipped integration.
|
||||
stand picks it up automatically from this path
|
||||
(`/opt/hp/bin/hp-update-dev.sh`, which calls the same script). The rest of the stand-only config
|
||||
(template LQI sensors, alarm helpers, the smoke automation) lives in the
|
||||
seeds on the stand host — see `docs/TESTING-DEMO.md` and the memory note
|
||||
`houseplan-demo-stand`.
|
||||
seeds on the stand host; the demo home itself is described below.
|
||||
|
||||
- `demo_guard/` — stand-only guard (2026-07-31). Visitors log in as an
|
||||
administrator (the card editor is gated on `is_admin`) and kept restarting
|
||||
@@ -56,3 +55,53 @@ refuses anything that does not have exactly one
|
||||
manifests turned the Hassfest job of PR #9004 red on 2026-08-11, five weeks into
|
||||
the review queue. `test/repo-hygiene.test.mjs` now fails if a second one
|
||||
appears, so this cannot be rediscovered by a reviewer again.
|
||||
|
||||
## The demo home
|
||||
|
||||
**https://demo.houseplan.tech** — public, login `demo` / `demo` (an
|
||||
administrator). **https://dev.houseplan.tech** — the closed stand behind basic
|
||||
auth (access with the owner), auto-deploys `dev`. The public stand **resets
|
||||
every hour** to a pristine synthetic home — break it freely, delete rooms,
|
||||
upload plans, an hour later everything is back (the countdown is printed to the
|
||||
DevTools console). Long-lived checks («the file is gone a day later», «survived
|
||||
a restart») therefore cannot live on the stand, and restarting HA from inside is
|
||||
blocked by `demo_guard`.
|
||||
|
||||
Demo home v2 is an anonymised layout of a real country house: dashboard
|
||||
«House plan» (`/house-plan/0`; views Plan / Kiosk / Schema) and three spaces —
|
||||
**Ground Floor** (Kitchen & Living, Hallway, Guest Bedroom, Guest WC, Boiler
|
||||
Room, Sauna, Under-Stairs Closet, Outdoor Storage — hand-drawn, thick hatched
|
||||
walls), **First Floor** (Kids Room A, Kids Room B, Upstairs Hall, Kids
|
||||
Bathroom, Master Bathroom, Bedroom, Study — with a plan image backdrop) and
|
||||
**Yard** (the Yard room plus a decor outline of the garage). 97 markers in
|
||||
total: ~51 on Ground Floor, 23 on First Floor, 2 in the yard. Key demo devices:
|
||||
the robot vacuum `vacuum.demo_robot` (dock in Under-Stairs Closet), leak
|
||||
sensors (toggled by the helper `input_boolean.demo_leak`), smoke sensors (fire
|
||||
by themselves every 10 minutes), the boiler and the water tank in Boiler Room
|
||||
(value markers plus live text labels), the Front Door and Terrace locks,
|
||||
curtains in Study, the garage gate in Yard, a TV with speakers, the kitchen
|
||||
hood, the air conditioner in Bedroom, the composite Smart Plug, the
|
||||
permanently unavailable Pantry Light, and the weather
|
||||
`weather.demo_weather_south` (sun in the windows and the day/night cycle).
|
||||
Everything is in English; the demo user's language is Auto, so the interface
|
||||
follows the browser. **Smart Plug 2** is deactivated in the HA registry on
|
||||
purpose — it is the ready-made example for the disabled-devices behaviour.
|
||||
|
||||
The public demo user is an administrator, so the full registry scenario can be
|
||||
checked on the stand; a limited/read-only user needs the local harness or a
|
||||
separate unprivileged user.
|
||||
|
||||
## What the stand cannot show
|
||||
|
||||
- Real Zigbee/Z-Wave hardware, real robots (Dreame/Xiaomi/Valetudo), a real
|
||||
wall tablet.
|
||||
- The HACS install/update path, YAML-mode Lovelace, reinstalling the
|
||||
integration while keeping its config.
|
||||
- Restarting HA from inside — blocked by `demo_guard` (the hourly container
|
||||
reset is the only «restart»).
|
||||
- Anything that needs the stand's file system: broken stores, `kill -9`
|
||||
between writes, unreadable folders, watching process memory.
|
||||
- Long-lived scenarios (a day-long sweep, «an hour later») — the reset comes
|
||||
first.
|
||||
- A non-admin user (`admin_only`, hidden tabs) — the stand has the single
|
||||
admin `demo`.
|
||||
|
||||
Reference in New Issue
Block a user