Skip to content

Bring V2 Operations admin settings to parity with the classic page - #1675

Merged
Paul Lizer (paullizer) merged 6 commits into
paullizer-react-v2-uifrom
paullizer-operations-settings-parity
Oct 7, 2026
Merged

Paul Lizer (paullizer) merged 6 commits into
paullizer-react-v2-uifrom
paullizer-operations-settings-parity

Conversation

@paullizer

@paullizer Paul Lizer (paullizer) commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The V2 Operations group (Control Center and Logging & Health) was mostly undescribed in the V2 settings schema. Most of it rendered as guessed enable_* switches such as "Dai debug", and three sections did not render at all, so admins had to go back to the classic page for the refresh schedule, health checks, Swagger, logging timers and log cleanup. This PR brings the group to full parity using the V2 design language, and shows what a save will do before it is made.

  • Every Operations section is described in admin_settings_fields.py, so nothing falls back to the key-name scan. Automatic Data Refresh, Health Check and API Documentation appear in V2 for the first time, and enable_dai_debug gets a real control with a link to the DAI Metrics card it affects.
  • One set of rules for schedules and timers. Two pure modules, functions_logging_timers.py and functions_control_center_schedule.py, are now used by the classic save, the V2 normalizer and the background checks. Logging turnoff times are stored in UTC, and legacy naive values are still read as server-local time, so timers set before the upgrade end when they were meant to.
  • Readouts instead of guesswork:
    • The next refresh is shown in the schedule's timezone and the reader's, with Use my timezone.
    • Logging turnoff times are shown in the reader's timezone.
    • A Control Center access table follows unsaved role switches.
    • App Insights and Swagger say when a restart is still pending, and App Insights reports whether its connection string is set.
    • Endpoint addresses are copyable, with access level and live state.
    • Stored file processing logs can be cleaned up after a confirmation that states exactly what will be deleted.
  • In-app guides. The classic role setup, health check and Swagger modals are ported as guides opened from the section headers. They correct three things the classic modals get wrong: the health check response shape, Swagger being open to any signed-in user rather than admins only, and ControlCenterAdmin not also needing the Admin role.

Worth a careful look

  • V2 now refuses an unreadable refresh time or timezone with a field error. The classic page still silently falls back to 02:00 / America/New_York.
  • GET /api/v2/admin/settings (admin-only) adds section_guides, three boolean runtime flags (appinsights_connection_configured, appinsights_global_logging_active, swagger_routes_registered) and an appinsights_connection status readout. The connection string never leaves the server.
  • The schedule helpers that moved now live only in functions_control_center_schedule.py. background_tasks.py, route_backend_control_center.py and route_frontend_admin_settings.py import them from there, and functions_control_center.py keeps only the one it uses. swagger_wrapper.py adds SWAGGER_BLUEPRINT_NAME and are_swagger_routes_registered(app).
  • Links built from data go through real guards. safeSameOriginUrl keeps an endpoint address on this deployment, refusing other hosts and javascript:. safeHttpsUrl keeps documentation links to plain HTTPS. A link that fails its guard is not shown.
  • admin_app_roles.py: the ControlCenterDashboardReader entry no longer claims to depend on the ControlCenterAdmin requirement, because control_center_required admits it on its own.
  • From the merge with V2: Tie mixed-source behavior to Enhanced Citations and describe its settings #1670 declared Application Insights and Health Check beside Appearance. Those declarations give way to the full Operations block, and Tie mixed-source behavior to Enhanced Citations and describe its settings #1670's Record mixed document and spreadsheet metrics switch now sits in the Operations Application Insights section, after the global logging readouts. Its label, help and default are unchanged. V2 admin: Enhanced Extraction section with Content Understanding nested #1668's content_understanding_supported flag is now reported through _build_runtime_flags().
  • Follow-up, not in this PR: the classic modals are unchanged and still carry the three corrected statements.

Screenshots

These are from the UI test fixture, with synthetic data.

Automatic Data Refresh with the next run in both timezones

Debug Logging with the nested timer, turnoff readout and DAI diagnostics link

Health check configuration guide with copyable addresses

Linked issue

N/A - no issue was filed for this work.

Release Notes & Latest Features

  • New Feature
  • Bug Fix
  • UI Enhancement
  • Breaking Change
  • Internal only

Is this visible to end users?

  • Yes
  • No

Is this admin-facing (Admin Settings, governance, deployment, config)?

  • Yes
  • No

