Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
087fc76
drafts
JonasScholl Jun 18, 2026
602879e
model draft
JonasScholl Jun 25, 2026
d59c663
research & concept refinement progress
JonasScholl Jul 8, 2026
e0ee9b8
inspect app implementation
JonasScholl Jul 9, 2026
5e51d3c
e2e test improvements
JonasScholl Jul 9, 2026
664f979
add tags e2e test
JonasScholl Jul 9, 2026
1deafb5
improve agent instructions
JonasScholl Jul 9, 2026
65b16e1
always use pydantic for consistency, remove dataclass usage
JonasScholl Jul 9, 2026
3763af9
improve test setup
JonasScholl Jul 9, 2026
7428e87
e2e test rework
JonasScholl Jul 9, 2026
6f772e5
update poetry lock
JonasScholl Jul 9, 2026
935728f
test improvements
JonasScholl Jul 9, 2026
9337be0
minor docs adjustments
JonasScholl Jul 9, 2026
d8c351f
inspect snapshot update improvements
JonasScholl Jul 9, 2026
b81386f
code style improvements
JonasScholl Jul 9, 2026
309cd25
apply feedback
JonasScholl Jul 16, 2026
f7abead
Potential fix for pull request finding 'Module is imported with 'impo…
JonasScholl Jul 16, 2026
1ad728d
improve port domain dto
JonasScholl Jul 17, 2026
6288f77
project all inspect data and configurations from VideoIPath UI
JonasScholl Jul 22, 2026
2d7a093
update model improvements
JonasScholl Jul 23, 2026
9d9110b
add examples and improve the documentation
JonasScholl Jul 23, 2026
b130d60
refactor, improve and add new e2e tests
JonasScholl Jul 23, 2026
f292cae
resolve findings
JonasScholl Jul 23, 2026
f60b076
refactor agent rules setup
JonasScholl Jul 23, 2026
ded36d4
add update method to transaction instance
JonasScholl Jul 23, 2026
076a2c2
add new schema version 2026.2.0
PaulWinterstein Jul 23, 2026
dda3e4d
Merge pull request #118 from SWR-MoIP/add-support-for-pre-version-202…
JonasScholl Jul 23, 2026
b3c1a23
skip e2e tests for apps that are not supported by the connected video…
JonasScholl Jul 23, 2026
7ecc86a
inspect app beta warning
JonasScholl Jul 23, 2026
218483d
use literals for fixed string value sets
JonasScholl Jul 23, 2026
247f9d1
descriptive inspect status enums
JonasScholl Jul 23, 2026
aad72c9
repr and str for domain classes
JonasScholl Jul 23, 2026
6156b6e
cleanup
JonasScholl Jul 23, 2026
be6fb27
documentation refinement and cleanup
JonasScholl Jul 23, 2026
4f02e7f
clarify legacy and new tag handling
PaulWinterstein Jul 24, 2026
5b1eebb
Merge pull request #119 from SWR-MoIP/inspect-integration-review
PaulWinterstein Jul 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions .agents/rules/agent-rules-layout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
description: Agent rules directory layout and symlink conventions
alwaysApply: false
globs: .agents/rules/**,.claude/rules/**,.cursor/rules/**
paths:
- ".agents/rules/**/*.md"
- ".claude/rules/**/*.md"
- ".cursor/rules/**/*.mdc"
---

# Agent rules layout

This repo stores path-scoped agent rules in a tool-agnostic location and bridges them into Claude Code and Cursor via symlinks.

## Canonical source

- **Edit rules here:** `.agents/rules/*.md`
- **Do not** put rule content directly in `.claude/rules/` or `.cursor/rules/` — those files are symlinks.

## Tool bridges

Claude Code reads `.claude/rules/*.md`. Cursor requires `.cursor/rules/*.mdc`. Each bridge entry is a symlink to the matching canonical `.md`:

```text
.agents/rules/my-rule.md ← canonical (commit this)
.claude/rules/my-rule.md ← symlink → ../../.agents/rules/my-rule.md
.cursor/rules/my-rule.mdc ← symlink → ../../.agents/rules/my-rule.md
```

## Dual frontmatter

Every rule file needs frontmatter for both tools:

```yaml
---
description: Short summary for Cursor rule picker
alwaysApply: false
globs: path/to/match/**
paths:
- "path/to/match/**"
---
```

- **Cursor** uses `globs`, `alwaysApply`, and `description`.
- **Claude Code** uses `paths`; omit `paths` for always-on rules.
- Each tool ignores the other's keys.

## Adding a rule

1. Create `.agents/rules/<name>.md` with dual frontmatter and content.
2. Add the Claude and Cursor symlinks:

```bash
ln -s ../../.agents/rules/<name>.md .claude/rules/<name>.md
ln -s ../../.agents/rules/<name>.md .cursor/rules/<name>.mdc
```

