Complete Phase 1: policy kernel, REST service, and local smoke tooling
Implements QONTO-WP-0002 (policy-gated Qonto REST service with audit logging, rate limiting, and credential handling) and the ADHOC-2026-07-21 follow-up (fixture-backed local smoke mode, repo classification metadata). Marks QONTO-WP-0001/0002 and the ad-hoc workplan finished, and regenerates WORK-RECORDS.md and the ADHOC workplan's state_hub_workstream_id via fix-consistency. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
eef408bb19
commit
ca12843013
33 changed files with 2533 additions and 30 deletions
53
tests/test_snapshot_semantics.py
Normal file
53
tests/test_snapshot_semantics.py
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
from pathlib import Path
|
||||
|
||||
from qonto_assistant.audit import AuditLogger
|
||||
from qonto_assistant.contracts import ActorClaims
|
||||
from qonto_assistant.policy import PolicyEngine
|
||||
from qonto_assistant.qonto_client import FixtureQontoClient
|
||||
from qonto_assistant.rate_limits import ConcurrencyLimiter, RateLimiter
|
||||
from qonto_assistant.service import CapabilityService
|
||||
|
||||
POLICY_FILE = Path(__file__).resolve().parents[1] / "src" / "qonto_assistant" / "policy" / "qonto-v1.yaml"
|
||||
FIXTURE_DIR = Path(__file__).resolve().parent / "fixtures" / "qonto"
|
||||
|
||||
|
||||
def _claims() -> ActorClaims:
|
||||
return ActorClaims(actor_id="codex", tenant_id="binky", lane="green")
|
||||
|
||||
|
||||
def _service() -> CapabilityService:
|
||||
return CapabilityService(
|
||||
client=FixtureQontoClient(fixture_dir=FIXTURE_DIR),
|
||||
policy=PolicyEngine.from_file(
|
||||
POLICY_FILE,
|
||||
required_scope="finance.qonto.read",
|
||||
enforce_scope=False,
|
||||
),
|
||||
audit_logger=AuditLogger(sink=lambda _: None),
|
||||
rate_limiter=RateLimiter(limit=20, window_seconds=60),
|
||||
concurrency_limiter=ConcurrencyLimiter(limit=4),
|
||||
)
|
||||
|
||||
|
||||
def test_snapshot_recent_window_excludes_recurring_hint() -> None:
|
||||
payload = _service().get_snapshot(
|
||||
claims=_claims(),
|
||||
request_id="req-snapshot-31",
|
||||
window_days=31,
|
||||
page_size=50,
|
||||
)
|
||||
|
||||
assert payload["cost_run_rate_hints"]["recurring_debits"] == []
|
||||
|
||||
|
||||
def test_snapshot_90_day_window_detects_recurring_hint() -> None:
|
||||
payload = _service().get_snapshot(
|
||||
claims=_claims(),
|
||||
request_id="req-snapshot-90",
|
||||
window_days=90,
|
||||
page_size=50,
|
||||
)
|
||||
|
||||
recurring = payload["cost_run_rate_hints"]["recurring_debits"]
|
||||
assert recurring[0]["label"] == "HUB31"
|
||||
assert recurring[0]["occurrences"] == 2
|
||||
Loading…
Add table
Add a link
Reference in a new issue