Commit Graph

10 Commits

Author SHA1 Message Date
Tony C
35c6f8532c Integration Capabilities framework (#355) (#359)
* Rename Connect vocabulary across the integrations framework

Three coordinated rename groups (no behavior change):

- test_connection -> validate_access on IntegrationGateway and all
  service overrides + call sites. The generalized verb covers both
  network probes (today) and access checks for future Import-capability
  integrations.
- is_initial_import -> is_initial_connect across the synchronizer
  protocol, view layer, templates, and tests. Internal sync /
  synchronize vocabulary is preserved.
- UI labels updated: IMPORT -> CONNECT (in live-discovery contexts),
  REFRESH -> UPDATE (button) / Update (inline link), Initial Import ->
  Initial Connect, Refresh Result -> Update Check Result. The
  no-items hero copy reads 'No items found.' with non-redundant
  sub-text.

Prerequisite for the broader integration-capabilities work in #355.

* Restructure HomeBox importer/ — Connect code to connector/, dormant preserved

The reachable Connect-mode synchronizer code moves from
services/homebox/importer/ to connector/:

- HomeBoxSynchronizer relocates to connector/hb_sync.py.
- New HbEntityFactory in connector/hb_entity_factory.py carries the
  two entity-create/update classmethods previously on HbImporter.

The dormant attribute-population code stays in importer/ for #358:

- HbImporter retains only its four attribute-side classmethods with a
  narrowed docstring noting their dormant status.
- The synchronizer's removed attribute-orchestration methods extract as
  HbAttributeSync in importer/hb_attribute_sync.py with a docstring
  marking them preserved for the HomeBox Importer in #358.

No behavior change. (#355)

* Phase 3 (#355): split integrations app into umbrella + connect sub-package

Relocate the Connect-capability machinery (gateways, synchronizers, sync-check,
views, view mixins, entity operations, attribute edit context, sync-result, and
related transient models) from hi/integrations/ into hi/integrations/connect/.
Umbrella-level modules (models, forms, enums, manager, urls, exceptions, etc.)
stay at hi/integrations/ as the framework root.

This re-shapes the package along capability lines ahead of the Import
capability being added by #358: the umbrella holds capability-agnostic
framework code; each capability sub-package holds the per-capability machinery.

No behavior changes. All call sites updated to the new module paths; all 3141
tests pass and lint is clean.

* Tolerate unreadable sync-check cache entries

The sync-check probe state is stored in Redis as a pickled
SyncCheckResult dataclass. Any class rename, module move, or shape
change can leave stale entries that fail to deserialize on read,
which previously propagated ModuleNotFoundError / AttributeError /
UnpicklingError straight out through the manage page.

Wrap the cache.get in get_state with a broad except: log the failure,
evict the bad key so the next request runs clean, and degrade to a
cache miss. The next probe cycle (or a Refresh) writes fresh state.

The cache is informational drift state, not load-bearing — a soft
miss is the right failure mode.

* Phase 4 (#355): add EntityDataSource enum + Entity.data_source field

EntityDataSource is the entity-wide provenance signal (INTERNAL when HI
owns the representation; EXTERNAL when an upstream system does).
Surfaces via Entity.data_source — a typed accessor over the new
data_source_str CharField, following the existing entity_type pattern.

Migration 0021 backfills integration-attached entities that disallow
internal attributes to EXTERNAL. Today this picks out only HomeBox-
Connect entities; HA / ZM / Frigate / native entities stay INTERNAL.

No UI impact yet. Phase 6 will consume data_source for cross-capability
transition prompts and Import-discard scoping.

* Phase 5 (#355): add IntegrationCapability enum + metadata declaration

IntegrationCapability declares what an integration brings to HI:
CONNECT (live mirror) or IMPORT (one-shot pull). IntegrationMetaData
now carries a `capabilities` frozenset declaring which capability set
the integration participates in; defaults to {CONNECT} since that is
the existing behavior for all four current integrations. An empty
set raises at construction time so a future integration cannot
silently register with no capability.

ALL_CAPABILITIES is provided as a frozenset convenience over all
enum members for callers that want "available everywhere" semantics.

No UI impact yet. Per-attribute capability filtering deferred until
Phase 6 introduces the consumer.

* Phase 6 (#355): make capability filtering explicit at integration list and attribute formset sites

Extend IntegrationAttributeType to accept an optional 8th tuple element
declaring which IntegrationCapabilities the attribute applies to
(defaults to ALL_CAPABILITIES, so existing declarations are unchanged).

Convert the previously-implicit "everything is Connect" assumption into
explicit capability filters at four sites that all run in Connect-mode
context today:

  * IntegrationSelectView (Enable Integrations picker modal)
  * IntegrationManageView (Config tab — enabled-integrations list and
    default-integration selector)
  * IntegrationAttributeItemEditContext (formset construction, used by
    both the Configure modal and the Config tab attribute pane)

IntegrationManager.get_integration_data_list() and
get_default_integration_data() gain an optional `capabilities`
frozenset kwarg. IntegrationAttributeItemEditContext gains a required
`capability` __init__ arg; its formset queryset is now filtered to
attribute rows whose AttributeType includes that capability. The same
class can be reused for the Import edit context in #358 by passing
IntegrationCapability.IMPORT.

Behavior unchanged today (all integrations are Connect, all attributes
default to ALL_CAPABILITIES) but the filter rules are now testable
with mixed-capability fixtures.

The Importer protocol, workflow/views/templates, and cross-capability
transition prompts originally listed in Phase 6 absorb into #358 (the
HomeBox Importer) — they are easier to design with a concrete consumer
driving them.

* Phase 7 (#355): collapse Configure + Pre-Sync + Sync into one CONNECT click

The initial-connect flow becomes a single workflow under
IntegrationEnableView: the user fills the configure form once and
clicks CONNECT, which validates access, saves attributes, enables
the integration, and runs the synchronizer in one pass — landing
directly on the sync-result modal. The previous Configure → Pre-Sync
confirm → Sync handshake is gone from this path, along with the
REVIEW CONFIG round-trip affordance.

Extracted IntegrationViewMixin.render_sync_result so the
synchronizer-invocation + cache-invalidation + sync-result rendering
is shared between IntegrationEnableView (initial-connect) and
IntegrationSyncView (update-check). Action button label flips from
the conditional CONFIGURE/UPDATE to a fixed CONNECT.

IntegrationPreSyncView and its template still serve the manage-page
UPDATE / CONNECT-when-no-entities paths unchanged; the
removal_summary policy choice (RETAIN MISSING / REMOVE MISSING) for
user-data-bearing integrations is preserved end-to-end.

Net behavior change: one fewer modal click on first-time setup.

* Phase 8 (#355): align documentation with the new Connect/Update vocabulary

Update the user-facing button-label references in the per-integration
docs (Refresh / REFRESH → Update / UPDATE; Import action → Connect)
and the developer-facing references where they were tied to user
surfaces. Internal developer vocabulary stays as "sync" — that is
the implementation-side term.

Add a Capability Model subsection to integration-guidelines.md
covering IntegrationCapability, the optional per-attribute capability
restriction, and EntityDataSource. Points at the enum modules; keeps
the explanation brief since the code is the authoritative source.

Update the per-integration doc template's vocabulary instruction so
new integrations start with the right terms.

* Address review feedback: sharpen vocabulary and add IntegrationEnableView POST tests

Four fixes from the pre-PR review pass:

- Sharpen EntityDataSource enum descriptions to disambiguate from raw
  value provenance: "HI owns the editable representation" /
  "Upstream constrains HI-side edits" (the actual semantics codified
  by migration 0021's allow_internal_attributes-based backfill).
- Replace the self-contradicting "first **Import**" / "post-import
  state" in docs/integrations/_template.md with the **Connect**
  vocabulary the same template instructs authors to use.
- Reword frigate.md troubleshooting heading "Update imports zero
  cameras" → "Update finds zero cameras" to stop mixing the UPDATE
  button label with the "imports" verb.
- Add two IntegrationEnableView.post() tests covering the Phase 7
  collapse: the happy path verifies enable + synchronizer.sync()
  fire and the sync-result modal renders; the synchronizer-less
  path verifies enable still flips but no sync-result is returned.
2026-05-24 16:58:18 -05:00
Tony C
8314eced6e Issue #280: Per-integration documentation structure and content (#291)
Establishes a two-track per-integration doc structure (user-facing
under docs/integrations/, developer-facing under docs/dev/integrations/)
with templates that enforce a consistent set of sections for each
integration. Populates the new structure for the three existing
user-configured integrations (Home Assistant, ZoneMinder, HomeBox)
and updates the integration-addition guideline to require both docs
for any new integration.

User-facing changes:

- New per-integration pages with overview, prerequisites, credential
  acquisition, configuration values, setup walkthrough, troubleshooting,
  and known limitations. ZoneMinder's existing CORS and HTTPS/SSL
  troubleshooting content migrated out of the shared Integrations.md
  into its own page.
- Restructured docs/Integrations.md as a short landing page that
  centralizes the conditional UI flow for enabling an integration
  (different button label and location depending on whether any are
  configured yet) so per-integration pages can link to it instead of
  restating it.
- Conventions documented in the user-facing template: introduce
  Home Information (HI) on first mention; use 'item' for HI's
  representation, reserve 'entity' for upstream services that use
  that term; use 'Import' (first run) and 'Refresh' (subsequent),
  not 'sync', in user-facing copy.

Developer-facing changes:

- New per-integration dev docs for ZoneMinder and HomeBox; HA dev
  doc expanded from a single section to all six required sections.
- Dev template explicitly directs writers to keep content
  high-level and refer to the code for details; existing dev docs
  follow that principle (key modules listed with one-line roles,
  no method signatures or field lists duplicated).
- Weather integration doc gets a one-paragraph preface marking it
  as an internal-source exception that does not follow the
  per-integration template structure.

Simulator documentation:

- docs/dev/testing/test-simulator.md expanded to cover the
  simulator's purpose and architecture, the URL mappings for
  pointing each HI integration at the simulator, and the
  seed_sim_profiles command (with a profile summary table and a
  pointer to the command's docstring for the full operator
  workflow).
2026-05-05 23:02:07 -05:00
Tony C
47acdaee39 Documentation and agent/command config improvements. (#225)
* Documentation and agent/comment config improvements.
2025-09-23 15:55:17 +00:00
Tony C
06bddccc6a Updated docs, claude agents and commands (#193)
* Working on improving AI agent docs.

* Update dev/docs and claude agent configs.

* Updated claude commands.
2025-09-17 17:19:51 +00:00
Tony C
f5032b72e0 Docs updates for new first-time user flows (#191)
* New Getting Started page, moved and revised content into Editing page.
2025-09-17 00:09:29 +00:00
Tony C
4ca4f6852b Initial startup profile support (#183)
* Added new home profile icon images for upcoming new start page.

* New start page design and structure. New profiles app created (stub).

* First time sidebars/modals. ProfileManager JSON docs and parsing.

* First working ProfileManager. WIP

* Added mechanisms for knowing when to show first-time help content.

* Refactor to clean up initial flows and intro help display.

* New DevTools views structure. Added stub for profile snapshot tool.

* Created initial profiel snapshot generator devtool.

* Rationalized profile generation and parsing with shared constants.

* Fixed location SVG path issues in predefined profiles.

* Improved unit tests for ProfileManager.

* Added SVG fragment install and generation for predefined profiles.

* Fixed unit tests depending on MEDIA_ROOT.

* Fixed remaining unit tests for MEDIA_ROOT isolation.

* Moved JSON initialization profiles to 'assets' dir.

* Refactored all the help content and added view mode ref dialog.
2025-09-14 16:03:15 +00:00
cassandra-ai-agent
6fc76e3da2 Add JavaScript unit tests for auto-view.js using QUnit (#160)
* Add JavaScript unit tests for auto-view.js using QUnit

- Set up QUnit testing framework with local vendoring (no CDN dependency)
- Create comprehensive test suite for auto-view.js core functions:
  * throttle() - timing behavior and edge cases
  * shouldAutoSwitch() - idle timeout decision logic
  * isPassiveEventSupported() - feature detection and caching
  * recordInteraction() and state management functions
- Add test runner HTML file that works offline
- Document testing approach and usage in README.md
- All tests focus on business logic, avoid testing framework internals
- Establishes reusable pattern for testing other JS modules

* Fix test assertion for shouldAutoSwitch 60s threshold behavior

The shouldAutoSwitch function uses >= comparison, so at exactly 60 seconds
it returns true (should auto-switch). Updated test to match actual behavior.

Also added Node.js test runner for command-line testing capability.

* Add master test runner for all JavaScript tests

- Created test-all.html that runs all JavaScript module tests in one page
- Updated README.md with improved workflow for single-URL testing
- Added instructions for adding future JavaScript modules to master runner
- Maintains individual test runners for focused debugging

This addresses the practical concern of needing to visit multiple URLs
as JavaScript test coverage grows.

* Organize JavaScript testing documentation

- Created high-level documentation at docs/dev/frontend/javascript-testing.md
- Covers testing philosophy, framework choice, and best practices
- Uses auto-view.js as reference implementation example
- Streamlined tests/README.md to focus on practical usage
- Follows project documentation organization patterns
- Maintains concise, maintainable approach with code references

* Remove redundant README.md, consolidate all JS testing docs

- Removed src/hi/static/tests/README.md (duplicate content)
- Made docs/dev/frontend/javascript-testing.md completely self-contained
- Added detailed code examples for adding new tests
- Single source of truth for JavaScript testing documentation

* Add comprehensive JavaScript unit tests for high-value modules

- svg-utils.js: 150+ test cases for SVG transform string parsing with regex edge cases
- main.js: Tests for generateUniqueId, cookie parsing/formatting with URL encoding
- video-timeline.js: Tests for VideoConnectionManager array logic and caching algorithms
- watchdog.js: Tests for timer management and restart logic simulation
- Updated test-all.html with proper module loading order (main.js first)
- Fixed svg-utils test assertions to match actual regex behavior
- Enhanced Node.js test runner with better mocking (though some modules too DOM-heavy)

All JavaScript tests now pass in browser - establishes comprehensive testing
coverage for business logic functions across multiple modules.

* Add JavaScript testing documentation links

- Added link to javascript-testing.md in frontend-guidelines.md
- Added link to javascript-testing.md in testing-guidelines.md
- Ensures JavaScript testing approach is discoverable from main guideline docs
2025-09-09 20:46:18 +00:00
Tony C
4305280c14 Location Editing Modal Redesign (#137)
* Implement template generalization for Entity/Location attribute editing

Add AttributeEditContext pattern enabling ~95% code reuse between Entity
and Location editing modals while maintaining type-safe owner-specific access.

- Add AttributeEditContext base class and owner-specific implementations
- Create generic edit_content_body.html template with extensible blocks
- Add template filters/tags for dynamic method calls and URL generation
- Update Entity/Location handlers to provide generalized context
- Replace specific templates to extend generic version
- Fix file upload and history restore template context issues

All Location tests (139/139) and Entity editing tests (17/17) passing.

* Updated documentation. Generic Attribute Editing, Testing

* Added unit tests and fixed linting errors.

* Rationalized view vs. edit mode names and directory organization.

* Fixed JS issues with previous refactor.

* More refactoring to rationalize view vs. edit mode.

* Yet more refactoring to rationalize view vs. edit mode.

* Continued refactoring to Javascript bug fixes for refactoring.

* Fixed a couple unit tests and linting errors.
2025-08-31 23:48:52 -05:00
Tony C
193c86eb65 Entity View/Edit Modal Redesign (#136)
* Document design workflow process and update CLAUDE.md

- Add comprehensive design workflow documentation in docs/dev/workflow/design-workflow.md
- Update CLAUDE.md with design work documentation workflow section
- Establishes data/design/issue-{number}/ pattern for local work
- Documents GitHub issue attachment vs comment organization
- Provides reusable process for future design-focused issues
- Maintains repository cleanliness while enabling design iteration

* Snapshpt fo semi-working new entity and attribute edit modal.

* Refactored new forms to remove duplication. Fixed some textarea bugs.

* Fixed textarea attributes to prevent data corruption.

* Fixed new attribute validation error handling.

* Moved Entity attribute formset non-file filtering closer to def.

* Styling impovements.

* Added attribute value history browsing and restoring.

* Fixed styling on new entity edit modal header area.

* Refactored the messy and confusing new entity edit modal.

* Fixed icon in new attruibute form.

* Attribute Edit style changes.

* Fixed bad claude factoring. Fixed CSRF file upload issue.

* Added scroll-to in antinode.js whic helped fix file upload UX issue.

* Fixed styling of the add new attribute card for the 'mark as secret'.

* Added modified field forms styling for new entity edit modal.

* Fixed bug in secret attribute readonly editing logic.

* Added file attribute value editing to new entity edit modal.

* Removed legacy EntityEditView and related code.

* Refactor to remove EntityEditData.

* Refactor to rename: EntityDetailsData -> EntityEditModeData

* More refactoring for name change from "details" to "edit mode"

* Removed debug log messages. Doc typo fix.

* Refactored entity views to add helper classes.

* Coded cleanup and test fixes.

* Refactored to replace use of hardcoded DOM ids, classes, selectors.

* Refactorings: better naming removed debug messages.

* Renamed "property" to "attribute".

* Fixed unit test gaps.

* Replaced hardcoded form field prefixes with common access.

* Added EntityTransitionType to replace brittle "magic" strings.

* Tweaks on display names for entity edit modal.

* Added missing __init__.py to nested test dirs. (New failures found.)

* Working on fixing unit tests: checkpoint. WIP

* Fixed units tests

* Removed mocking from soem unit tests.

* Removed partial V2 implementation mistake from entity edit work.

* Added testing doc about lessons learned.

* Added a bunch of testing-related documentation.

* Fixed test expectation for LocationAttributeUploadView invalid upload

Updated test to expect 200 status with modal form response instead of 400 error, aligning with new form error handling behavior from entity attribute redesign.
2025-08-31 13:21:22 -05:00
Tony C
39c7266e77 Refactor developer documentation for role-based use (#126)
* Refactored dev documentation extensivekly.

* Style tweaks and link removals.
2025-08-26 23:17:26 +00:00