3. List the new rule in the **Agent rules** section of `AGENTS.md`.

## Removing a rule

1. Delete `.agents/rules/<name>.md`.
2. Delete `.claude/rules/<name>.md` and `.cursor/rules/<name>.mdc` (the symlinks, not separate copies).
3. Remove its entry from `AGENTS.md`.

## Do not

- Symlink an entire bridge directory to another (extension mismatch: `.mdc` vs `.md`).
- Duplicate rule content across directories.
- Commit real files under `.claude/rules/` or `.cursor/rules/` — only symlinks belong there.
46 changes: 46 additions & 0 deletions .agents/rules/python-quality.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
description: Python code quality conventions for src/ and tests/
alwaysApply: false
globs: src/**/*.py,tests/**/*.py
paths:
- "src/**/*.py"
- "tests/**/*.py"
---

# Python code quality

## Structured data

- Use **Pydantic `BaseModel`** for all structured data — API responses, settings, internal records, result types, and domain wrappers. Do not use `@dataclass`.
- Prefer typed models over plain `dict` for structured data.
- Reuse project base models where they exist (e.g. `InspectApiBaseModel` for API shapes; inspect-internal bases for in-memory models).

## Exceptions

- Raise **specific, descriptive exceptions** rather than bare `Exception`.
- Follow domain error hierarchies: a base exception class plus typed subclasses with context attributes (see `src/videoipath_automation_tool/apps/inspect/errors.py`).

## Context managers

- Use `with` for files, locks, test spies, and connector wrappers.

## Quality gates

Before finishing Python changes, run:

```bash
poetry run ruff check --fix src/ tests/
poetry run ruff format src/ tests/
```

Pre-commit hooks mirror these commands (see `.pre-commit-config.yaml`).

## Generated and sensitive code

- Do **not** hand-edit `src/videoipath_automation_tool/apps/inventory/model/drivers.py` — regenerate with `set-videoipath-version <version>`.
- All committed data must follow the anonymization rules in `AGENTS.md`.

## Change scope

- Keep diffs minimal and focused.
- Match surrounding patterns: mixins, module docstrings, `TYPE_CHECKING` imports, and existing naming in the file you edit.
55 changes: 55 additions & 0 deletions .agents/rules/python-style.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
description: Python coding style for src/ and tests/
alwaysApply: false
globs: src/**/*.py,tests/**/*.py
paths:
- "src/**/*.py"
- "tests/**/*.py"
---

# Python coding style

## Type hints

- Annotate all function parameters and return types.
- Use `from __future__ import annotations` in new modules.
- Use `TYPE_CHECKING` blocks for imports needed only for type hints.

## Formatting and naming

