feat(prices): Settings revocation toggle for price_fetching_consent (#159) #168

Merged
maximus merged 3 commits from issue-159-settings-revoke-toggle into main 2026-04-28 01:36:15 +00:00
Owner

Summary

  • New PriceFetchConsentToggle component in src/components/settings/
  • Wired into SettingsPage.tsx Privacy section
  • Reads/writes user_preferences.price_fetching_consent for active profile
  • Confirmation dialog before revoke (DELETE the row entirely so next click on PriceFetchControl re-opens consent modal)
  • Disabled when license is not premium (tooltip via notPremium key)
  • Adds deletePreference() to userPreferenceService
  • Adds settings.privacy.title i18n key (FR + EN)
  • 10 vitest tests covering all paths

Stacked on (must merge first)

This branch contains a merge from upstream autopilot PRs:

Closes #159

Generated autonomously by /autopilot run of 2026-04-27

## Summary - New `PriceFetchConsentToggle` component in `src/components/settings/` - Wired into `SettingsPage.tsx` Privacy section - Reads/writes `user_preferences.price_fetching_consent` for active profile - Confirmation dialog before revoke (DELETE the row entirely so next click on `PriceFetchControl` re-opens consent modal) - Disabled when license is not premium (tooltip via `notPremium` key) - Adds `deletePreference()` to `userPreferenceService` - Adds `settings.privacy.title` i18n key (FR + EN) - 10 vitest tests covering all paths ## Stacked on (must merge first) This branch contains a merge from upstream autopilot PRs: - #167 (transitively #163, #164, #166) Closes #159 Generated autonomously by /autopilot run of 2026-04-27
maximus added 9 commits 2026-04-27 12:41:28 +00:00
feat(prices): i18n FR/EN keys + CHANGELOG entries
All checks were successful
PR Check / rust (push) Successful in 26m25s
PR Check / frontend (push) Successful in 2m34s
PR Check / rust (pull_request) Successful in 26m20s
PR Check / frontend (pull_request) Successful in 2m54s
ab7e0a3362
Closes #160
feat(prices): useIsPremium hook from license.edition
All checks were successful
PR Check / rust (push) Successful in 26m18s
PR Check / frontend (push) Successful in 2m37s
PR Check / rust (pull_request) Successful in 25m0s
PR Check / frontend (pull_request) Successful in 2m41s
98f68f7a1f
- Reads useLicense().state.edition === 'premium'
- Ergonomic only — server enforces independently (ADR 0011)
- 3 vitest tests (premium, base, free)
- CLAUDE.md hook count 12 -> 13

Closes #157
feat(prices): balance.service prices section with rate-limit + dedup + retries
All checks were successful
PR Check / rust (push) Successful in 27m27s
PR Check / frontend (push) Successful in 2m49s
PR Check / rust (pull_request) Successful in 28m58s
PR Check / frontend (pull_request) Successful in 2m57s
920f81fce5
- prices.fetchPrice wraps invoke('fetch_price', ...) with local rate-limit (1/2s), in-flight dedup, exp backoff on 5xx (2/4/8s, max 3 retries), no retry on 4xx/429, hard 100/session cap
- 9 vitest tests with vi.useFakeTimers() (happy, 401/403/404, 429 no-retry, 5xx retries, dedup, pacing, session cap)
- Annexe B i18n mapping wired (PriceError → balance.priceFetching.errors.* keys)
- Session cap checked before rate-limit/dedup; failures do not consume budget (MEDIUM decision)

Closes #156

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat(prices): PriceFetchControl component + consent modal + best-effort UX
All checks were successful
PR Check / rust (push) Successful in 30m45s
PR Check / frontend (push) Successful in 3m12s
PR Check / rust (pull_request) Successful in 28m50s
PR Check / frontend (pull_request) Successful in 3m15s
043e9bf622
- New component renders button + consent modal + spinner + attribution
- Best-effort warning shown once per session for stock categories
- Hidden if not premium or category kind != 'priced'
- Consent persisted per-profile in user_preferences.price_fetching_consent
- Manual unit_price input remains active in all paths
- 17 vitest tests (no RTL/jsdom — logged MEDIUM in decisions-log.md)
- Wired into SnapshotLineRow/SnapshotEditor/SnapshotEditPage
- asset_type hardcoded to 'stock' pending category schema extension (MEDIUM)

Closes #158
feat(prices): Settings revocation toggle for price_fetching_consent
All checks were successful
PR Check / rust (push) Successful in 28m16s
PR Check / frontend (push) Successful in 3m0s
PR Check / rust (pull_request) Successful in 29m45s
PR Check / frontend (pull_request) Successful in 3m6s
80c28d43ac
- Adds PriceFetchConsentToggle to SettingsPage Privacy section
- Reads/writes user_preferences.price_fetching_consent for active profile
- Confirmation dialog before revoke (DELETE the key entirely so next click re-opens consent modal)
- Disabled (with notPremium tooltip) when license is not premium
- Adds deletePreference() to userPreferenceService
- Adds settings.privacy.title i18n key (FR + EN)
- 10 vitest tests covering all paths

Closes #159
maximus added the
autopilot:pending-human
status:approved
type:feature
labels 2026-04-27 12:41:34 +00:00
maximus added 1 commit 2026-04-28 01:36:01 +00:00
chore: drop decisions-log.md (autopilot scratch, conflicts with main cleanup)
All checks were successful
PR Check / rust (push) Successful in 23m34s
PR Check / frontend (push) Successful in 2m30s
PR Check / rust (pull_request) Successful in 23m22s
PR Check / frontend (pull_request) Successful in 2m27s
a6097afcf3
maximus merged commit 877aff8d6d into main 2026-04-28 01:36:15 +00:00
maximus deleted branch issue-159-settings-revoke-toggle 2026-04-28 01:36:16 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/Simpl-Resultat#168
No description provided.