4.4.0 to 4.5.0
PlanDev 4.5.0 adds SeqDev file revisions, model-free plan imports, and improvements to external-event processing. Existing deployments require database migrations, and integrations that use the mission-model or plan-import APIs need updates.
Deployment and database migrations
This release includes database migrations. Follow the general Upgrade Process and Database Migration Guide, using the deployment files, complete migration directory, and Hasura metadata supplied with 4.5.0.
One migration rebuilds derived external events from existing source data. Run migrations with only PostgreSQL and Hasura running, and keep external writers stopped. Allow additional time for deployments with large external-event datasets.
SeqDev workspace versioning
SeqDev now maintains Git-backed workspace history and supports explicitly created File Revisions. Existing workspaces are adopted automatically on their first write; no manual conversion is required. Existing files start without named revisions, and saving a file does not create one - they are created manually from the File Revisions panel on the right side.
Revision naming convention
Revisions default to numeric names (1, 2, 3, …). To use alphabetic names instead (displayed as A, B, C, …), set both of these variables to ALPHABETIC in the corresponding services' environment configuration:
| Service | Environment variable |
|---|---|
plandev_workspace | WORKSPACE_REVISION_NAMING_CONVENTION |
plandev_ui | PUBLIC_WORKSPACE_REVISION_NAMING_CONVENTION |
Both default to NUMERIC and must use the same convention.
Workspace storage and backup
Revision history is stored in the workspace volume, not PostgreSQL. Ensure your backups preserve the entire workspace volume,
including metadata and the .git and .seqdev directories. Historical contents will require additional disk space.
If any of your external tools currently edit workspace files directly on the volume, change them to use the workspace API: direct filesystem edits will now be quarantined by SeqDev and reverted to their recorded state to maintain expected history.
Permissions and actions
The new create_file_revision permission defaults to OWNER_COLLABORATOR for the user role. If you customize workspace access,
configure this permission alongside your existing write permissions. Restoring revisions uses the existing write_file_directory permission.
Existing actions do not need changes to keep using working-copy files. To opt into revision-aware inputs and revision helper methods, use
@nasa-jpl/plandev-actions 1.4.0 or later and follow the Actions documentation.
Plan import/export compatibility
Plan exports now use "version": "3" to support Model-Free Plans. Version 2 and versionless files with the version 2 structure remain supported on import.
Update any of your custom consumers that only accept version 2 exports.
Model-free plans are an optional new import workflow; existing plans and executable mission models do not need conversion. Imported model-free plans are read-only.
API changes for custom integrations
Review these changes if you maintain scripts, GraphQL clients, or actions that make their own API queries:
- Mission-model file field:
mission_model.jar_idis nowdefinition_file_id, since not every model has a JAR file now. Update queries, mutations, generated types, and custom metadata that reference it. Models now exposeis_executable; clients must not assume every model has executable code. - Asynchronous plan imports:
POST /importPlannow returns HTTP202withmodel_id,plan_id, andplan_import_request_id. This applies to ordinary imports as well as model-free imports. Poll or subscribe to the correspondingplan_import_requestrow until its status iscomplete; handlefailedusing itsreason. Do not start dependent operations just because the upload request returned successfully. - Removed resource-types query: Replace
resourceTypes(missionModelId: ...)with aresource_typequery filtered bymodel_id. - Derived events:
merlin.derived_eventsis now a trigger-maintained table. Remove any custom jobs that issueREFRESH MATERIALIZED VIEW merlin.derived_events; normal source/event writes update it automatically.