- Follow PEP 8 with **snake_case** for functions, variables, and modules.
- Max line length is **120** characters (ruff formatter default in this project — not Black's 88).
- Format with **ruff**, not Black:

```bash
poetry run ruff format src/ tests/
```

## Strings and paths

- Use **f-strings** for string formatting; avoid `%` formatting and `.format()`.
- Use **`pathlib.Path`** over `os.path` for filesystem operations.

## Comprehensions and readability

- Prefer list/dict/set comprehensions over explicit loops when the result stays readable.
- Do not sacrifice clarity for brevity.

## Layout and whitespace

- Group **logically related lines** together (e.g. setup, core logic, cleanup).
- Separate groups with a **single blank line**; use an extra blank line between larger sections when it aids scanning.
- Do not sprinkle blank lines randomly, and do not leave long unbroken blocks when a visual break would help.
- Within a function, keep the main path easy to follow: inputs and validation first, then the core work, then return/cleanup.

## Public before private

- Place **public** API first so readers see the most relevant surface when scrolling: public classes, methods, functions, and module-level constants.
- Place **private** members after public ones: names prefixed with `_` (attributes, methods, functions, nested helpers) and internal implementation details.
- In classes: public methods first, then `_`-prefixed helpers and internal state accessors.
- In modules: public exports and user-facing functions first; private helpers and module-internal constants at the bottom.
- A short section comment (e.g. `# --- Internal ---`) is fine when a class or module has a large private block.

## Resources

- Use **context managers** (`with`) for files, locks, and other resources that need cleanup.
81 changes: 81 additions & 0 deletions .agents/rules/python-testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
description: Python testing conventions for src/ and tests/
alwaysApply: false
globs: src/**/*.py,tests/**/*.py
paths:
- "src/**/*.py"
- "tests/**/*.py"
---

# Python testing

## Framework and commands

- Use **pytest** for all tests.
- Prefer the dedicated entry points over bare `pytest`:

```bash
poetry run test-unit # offline/unit suite (CI default)
poetry run test-e2e # live-server e2e (loads .env)
poetry run test # unit then e2e sequentially

# Single file or test (extra args pass through to test-unit / test-e2e)
poetry run test-unit tests/validators/test_device_id.py
poetry run test-e2e tests/e2e/inspect/test_e2e_inspect.py::test_name
```

- `poetry run pytest` also runs unit tests only (e2e excluded via `addopts` in `pyproject.toml`).

### VS Code

Use the launch configs in `.vscode/launch.json`:

- **Unit Tests** / **Unit Tests (current file)** — offline suite
- **E2E Tests** / **E2E Tests (current file)** — live-server suite

Or run **Tests** from `.vscode/tasks.json` (`poetry run test`).

## Unit vs e2e separation

| Layer | Unit | E2E |
|-------|------|-----|
| Location | `tests/` except `tests/e2e/` | `tests/e2e/` only |
| Marker | unmarked | `@pytest.mark.e2e` |
| Env | `tests/conftest.py` (dummy values) | `.env` (copy from `.env.template`) |
| Run command | `test-unit` / `pytest` | `test-e2e` |
| CI | yes | no |

Default `addopts` run coverage on `src/` and exclude e2e (`-m "not e2e"`).

## Assertions

- Use `pytest.raises(SpecificError)` with the exact exception type.
- Do not catch or assert against bare `Exception` when a domain error exists.

## Unit and offline tests

- Mock external I/O with fake connectors and lightweight stand-ins (see `tests/inspect/test_actions.py`).
- Dummy `VIPAT_*` env vars are set in `tests/conftest.py` (autouse fixture; skipped for e2e).
- Load JSON fixtures from `tests/<app>/fixtures/<version>/` using `pathlib.Path`.
- Put shared fixtures in `conftest.py` at the appropriate directory level.
- Use session-scoped fixtures only when setup is expensive and reuse is intentional.

## E2E tests

- Live-server tests live under `tests/e2e/` only.
- Mark with `@pytest.mark.e2e`; they are excluded from the default suite.
- E2e entry points (`poetry run test-e2e`, `poetry run test`, VS Code **E2E Tests**) load `.env` and enable the suite automatically. E2e runs use `--no-cov`.
- Copy `.env.template` to `.env` (gitignored), set connection vars. The e2e conftest loads `.env` automatically when present.
- Run with `poetry run test-e2e` (no extra env vars on the command line).
- Namespace all writes with the `E2E-` label prefix and `vipat-e2e` tag.
- Do not add e2e tests to the default CI/offline run.

## Test data

- All fixture and test data must follow anonymization rules in `AGENTS.md`.
- Preserve structure and relationships; replace real hostnames, IPs, and customer identifiers with generic placeholders.

## Coverage

- Default runs report coverage on `src/`.
- Do not disable coverage flags without a clear reason.
1 change: 1 addition & 0 deletions .claude/rules/agent-rules-layout.md
1 change: 1 addition & 0 deletions .claude/rules/python-quality.md
1 change: 1 addition & 0 deletions .claude/rules/python-style.md
1 change: 1 addition & 0 deletions .claude/rules/python-testing.md
1 change: 1 addition & 0 deletions .cursor/rules/agent-rules-layout.mdc
1 change: 1 addition & 0 deletions .cursor/rules/python-quality.mdc
1 change: 1 addition & 0 deletions .cursor/rules/python-style.mdc
1 change: 1 addition & 0 deletions .cursor/rules/python-testing.mdc
11 changes: 0 additions & 11 deletions .env.example

This file was deleted.

13 changes: 13 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copy to .env (gitignored) for local development and live-server e2e tests.

VIPAT_ENVIRONMENT=DEV
VIPAT_VIDEOIPATH_SERVER_ADDRESS=vip-server.example
VIPAT_VIDEOIPATH_USERNAME=test-user
VIPAT_VIDEOIPATH_PASSWORD=test-password
VIPAT_USE_HTTPS=true
VIPAT_VERIFY_SSL_CERT=false
VIPAT_LOG_LEVEL=INFO
VIPAT_ADVANCED_DRIVER_SCHEMA_CHECK=true
VIPAT_TIMEOUT_HTTP_GET=10
VIPAT_TIMEOUT_HTTP_PATCH=10
VIPAT_TIMEOUT_HTTP_POST=10
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches:
- main
tags:
- 'v*' # Trigger on version tags like v1.2.3
- "v*" # Trigger on version tags like v1.2.3
pull_request_target:
branches:
- main
Expand All @@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12", "3.13"]
python-version: ["3.11", "3.12", "3.13", "3.14"]
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand All @@ -37,7 +37,7 @@ jobs:
run: poetry install --with dev,test

- name: Run tests
run: poetry run pytest
run: poetry run test-unit

# 2️⃣ Release Job (Uses Prebuilt Package)
release:
Expand All @@ -52,7 +52,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.13"
python-version: "3.14"

- name: Install Poetry
run: pip install poetry
Expand Down
Loading
Loading