Add manager save version migrations and profile metadata#16
Conversation
Reviewer's GuideIntroduces a versioned manager save format with a migration pipeline, extends manager state normalization to handle facilities and sponsors robustly, and enriches profile export/import with manager metadata and compatibility checks. Sequence diagram for profile import and manager save version migrationsequenceDiagram
actor User
participant FileInput
participant App
participant applyProfileSnapshot
participant ManagerNormalizer as normalizeManagerState
participant MigrationPipeline as MANAGER_MIGRATIONS
User->>FileInput: Select profile file
FileInput-->>App: FileReader result (JSON string)
App->>App: JSON.parse(reader.result)
App->>applyProfileSnapshot: snapshot
applyProfileSnapshot->>applyProfileSnapshot: validate snapshot object
applyProfileSnapshot->>applyProfileSnapshot: parse managerMeta.saveVersion
applyProfileSnapshot->>applyProfileSnapshot: fallback to snapshot.manager.saveVersion
applyProfileSnapshot->>applyProfileSnapshot: clamp and compare to MANAGER_SAVE_VERSION
alt incomingSaveVersion > MANAGER_SAVE_VERSION
applyProfileSnapshot-->>App: throw Error(incompatible save version)
App-->>User: showSettingsNotice(error, danger)
else compatible save version
applyProfileSnapshot->>applyProfileSnapshot: warn if manager version differs from default
applyProfileSnapshot->>ManagerNormalizer: normalizeManagerState(snapshot.manager)
ManagerNormalizer->>ManagerNormalizer: deep clone working state
ManagerNormalizer->>ManagerNormalizer: determine saveVersion
ManagerNormalizer->>MigrationPipeline: applyMigrations(working, saveVersion)
MigrationPipeline-->>ManagerNormalizer: migrated state
ManagerNormalizer-->>applyProfileSnapshot: normalized ManagerState
applyProfileSnapshot->>applyProfileSnapshot: ensureFreeAgentPool()
applyProfileSnapshot->>applyProfileSnapshot: restore gp, ui, raceSettings
applyProfileSnapshot-->>App: info {version, managerSaveVersion, managerVersion}
App->>App: build label with profile and managerSaveVersion
App-->>User: showSettingsNotice(label, success)
end
Class diagram for updated manager state, sponsors, and profile metadataclassDiagram
class ManagerState {
number version
number saveVersion
number seasonYear
number week
string selectedTeam
Map~string,TeamState~ teams
DriverAgent[] freeAgents
}
class TeamState {
string team
number budget
Upgrades upgrades
Facilities facilities
Sponsors sponsors
Contract[] roster
number form
}
class Upgrades {
number engine
number aero
number systems
}
class Facilities {
number engine
number aero
number systems
}
class Sponsors {
string[] primary
string[] secondary
string[] partners
}
class DriverAgent {
string driver
number morale
number askingSalary
}
class Contract {
string driver
number salary
number length
}
class ProfileSnapshot {
string version
string exportedAt
ManagerMeta managerMeta
ManagerState manager
GpSnapshot gp
UiSnapshot ui
RaceSettingsSnapshot raceSettings
}
class ManagerMeta {
number version
number saveVersion
}
class GpSnapshot {
boolean active
number raceIndex
TableEntry[] table
}
class UiSnapshot {
}
class RaceSettingsSnapshot {
}
class ManagerNormalizer {
normalizeManagerState(state)
}
class MigrationPipeline {
MANAGER_SAVE_VERSION
MANAGER_MIGRATIONS
applyMigrations(state, saveVersion)
}
ManagerState "1" -- "many" TeamState : teams
TeamState "1" -- "1" Upgrades : upgrades
TeamState "1" -- "1" Facilities : facilities
TeamState "1" -- "1" Sponsors : sponsors
ManagerState "1" -- "many" DriverAgent : freeAgents
ManagerState "1" -- "1" ManagerNormalizer : normalizedBy
ManagerNormalizer "1" -- "1" MigrationPipeline : uses
MigrationPipeline "1" --> "1" ManagerState : migrates
ProfileSnapshot "1" -- "1" ManagerState : manager
ProfileSnapshot "1" -- "1" ManagerMeta : managerMeta
ProfileSnapshot "1" -- "1" GpSnapshot : gp
ProfileSnapshot "1" -- "1" UiSnapshot : ui
ProfileSnapshot "1" -- "1" RaceSettingsSnapshot : raceSettings
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- There is quite a bit of duplicated logic for parsing and normalizing numeric versions (manager version, saveVersion) across
normalizeManagerState,collectProfileSnapshot, andapplyProfileSnapshot; consider extracting a small helper (e.g.parseIntOrNaN/normalizeVersionNumber) to keep the behavior consistent and easier to change. - The migration functions in
MANAGER_MIGRATIONScurrently both mutate the passed-in state and return it, but the return value is ignored innormalizeManagerState; either rely solely on mutation (and drop thereturn state) or havenormalizeManagerStateuse the returned value to make the intent clearer.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- There is quite a bit of duplicated logic for parsing and normalizing numeric versions (manager version, saveVersion) across `normalizeManagerState`, `collectProfileSnapshot`, and `applyProfileSnapshot`; consider extracting a small helper (e.g. `parseIntOrNaN` / `normalizeVersionNumber`) to keep the behavior consistent and easier to change.
- The migration functions in `MANAGER_MIGRATIONS` currently both mutate the passed-in state and return it, but the return value is ignored in `normalizeManagerState`; either rely solely on mutation (and drop the `return state`) or have `normalizeManagerState` use the returned value to make the intent clearer.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 15b195f2e4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| } | ||
|
|
||
| working.saveVersion = MANAGER_SAVE_VERSION; |
There was a problem hiding this comment.
Reject unsupported manager save versions
When saveVersion is newer than MANAGER_SAVE_VERSION, this code only warns and then forcefully rewrites working.saveVersion to the current runtime version. In a downgrade scenario (opening localStorage written by a newer app), unknown fields are discarded during normalization and the next persistManagerState() call can permanently overwrite the newer save with downgraded data, so this path should fail fast like applyProfileSnapshot does for profile imports.
Useful? React with 👍 / 👎.
Summary
Testing
Codex Task
Summary by Sourcery
Introduce versioned manager save handling with migration support and propagate manager metadata through profile export/import.
Enhancements: