mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-01 04:09:17 +00:00
feat: выбор граней окон для солнечных лучей (#577)
Issue: #577 User-Visible: yes
This commit is contained in:
@@ -263,8 +263,13 @@ export const LOW_HEADROOM_WARNING_BYTES = 15_000;
|
||||
* отдельный модуль; механизм обязан быть синхронным на первом касании и потому
|
||||
* не может жить в lazy editor graph. Измеренный факт 290 181 Б оставляет 719 Б
|
||||
* сверху и 1 281 Б до нижней границы полосы.
|
||||
*
|
||||
* 2026-09-15, #577: потолок перецентрирован 290 900 → 291 300 без изменения
|
||||
* общего бюджета. Выбор внутренней или внешней грани окна относится к
|
||||
* синхронной геометрии лучей в initial View. Измеренный факт 290 629 Б
|
||||
* оставляет 671 Б сверху и 1 329 Б до нижней границы полосы.
|
||||
*/
|
||||
export const INITIAL_VIEW_GZIP_CEILING = 290_900;
|
||||
export const INITIAL_VIEW_GZIP_CEILING = 291_300;
|
||||
export const INITIAL_VIEW_CEILING_BAND = 2_000;
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,21 @@
|
||||
* field whose key is still current but whose old value is compatibility-only.
|
||||
*/
|
||||
export const CONFIG_FIELD_REGISTRY = Object.freeze([
|
||||
{
|
||||
id: 'settings.sun_ray_origin',
|
||||
enforcedBy: 'sun.ts + validation.py + config-schema parity; #577',
|
||||
selector: { path: ['settings', 'sun_ray_origin'] },
|
||||
storage: 'House Plan server config',
|
||||
type: "'inner' | 'outer'",
|
||||
default: "unset (= 'inner', the pre-#577 geometry)",
|
||||
level: 'global',
|
||||
ui: 'General settings → Sun → Sun rays',
|
||||
runtime: 'selects the physical window face used as the source span',
|
||||
introduced: '#577',
|
||||
status: 'current',
|
||||
migration: "none — old configs stay on 'inner'; new settings saves materialise the enum",
|
||||
compatibility: "unknown values fail backend writes and fall back to 'inner' in the frontend",
|
||||
},
|
||||
{
|
||||
id: 'settings.summary_panel',
|
||||
enforcedBy: 'summary-panel.ts + validation.py change-aware reference validation; #437',
|
||||
|
||||
@@ -442,6 +442,13 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"config.settings.sun_ray_origin": {
|
||||
"enum": [
|
||||
"inner",
|
||||
"outer"
|
||||
],
|
||||
"required": false
|
||||
},
|
||||
"config.settings.sun_rays": {
|
||||
"required": false,
|
||||
"type": "bool"
|
||||
|
||||
@@ -5329,6 +5329,63 @@ const MUTANT_DEFINITIONS = [
|
||||
replace: "{ id: 'openings-filled-tunnel-dark', fixture: 'visual', space: 'golden-lighting', mode: 'view',\n fillMode: 'none', customFill: { c: '#66717c', a: 0.55 }, glowEnabled: false,",
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'sun-ray-origin-outer-ignored',
|
||||
guard: 'npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs '
|
||||
+ '&& node --test --test-name-pattern="#577: outer rays" test/sun.test.mjs',
|
||||
because: 'если внешний режим снова использует внутреннюю грань, геометрия остаётся '
|
||||
+ 'визуально прежней; unit-защита #577 обязана увидеть обе фасадные точки и тоннель',
|
||||
patches: [{
|
||||
file: 'src/sun.ts',
|
||||
find: " const side = origin === 'outer' ? -1 : 1;",
|
||||
replace: ' const side = 1; // mutant: ignore outer source face',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'sun-ray-origin-cache-ignored',
|
||||
guard: 'node demo/smoke_sun.mjs',
|
||||
because: 'переключение в открытом диалоге не меняет config epoch; без origin в ключе '
|
||||
+ 'пользователь до следующей записи видит закэшированную старую геометрию (#577)',
|
||||
patches: [{
|
||||
file: 'src/houseplan-card.ts',
|
||||
find: '`${space.id}|${sun.azimuth}|${sun.elevation}|${north}|${origin}|${this._cfgEpoch}`',
|
||||
replace: '`${space.id}|${sun.azimuth}|${sun.elevation}|${north}|${this._cfgEpoch}`',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'sun-ray-origin-save-forced-inner',
|
||||
guard: 'node demo/smoke_sun.mjs',
|
||||
because: 'селектор без сохранения — ложная функция; браузерный round-trip обязан '
|
||||
+ 'увидеть outer после Save и при повторном открытии общих настроек (#577)',
|
||||
patches: [{
|
||||
file: 'src/houseplan-editor-runtime.ts',
|
||||
find: ' settings.sun_ray_origin = d.sunRayOrigin;',
|
||||
replace: " settings.sun_ray_origin = 'inner'; // mutant: discard the selected face",
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'sun-ray-origin-backend-allows-any-string',
|
||||
guard: 'node scripts/backend-test-guard.mjs test_sun_settings_global tests_backend/test_validation.py',
|
||||
because: 'backend обязан отвергать неизвестный enum, иначе сохранённая опечатка расходится '
|
||||
+ 'с UI и молча читается как inner; строгий validation-тест #577 должен покраснеть',
|
||||
patches: [{
|
||||
file: 'custom_components/houseplan/validation.py',
|
||||
find: '_SUN_RAY_ORIGIN = vol.In(["inner", "outer"])',
|
||||
replace: '_SUN_RAY_ORIGIN = str # mutant: accept any string',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'sun-ray-origin-support-leaks-invalid',
|
||||
guard: 'node scripts/backend-test-guard.mjs '
|
||||
+ 'test_projection_helpers_fail_closed_on_malformed_shapes tests_backend/test_support_package.py',
|
||||
because: 'support package переносит только безопасный известный enum; неизвестная строка '
|
||||
+ 'не должна попадать в диагностический архив (#577)',
|
||||
patches: [{
|
||||
file: 'custom_components/houseplan/support_package.py',
|
||||
find: ' if sun_ray_origin in ("inner", "outer"):',
|
||||
replace: ' if isinstance(sun_ray_origin, str): # mutant: leak unknown strings',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'sun-north-subtraction-restored',
|
||||
guard: 'npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs '
|
||||
|
||||
Reference in New Issue
Block a user