mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
Add docs/AUDIT*.md covering competitive landscape (easy-floorplan 11→430★), implementation quality, functional integrity, and P0–P3 recommendations. Refresh PRODUCT.md competitor claim and point STATUS watchlist at the pack. Co-authored-by: Matysh <Matysh@users.noreply.github.com>
6.7 KiB
6.7 KiB
Audit — implementation quality
Snapshot: 2026-08-05, product v1.58.0. Severity: critical / major / minor / nit. No critical RCE found under normal HA session auth.
1. Architecture snapshot
src/ Lit 3 Lovelace cards (houseplan + space-card)
houseplan-card.ts ~8691 LOC — orchestration god-object
logic.ts / devices.ts / … extracted pure modules (good)
styles.ts ~2223 LOC CSS-in-JS
custom_components/houseplan/ HA integration (storage, WS, HTTP, trails)
dist/ + frontend/ committed bundle (CI byte-compares)
demo/ Playwright harness + smoke_*.mjs
tests_backend/ pure + HA-harness pytest
Bundle: ≈449 KB raw / ≈128 KB gzip — acceptable for a full editor+viewer.
2. What is strong
Backend
- Single write-auth helper (
auth.may_write) with fail-closed when entry missing (audit B2 lesson documented in the module). - Voluptuous validation with cross-language option-list tests that parse
DISPLAY_MODES/TAP_ACTIONSfromlogic.ts— rare and valuable. - Config CAS via
expected_rev; plan COW + quotas; never-delete-on-inference file policy (SCOPE). - Geometry migration with durable
geom_pendingintent (HP-1490 class). - Content HTTP:
requires_auth, signed URLs for<image href>, SVG CSP sandbox. - Diagnostics / repairs / system_health present;
quality_scale.yamlmostly honest (test-coverage,strict-typing, docs todos marked todo).
Frontend (extracted brain)
- Tap security model in
resolveTapAction— locks/alarms never toggle from the plan; cover garage/door/gate guarded;runlimited to automation/script/scene. - Pure geometry / devices / sun / vacuum / resize / align-grid / signing modules
with solid
node:testcoverage (~270 tests). - Shared
config-store+ space-geometry/render forhouseplan-space-card. - Optimistic UI without rollback is documented intentional (ARCHITECTURE).
Process
- Four test layers + smoke policy (“
[manual]must have a failing auto check”). - Dual CHANGELOG (en/ru), SCOPE guard rail, CONTRIBUTING five-minute loop.
- CI: hacs + hassfest + frontend + backend + smoke job.
3. Findings (ranked)
| # | Sev | Finding | Where |
|---|---|---|---|
| 1 | major | God-object card: ~8691 LOC, ~359 methods, ~125 private fields; render() ~382 lines. Smokes-only coverage for orchestration. |
src/houseplan-card.ts |
| 2 | major | strict: true hollowed by noImplicitAny: false; ~200 any sites in the card alone; hass: any everywhere |
tsconfig.json, card / devices / logic |
| 3 | major | Write-policy split: UI _canEdit is always admin-gated; API default admin_only=False lets any authenticated user write via WS/HTTP |
houseplan-card.ts ≈L247–249, auth.py |
| 4 | major | _canEdit fails open when hass.user is missing (is_admin !== false) |
card ≈L248 |
| 5 | major | styles.ts ~2223 LOC — second maintainability sink; untested |
src/styles.ts |
| 6 | minor | layout/update has no expected_rev — multi-tablet last-writer-wins per point |
websocket_api.py |
| 7 | minor | Marker binding is bare str; ripple_color not hex-matched; decor w/h allow negatives via _NORM |
validation.py |
| 8 | minor | Card-level tap_action / resolveTapAction cardDefault is dead / ignored — confusing API surface |
types.ts, click path |
| 9 | minor | Store _async_migrate_func is a no-op; real migrations live ad-hoc in setup |
store.py, __init__.py |
| 10 | nit | quality_scale.yaml cites test_config_flow.py; file is test_ha_config_flow.py |
quality_scale.yaml |
| 11 | nit | Duplicated fireEvent / navigate in card + space-card |
both files |
| — | positive | Forbidden-domain tap model + confirm + cover guards | logic.ts |
| — | positive | Signed content + SVG sandbox | http_api.py, signing.ts |
No critical auth bypass of HA sessions found. Closest systemic issue is finding #3 (API openness vs UI) under the default options.
4. TypeScript & tooling
| Item | State |
|---|---|
tsc --noEmit in build |
Yes — correct (rollup TS plugin can warn-and-ship) |
| ESLint / Prettier | Absent |
noImplicitAny |
Off |
| Frontend unit of the Lit class | None |
| mypy strict (backend) | quality_scale todo |
5. Test map
| Layer | What it proves | Gap |
|---|---|---|
npm test (~270) |
Pure logic, i18n parity, tap security, geometry | Not the card shell |
pytest pure |
validation.py without HA | — |
| HA-harness (py≥3.13) | setup, WS races, auth, upload, geometry repair | Coverage % unmeasured |
demo/smoke_*.mjs (~100) |
Real pointer/UI against fake hass | Pixel flakes (smoke_opening_measure); no Safari/Companion matrix |
Human checklist in TESTING.md last full self-run recorded at v1.21.1 while product is at v1.58.0 — auto net grew; documented human pass did not.
6. Docs drift (quality of truth)
| Doc | Drift |
|---|---|
ARCHITECTURE.md intro |
Still mentions old src/data/house.ts / 1489×1053 era in places; square/infinite canvas sections newer |
UX-MODES.md header |
Still says “No code has been changed yet” — Phase 11 shipped |
PRODUCT.md competitor table |
Stale — easy-floorplan 11→430★ (see AUDIT-MARKET) |
STATUS.md |
Generally current as of 2026-08-04 |
Docs discipline is a project strength; these drifts are fixable and should be treated as debt, not ignored.
7. Top 10 technical debt (actionable)
- Split
houseplan-card.tsinto shell + Plan/Devices/Decor editors + dialogs. - Turn on
noImplicitAnyincrementally; type a thinHasssurface. - Align write policy: wire UI to
admin_only, or defaultadmin_only=True. - Fail closed on missing
hass.user. - Add CAS / expected_rev to
layout/update(or document single-writer assumption). - Split
styles.tsby feature surface. - Tighten MARKER_SCHEMA (
binding, colors, decor extents, space ids). - Unit-test orchestration hotspots (
_clickDevice, write-chain conflicts, modes). - Real Store migrations or document setup-time migrations as the only path.
- Remove or re-wire dead card-level
tap_action/ cardDefault.
Detailed priority and sequencing: AUDIT-RECOMMENDATIONS.md.
8. Quality-scale honesty check
| Claim | Audit view |
|---|---|
Bronze structural items done |
Accurate |
Silver unloading / owner done |
Accurate |
Gold diagnostics / repairs done |
Accurate |
test-coverage / strict-typing / docs examples todo |
Accurate — keep them todo until measured |
config-flow-test-coverage path typo |
Nit — fix filename in yaml |
Overall: self-assessment is trustworthy; do not mark coverage done without a number.