Should this become a Latest Feature card?

  • Yes
  • No
  • Already added

Screenshot needed for the card?

  • Yes
  • No
  • Attached

Version bump

  • application/single_app/config.py VERSION third segment bumped, or not needed because this is docs-only (0.261.268 -> 0.261.269)
  • deployers/version.txt bumped, or not needed because deployers/ was not changed

V2 7bc21b612 (#1662 through #1674) is merged in, and this change is renumbered from 0.261.260 to 0.261.269. The base's own 0.261.260 references, from the Web Search nested-settings fix, are unchanged.

Testing / validation

All results below are from the merged tree:

  • python -m pytest over all 10 ui_tests\test_v2_admin_*.py suites with -m ui -q: 107 passed. This includes this PR's 21 Operations tests, which drive the built SPA with the real schema and normalizer behind intercepted APIs, in light and dark at 390 and 1920 px, including large text. It also includes the base's mixed-source, enhanced extraction, rail collapse, search cache and file sync suites. After the link guards landed, I re-ran the Operations suite: 21 passed.
  • python scripts\check_xss_sinks.py --base-sha <base> --head-sha <head> <changed application files>: passed (the xss-sink-check job)
  • python functional_tests\test_v2_admin_operations_parity.py: 11/11 passed (new)
  • python functional_tests\test_v2_admin_operations_derivations.py: 14/14 passed (new). Also runs test_v2_admin_operations_logic.ts, with 29 TypeScript checks. These include daylight-saving gaps and overlaps that mirror Python zoneinfo, and the link guards refusing other hosts, javascript: and non-HTTPS links.
  • npx tsc -b --noEmit and npm run build in application/v2_ui: passed
  • Every functional_tests\test_v2_admin_*.py suite (33), run individually with python <file>, plus test_admin_app_role_settings_consistency.py (3/3): all pass except the pre-existing failures below.
  • test_mixed_source_settings_derivation.py 9/9, test_app_settings_auxiliary_writers.py 103 passed, and test_codeql_import_cycle_lazy_imports.py 2/2. test_control_center_auto_refresh_schedule.py and test_admin_update_banner_version_comparison.py: passed.
  • Route policy: test_route_blueprint_policy_inventory.py 12/12, test_route_unauthenticated_policy_contract.py 7/7, test_route_policy_test_coverage.py 2/2
  • Docs: test_docs_app_surface_coverage.py 7/7 (including the inventory sync check) and test_docs_site_quality.py 6/6
  • python functional_tests\test_pytest_return_false_guard.py: 7/7. git diff --check: clean.

These failures are pre-existing and unrelated. The first three fail identically on a clean checkout of 7bc21b612. The last two failed the same way without this PR's changes, before the merge:

  • test_v2_admin_security_parity.py 7/8 (chat_content_settings_present unclaimed)
  • test_v2_admin_settings_schema.py 10/11 (m365_trusted_download_hosts default type)
  • test_content_understanding_extraction_engine.py 18/19 (expects "azure_content_understanding_key", in functions_settings.py, which this PR does not touch)
  • test_logging_tag_standardization.py (nonstandard workflow logging tags)
  • test_docs_release_notes_integrity.py (generated release-notes pages are stale)

Documentation

  • Release notes updated, or not needed (new v0.261.269 section)
  • Feature documentation updated, or not needed. Added docs/explanation/features/V2_ADMIN_OPERATIONS_SETTINGS.md, and rewrote docs/admin/operations.md, which was boilerplate, with every section anchor kept and Tie mixed-source behavior to Enhanced Citations and describe its settings #1670's mixed-source telemetry content included. enable_dai_debug is now documented instead of exempted from docs coverage, and [LOGGING_TIMERS] was added to docs/reference/logging-tags.md.
  • Fix documentation updated, or not needed (the DashboardReader description fix is covered in the feature note)

Security checklist

  • New Flask routes include @swagger_route(security=get_auth_security()) (no new routes; the cleanup UI reuses the existing admin endpoint)
  • Settings sent to non-admin frontends use sanitize_settings_for_user() (only the admin-only V2 settings payload changed; App Insights state is returned as booleans and fixed messages)
  • Browser JavaScript is served from local SimpleChat static assets only; no CDN-hosted JS (no new dependencies)
  • No secrets, keys, connection strings, or local-only artifacts are included (ui_tests/artifacts is git-ignored)

Paul Lizer (paullizer) and others added 5 commits October 6, 2026 18:59
Describe all seven Operations sections in the V2 settings schema so none
fall back to guessed enable_* switches, and add readouts and guides that
show what a save will do before it is made.

- Share the schedule and logging-timer rules between the classic save,
  the V2 normalizer and the background checks (functions_logging_timers,
  functions_control_center_schedule). Turnoff times are stored in UTC;
  legacy naive values are still read as server-local time.
- V2 validates refresh time and timezone, clamps timer durations per
  unit, and derives turnoff times and the next refresh on save.
- Add refresh schedule (both zones, Use my timezone), Control Center
  access table, logging turnoff, restart-pending, endpoint links, stored
  log cleanup, and Document Access Index diagnostics with a DAI link.
- Port the role setup, health check and Swagger modals as in-app guides,
  correcting statements the classic modals got wrong.
- Fix the DashboardReader registry entry, rewrite docs/admin/operations.md,
  document enable_dai_debug instead of exempting it, bump to 0.261.260.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Also correct the feature note: the shared timer and schedule helpers keep
the classic page's recalculation rules rather than changing them.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The picker shows the reader's own clock format, so an empty value now gets
its own message instead of one about 24-hour clocks. API callers sending
an unreadable time still get the HH:MM guidance.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
V2 already showed enable_dai_debug as an unexplained fallback switch; it
was the classic page that had no control for it.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
, #1671, #1674) and renumber the Operations settings parity to 0.261.269

Conflict resolutions:
- admin_settings_fields.py: keep the full Operations block. The Application
  Insights and Health Check declarations #1670 added beside Appearance are
  superseded by it, and its mixed-source telemetry switch moves into the
  Operations Application Insights section, after the global logging readouts.
  Keep #1668's on_enable documentation and both sides' V2_ONLY_FIELDS entries.
- route_backend_v2.py: fold content_understanding_supported into
  _build_runtime_flags.
- SettingsSection.tsx, AdminSettingsPage.tsx, adminFields.ts: keep both the
  section guide and runtimeFlags props, and on_enable beside the Operations
  field properties.
- operations.md, release_notes.md and tests: keep both sides. Both
  enable_dai_debug and enable_mixed_source_development_telemetry are documented
  rather than exempted, and Workspaces and Operations are both fully described.
- Renumber this branch's 0.261.260 references to 0.261.269; the base's own
  0.261.260 Web Search fix references are unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment thread functional_tests/test_v2_admin_operations_logic.ts Fixed
Comment thread application/single_app/functions_control_center.py Fixed
Comment thread application/single_app/functions_control_center_schedule.py Fixed
Comment thread application/single_app/functions_control_center_schedule.py Fixed
Comment thread application/single_app/functions_control_center_schedule.py Fixed
Add same-origin and HTTPS link guards for Operations admin links.

Remove unused control-center schedule re-exports and document intentional schedule parse fallbacks.

Update focused regression coverage for the guarded links and schedule helper imports.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@paullizer
Paul Lizer (paullizer) merged commit 931b426 into paullizer-react-v2-ui Oct 7, 2026
11 checks passed
Paul Lizer (paullizer) added a commit that referenced this pull request Oct 7, 2026
… 0.261.270

The Operations settings parity (#1675) took 0.261.269, so this pull request's
version, release notes section and version references move to 0.261.270.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit that referenced this pull request Oct 7, 2026
…ditors to 0.261.270

Brings in the V2 Operations settings parity (#1675), which took 0.261.269,
the version this pull request had just moved to.

- AdminSettingsPage.tsx: kept both sides in all three conflicts. Imports
  keep the global agents, global actions and approvals components and the
  base's Operations helpers; the Global agent delegation imports stay
  removed, because nothing on the page uses that card any more. Helpers keep
  selectCategory (category scroll reset) beside the base's readSwitch and
  renderRelatedSection. Overlays keep the unsaved-settings prompt for the
  global editors and the base's section guide dialog.
- admin_settings_fields.py auto-merged; the global manager components are
  intact and no delegation card was reintroduced.
- config.py: VERSION 0.261.270 (both sides had moved to 0.261.269).
- release_notes.md: this pull request's section moves to v0.261.270 above
  the base's v0.261.269 Operations section, which is kept unchanged.
- Renumbered this pull request's 30 other 0.261.269 references; the fix doc's
  version transition now reads 0.261.269 -> 0.261.270. The base's own
  0.261.269 references are untouched.
- docs/_data/app_surface.yml regenerated; unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants