Skip to content

feat: migrate meteor settings file to new places#1781

Open
Julusian wants to merge 5 commits into
Sofie-Automation:mainfrom
SuperFlyTV:feat/migrate-meteor-settings-file
Open

feat: migrate meteor settings file to new places#1781
Julusian wants to merge 5 commits into
Sofie-Automation:mainfrom
SuperFlyTV:feat/migrate-meteor-settings-file

Conversation

@Julusian

Copy link
Copy Markdown
Member

About the Contributor

This pull request is posted on behalf of Superfly

Type of Contribution

This is a: Code improvement / Documentation improvement

Current Behavior

There are some sofie settings defined in a meteor-settings.json config file. This is documented but is not very friendly to those configuring sofie, as it requires to be done at deployment separate from the rest of the settings.

New Behavior

These settings have all been migrated to new homes:

  • Most are in the studio settings, and can be configured both in the ui and from blueprints
  • Some are in the 'core system' settings and can be configured in the ui
  • One has moved to be an environment variable, as it is security related and requires other deployment changes to be useful.
  • A couple have been removed as they do not appear useful

The customizationClassName setting has been removed, as I am not sure if it has value. I expect that anyone wanting to use this already needs to embed custom css into sofie, in which case they can easily do this in another way. Please say if you disagree and use this.
The enableNTPTimeChecker setting has been removed as it appears it was broken and has been for I suspect multiple years.

Testing

  • I have added one or more unit tests for this PR
  • I have updated the relevant unit tests
  • No unit test changes are needed for this PR

Affected areas

Time Frame

Other Information

Status

  • PR is ready to be reviewed.
  • The functionality has been tested by the author.
  • Relevant unit tests has been added / updated.
  • Relevant documentation (code comments, system documentation) has been added / updated.

@Julusian Julusian added the Contribution from SuperFly.tv Contributions sponsored by SuperFly.tv label Jun 23, 2026
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 524286ad-2b3d-4a2a-bfb7-d65b31bc318a

📥 Commits

Reviewing files that changed from the base of the PR and between 58f9f74 and 7baa175.

📒 Files selected for processing (5)
  • meteor/server/api/cleanup.ts
  • packages/documentation/docs/user-guide/configuration/sofie-core-settings.md
  • packages/webui/src/client/lib/viewPort.ts
  • packages/webui/src/client/ui/SegmentTimeline/TimelineGrid.tsx
  • packages/webui/src/client/ui/Settings/Studio/Generic.tsx
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/webui/src/client/ui/Settings/Studio/Generic.tsx
  • packages/webui/src/client/ui/SegmentTimeline/TimelineGrid.tsx
  • packages/documentation/docs/user-guide/configuration/sofie-core-settings.md
  • packages/webui/src/client/lib/viewPort.ts
  • meteor/server/api/cleanup.ts

Walkthrough

Removes the Meteor settings-file-based Settings module and redistributes all previously file-configured settings: enableHeaderAuth moves to the SOFIE_ENABLE_HEADER_AUTH environment variable; maximumDataAge, confirmKeyCode, and poisonKey move to CoreSystem DB settings; and display/timeline/scroll defaults move to Studio DB settings. New shared constants provide defaults throughout.

Changes

Settings File Removal and DB Settings Migration

Layer / File(s) Summary
Shared constants and data model extensions
packages/shared-lib/src/core/constants.ts, packages/shared-lib/src/core/model/CoreSystemSettings.ts, packages/shared-lib/src/core/model/StudioSettings.ts, packages/meteor-lib/src/Settings.ts
Adds DEFAULT_DISPLAY_DURATION, DEFAULT_MAXIMUM_DATA_AGE, DEFAULT_TIME_SCALE, DEFAULT_POISON_KEY, DEFAULT_CONFIRM_KEY_CODE, DEFAULT_SHELF_DISPLAY_OPTIONS constants; extends ICoreSystemSettings with maximumDataAge, confirmKeyCode, poisonKey; extends IStudioSettings with 8 new optional display/behavior fields; replaces ISettings with IExtendedSettings.
Header auth migration to environment variable
meteor/server/security/auth.ts, meteor/server/api/rest/koa.ts, packages/webui/src/client/lib/Settings.ts, packages/webui/src/client/ui/UserPermissions.tsx, packages/documentation/docs/...
Introduces ENABLE_HEADER_AUTH from SOFIE_ENABLE_HEADER_AUTH on the server; injects enableHeaderAuth into Meteor runtime config; adds APP_HEADER_AUTH_ENABLED on the client replacing Settings.enableHeaderAuth; gates UserPermissions effects on the new constant; removes settings-file docs and adds env-var docs.
CoreSystem DB settings: init, migration, cleanup, and system management UI
meteor/server/coreSystem/index.ts, meteor/server/migration/upgrades/system.ts, meteor/server/migration/1_40_0.ts, meteor/server/api/cleanup.ts, meteor/server/__tests__/cronjobs.test.ts, packages/webui/src/client/ui/Settings/SystemManagement.tsx
Seeds CoreSystem settingsWithOverrides with DEFAULT_* constants at init and migration; migrates cleanupOldDataInner cutoff from Settings.maximumDataAge to DB-resolved value with DEFAULT_MAXIMUM_DATA_AGE fallback; adds maximumDataAge, confirmKeyCode, poisonKey controls to the System Management UI.
Studio DB settings: model, REST API, OpenAPI, init defaults, and settings UI
meteor/server/lib/rest/v1/studios.ts, packages/openapi/api/definitions/studios.yaml, meteor/server/api/rest/v1/typeConversion.ts, meteor/server/api/studio/api.ts, packages/webui/src/client/ui/Settings/Studio/Generic.tsx
Extends APIStudioSettings and OpenAPI schema with 7 new fields; wires bi-directional REST type conversion; seeds new studio defaults in insertStudioInner; adds 8 override-aware UI controls to the Studio generic settings page.
Client Settings module refactor and getCoreSystemSettings helper
packages/webui/src/client/lib/Settings.ts, packages/webui/src/client/collections/index.ts, packages/webui/src/client/ui/App.tsx
Removes exported Settings object and the DEFAULT_SETTINGS merge flow; adds getCoreSystemSettings() reading CoreSystem overrides from the client collection; removes customizationClassName body-class application.
Timing and zoom API signature changes
packages/webui/src/client/lib/rundownTiming.ts, packages/webui/src/client/lib/rundown.ts, packages/webui/src/client/ui/RundownView/RundownTiming/RundownTimingProvider.tsx, packages/webui/src/client/ui/SegmentTimeline/Constants.tsx
Changes computeSegmentDuration / getSegmentDuration from a boolean display flag to a numeric displayDuration; makes RundownTimingProvider.defaultDuration required; replaces exported MINIMUM_ZOOM_FACTOR constant with getMinimumZoomFactor(defaultTimeScale) function.
Viewport scroll API: followOnAirSegmentsHistory propagation
packages/webui/src/client/lib/viewPort.ts, packages/webui/src/client/ui/RundownView.tsx, packages/webui/src/client/ui/RundownView/MediaStatusPopUp/*, packages/webui/src/client/ui/RundownView/RundownHeader/useRundownPlaylistOperations.tsx, packages/webui/src/client/ui/SegmentTimeline/SegmentTimeline.tsx, packages/webui/src/client/ui/SegmentTimeline/SegmentTimelineContainer.tsx, packages/webui/src/client/ui/SegmentStoryboard/SegmentStoryboard.tsx
Adds followOnAirSegmentsHistory: number parameter to all scroll/focus functions and threads studio.settings.followOnAirSegmentsHistory ?? 0 from every call site, replacing the previous hardcoded boolean argument.
Default display duration and time scale propagation
packages/webui/src/client/ui/SegmentTimeline/TimelineGrid.tsx, packages/webui/src/client/ui/SegmentTimeline/SegmentTimeline.tsx, packages/webui/src/client/ui/SegmentTimeline/SegmentTimelineContainer.tsx, packages/webui/src/client/ui/SegmentTimeline/Renderers/VTSourceRenderer.tsx, packages/webui/src/client/ui/RundownView/RundownViewContextProviders.tsx, packages/webui/src/client/ui/RundownView/RundownDetachedShelf.tsx, packages/webui/src/client/ui/ClockView/ClockView.tsx, packages/webui/src/client/ui/Prompter/PrompterView.tsx
Threads studio.settings.defaultDisplayDuration ?? DEFAULT_DISPLAY_DURATION into all RundownTimingProvider and TimelineGrid call sites; migrates autoRewindLeavingSegment, allowGrabbingTimeline, useCountdownToFreezeFrame to studio settings; switches zoom clamping to getMinimumZoomFactor.
Confirm key and poison key migration to CoreSystem settings
packages/webui/src/client/lib/ModalDialog.tsx, packages/webui/src/client/lib/ui/containers/modals/Modal.tsx, packages/webui/src/client/lib/triggers/TriggersHandler.tsx, packages/webui/src/client/ui/Shelf/Shelf.tsx
Replaces Settings.confirmKeyCode and Settings.poisonKey with reactive getCoreSystemSettings() reads with DEFAULT_* fallbacks; TriggersHandler adds poisonKey to its useEffect dependency array; Modal captures the confirm key at bind time for consistent unbind.

Sequence Diagram(s)

sequenceDiagram
  rect rgba(100, 149, 237, 0.5)
    Note over Env,koa.ts: Server startup
    participant Env as SOFIE_ENABLE_HEADER_AUTH
    participant auth as auth.ts (ENABLE_HEADER_AUTH)
    participant koa as koa.ts
    participant MeteorConfig as __meteor_runtime_config__
  end
  rect rgba(144, 238, 144, 0.5)
    Note over ClientSettings,UserPermissions: Client init
    participant ClientSettings as client/lib/Settings.ts
    participant UserPermissions as UserPermissions.tsx
  end
  rect rgba(255, 165, 0, 0.5)
    Note over CoreSystemDB,SystemMgmtUI: Settings persistence
    participant CoreSystemDB as CoreSystem DB
    participant getCoreSystemSettings as getCoreSystemSettings()
    participant SystemMgmtUI as SystemManagement.tsx
  end

  Env->>auth: parsed into ENABLE_HEADER_AUTH boolean
  auth->>koa: ENABLE_HEADER_AUTH
  koa->>MeteorConfig: inject enableHeaderAuth into __meteor_runtime_config__
  MeteorConfig->>ClientSettings: APP_HEADER_AUTH_ENABLED = MeteorInjectedSettings.enableHeaderAuth
  ClientSettings->>UserPermissions: gates permission fetch effects

  SystemMgmtUI->>CoreSystemDB: writes confirmKeyCode / poisonKey / maximumDataAge
  CoreSystemDB->>getCoreSystemSettings: applyAndValidateOverrides(settingsWithOverrides)
  getCoreSystemSettings->>UserPermissions: (separate flow)
  getCoreSystemSettings->>TriggersHandler: reactive poisonKey
  getCoreSystemSettings->>ModalDialog: confirmKeyCode at bind time
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • Sofie-Automation/sofie-core#1681: Directly modifies computeSegmentDuration logic and signature in rundownTiming.ts, overlapping with this PR's rename of the display boolean parameter to a numeric displayDuration.
  • Sofie-Automation/sofie-core#1765: Modifies viewPort.ts scroll/focus logic including maintainFocusOnPartInstance and scrollToSegment, which this PR also refactors to thread followOnAirSegmentsHistory.

Suggested reviewers

  • nytamin
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: migrating meteor settings from a config file to new locations within the system.
Description check ✅ Passed The description is well-documented and related to the changeset, explaining the migration of settings and the rationale for changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@meteor/server/api/cleanup.ts`:
- Around line 86-89: The maximumDataAge variable extracted from systemSettings
on line 88 is not validated before being used in cleanup threshold calculations.
Add validation logic to ensure maximumDataAge is a positive finite number before
it is applied to any retention or cleanup math. If the value is invalid (less
than or equal to zero, NaN, or Infinity), either clamp it to a safe minimum
value or fallback to the DEFAULT_MAXIMUM_DATA_AGE constant to prevent unsafe
aggressive purging of recent data across collections.

In `@packages/documentation/docs/user-guide/configuration/sofie-core-settings.md`:
- Line 7: In the opening sentence of the sofie-core-settings.md file, replace
the contraction "it's" with the possessive form "its" in the phrase "configured
at its most basic level". The sentence should read "_Sofie Core_ is
configured at its most basic level using environment variables." where "its"
indicates possession rather than "it is".

In `@packages/shared-lib/src/core/model/StudioSettings.ts`:
- Around line 131-133: The new field `defaultShelfDisplayOptions` added to
`IStudioSettings` in StudioSettings.ts needs to be mapped in the REST conversion
layer to prevent it from being silently dropped in API responses. Add the
mapping for `defaultShelfDisplayOptions` in both the `APIStudioSettingsFrom`
function (which converts to API format) and the `APIStudioSettingsTo` function
(which converts from API format) in the type conversion module to ensure proper
round-trip serialization and deserialization of this setting.

In `@packages/webui/src/client/lib/viewPort.ts`:
- Around line 225-227: The variable followOnAirSegmentsHistory is being used
directly as a loop counter without normalization, but since it can contain
fractional values (like 1.5), this causes the loop to iterate an incorrect
number of times. Before assigning followOnAirSegmentsHistory to the loop counter
variable i, normalize it to a non-negative integer by using Math.floor to remove
any fractional part and ensure it doesn't go below zero.

In `@packages/webui/src/client/ui/SegmentTimeline/TimelineGrid.tsx`:
- Line 46: The new prop defaultDisplayDuration added at line 46 is not being
monitored for changes in the component's update guards. Update the
shouldComponentUpdate method to include defaultDisplayDuration in its prop
comparison logic, and ensure that componentDidUpdate also invalidates the
relevant cache (total duration cache) when defaultDisplayDuration changes. This
will prevent the grid from using stale duration values when this prop is
updated.

In `@packages/webui/src/client/ui/Settings/Studio/Generic.tsx`:
- Around line 511-526: The defaultTimeScale property uses IntInputControl which
truncates decimal values via parseInt, but the property is modeled as a number
that should support decimal precision. Replace IntInputControl with a
FloatInputControl or equivalent numeric control that properly handles and
preserves decimal values when updating the defaultTimeScale key through the
handleUpdate callback.

In `@packages/webui/src/client/ui/Shelf/Shelf.tsx`:
- Around line 600-604: The displayOptions variable assignment in the Shelf
component does not guard against params['display'] being a string array (which
occurs when URL has repeated display parameters). The .split() method will fail
at runtime if params['display'] is an array. Add a type check to handle both
cases: if params['display'] is already an array, use it directly; if it's a
string, call .split(',') on it. Ensure the result is always an array of strings
before assigning to displayOptions, falling back to
studioSettings?.defaultShelfDisplayOptions or DEFAULT_SHELF_DISPLAY_OPTIONS as
needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d32d0b38-9289-4099-9125-982e6ec713f1

📥 Commits

Reviewing files that changed from the base of the PR and between b2a2225 and 58f9f74.

⛔ Files ignored due to path filters (1)
  • packages/openapi/src/generated/openapi.yaml is excluded by !**/generated/**
📒 Files selected for processing (47)
  • meteor/server/Settings.ts
  • meteor/server/__tests__/cronjobs.test.ts
  • meteor/server/api/cleanup.ts
  • meteor/server/api/rest/koa.ts
  • meteor/server/api/rest/v1/typeConversion.ts
  • meteor/server/api/studio/api.ts
  • meteor/server/api/systemTime/ntpTimeChecker.ts
  • meteor/server/coreSystem/index.ts
  • meteor/server/lib/rest/v1/studios.ts
  • meteor/server/migration/1_40_0.ts
  • meteor/server/migration/upgrades/system.ts
  • meteor/server/security/auth.ts
  • packages/documentation/docs/user-guide/configuration/sofie-core-settings.md
  • packages/documentation/docs/user-guide/features/access-levels.md
  • packages/meteor-lib/src/Settings.ts
  • packages/openapi/api/definitions/studios.yaml
  • packages/shared-lib/src/core/constants.ts
  • packages/shared-lib/src/core/model/CoreSystemSettings.ts
  • packages/shared-lib/src/core/model/StudioSettings.ts
  • packages/webui/src/client/collections/index.ts
  • packages/webui/src/client/lib/ModalDialog.tsx
  • packages/webui/src/client/lib/Settings.ts
  • packages/webui/src/client/lib/rundown.ts
  • packages/webui/src/client/lib/rundownTiming.ts
  • packages/webui/src/client/lib/triggers/TriggersHandler.tsx
  • packages/webui/src/client/lib/ui/containers/modals/Modal.tsx
  • packages/webui/src/client/lib/viewPort.ts
  • packages/webui/src/client/ui/App.tsx
  • packages/webui/src/client/ui/ClockView/ClockView.tsx
  • packages/webui/src/client/ui/Prompter/PrompterView.tsx
  • packages/webui/src/client/ui/RundownView.tsx
  • packages/webui/src/client/ui/RundownView/MediaStatusPopUp/MediaStatusPopUpItem.tsx
  • packages/webui/src/client/ui/RundownView/MediaStatusPopUp/index.tsx
  • packages/webui/src/client/ui/RundownView/RundownDetachedShelf.tsx
  • packages/webui/src/client/ui/RundownView/RundownHeader/useRundownPlaylistOperations.tsx
  • packages/webui/src/client/ui/RundownView/RundownTiming/RundownTimingProvider.tsx
  • packages/webui/src/client/ui/RundownView/RundownViewContextProviders.tsx
  • packages/webui/src/client/ui/SegmentStoryboard/SegmentStoryboard.tsx
  • packages/webui/src/client/ui/SegmentTimeline/Constants.tsx
  • packages/webui/src/client/ui/SegmentTimeline/Renderers/VTSourceRenderer.tsx
  • packages/webui/src/client/ui/SegmentTimeline/SegmentTimeline.tsx
  • packages/webui/src/client/ui/SegmentTimeline/SegmentTimelineContainer.tsx
  • packages/webui/src/client/ui/SegmentTimeline/TimelineGrid.tsx
  • packages/webui/src/client/ui/Settings/Studio/Generic.tsx
  • packages/webui/src/client/ui/Settings/SystemManagement.tsx
  • packages/webui/src/client/ui/Shelf/Shelf.tsx
  • packages/webui/src/client/ui/UserPermissions.tsx
💤 Files with no reviewable changes (3)
  • meteor/server/Settings.ts
  • meteor/server/api/systemTime/ntpTimeChecker.ts
  • packages/webui/src/client/ui/App.tsx

Comment thread meteor/server/api/cleanup.ts
Comment thread packages/documentation/docs/user-guide/configuration/sofie-core-settings.md Outdated
Comment thread packages/shared-lib/src/core/model/StudioSettings.ts
Comment thread packages/webui/src/client/lib/viewPort.ts Outdated
Comment thread packages/webui/src/client/ui/SegmentTimeline/TimelineGrid.tsx
Comment thread packages/webui/src/client/ui/Settings/Studio/Generic.tsx Outdated
Comment thread packages/webui/src/client/ui/Shelf/Shelf.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Contribution from SuperFly.tv Contributions sponsored by SuperFly.tv

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant