using ZB.MOM.WW.ScadaBridge.Commons.Entities.Deployment; using ZB.MOM.WW.ScadaBridge.Commons.Entities.Instances; using ZB.MOM.WW.ScadaBridge.Commons.Types.Deployment; using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums; namespace ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories; public interface IDeploymentManagerRepository { // DeploymentRecord /// /// Gets a deployment record by its ID. /// /// The deployment record ID. /// A cancellation token that can be used to cancel the operation. /// The deployment record, or null if not found. Task GetDeploymentRecordByIdAsync(int id, CancellationToken cancellationToken = default); /// /// Gets all deployment records. /// /// A cancellation token that can be used to cancel the operation. /// A read-only list of all deployment records. Task> GetAllDeploymentRecordsAsync(CancellationToken cancellationToken = default); /// /// Gets all deployment records for a specific instance. /// /// The instance ID. /// A cancellation token that can be used to cancel the operation. /// A read-only list of deployment records for the instance. Task> GetDeploymentsByInstanceIdAsync(int instanceId, CancellationToken cancellationToken = default); /// /// Gets the current deployment status for an instance. /// /// The instance ID. /// A cancellation token that can be used to cancel the operation. /// The current deployment record, or null if no deployment exists. Task GetCurrentDeploymentStatusAsync(int instanceId, CancellationToken cancellationToken = default); /// /// Gets a deployment record by deployment ID. /// /// The deployment ID. /// A cancellation token that can be used to cancel the operation. /// The deployment record, or null if not found. Task GetDeploymentByDeploymentIdAsync(string deploymentId, CancellationToken cancellationToken = default); /// /// Adds a new deployment record. /// /// The deployment record to add. /// A cancellation token that can be used to cancel the operation. /// A task representing the asynchronous operation. Task AddDeploymentRecordAsync(DeploymentRecord record, CancellationToken cancellationToken = default); /// /// Updates an existing deployment record. /// /// The deployment record to update. /// A cancellation token that can be used to cancel the operation. /// A task representing the asynchronous operation. Task UpdateDeploymentRecordAsync(DeploymentRecord record, CancellationToken cancellationToken = default); /// /// Deletes a deployment record by ID, enforcing optimistic concurrency against the /// supplied . The caller MUST pass the /// RowVersion it last observed on the record so EF emits /// DELETE ... WHERE Id = @id AND RowVersion = @prior. A concurrent edit /// surfaces as /// on , matching the documented /// "Optimistic concurrency is used on deployment status records" design rule. /// /// The deployment record ID to delete. /// The RowVersion the caller observed; used as the optimistic-concurrency token. /// A cancellation token that can be used to cancel the operation. /// A task representing the asynchronous operation. Task DeleteDeploymentRecordAsync(int id, byte[] expectedRowVersion, CancellationToken cancellationToken = default); // SystemArtifactDeploymentRecord /// /// Gets a system artifact deployment record by ID. /// /// The system artifact deployment record ID. /// A cancellation token that can be used to cancel the operation. /// The system artifact deployment record, or null if not found. Task GetSystemArtifactDeploymentByIdAsync(int id, CancellationToken cancellationToken = default); /// /// Gets all system artifact deployment records. /// /// A cancellation token that can be used to cancel the operation. /// A read-only list of all system artifact deployment records. Task> GetAllSystemArtifactDeploymentsAsync(CancellationToken cancellationToken = default); /// /// Adds a new system artifact deployment record. /// /// The system artifact deployment record to add. /// A cancellation token that can be used to cancel the operation. /// A task representing the asynchronous operation. Task AddSystemArtifactDeploymentAsync(SystemArtifactDeploymentRecord record, CancellationToken cancellationToken = default); /// /// Updates an existing system artifact deployment record. /// /// The system artifact deployment record to update. /// A cancellation token that can be used to cancel the operation. /// A task representing the asynchronous operation. Task UpdateSystemArtifactDeploymentAsync(SystemArtifactDeploymentRecord record, CancellationToken cancellationToken = default); /// /// Deletes a system artifact deployment record by ID. /// /// The system artifact deployment record ID to delete. /// A cancellation token that can be used to cancel the operation. /// A task representing the asynchronous operation. Task DeleteSystemArtifactDeploymentAsync(int id, CancellationToken cancellationToken = default); // WP-8: DeployedConfigSnapshot /// /// Gets the deployed config snapshot for an instance. /// /// The instance ID. /// A cancellation token that can be used to cancel the operation. /// The deployed config snapshot, or null if not found. Task GetDeployedSnapshotByInstanceIdAsync(int instanceId, CancellationToken cancellationToken = default); /// /// Adds a new deployed config snapshot. /// /// The deployed config snapshot to add. /// A cancellation token that can be used to cancel the operation. /// A task representing the asynchronous operation. Task AddDeployedSnapshotAsync(DeployedConfigSnapshot snapshot, CancellationToken cancellationToken = default); /// /// Updates an existing deployed config snapshot. /// /// The deployed config snapshot to update. /// A cancellation token that can be used to cancel the operation. /// A task representing the asynchronous operation. Task UpdateDeployedSnapshotAsync(DeployedConfigSnapshot snapshot, CancellationToken cancellationToken = default); /// /// Deletes the deployed config snapshot for an instance. /// /// The instance ID. /// A cancellation token that can be used to cancel the operation. /// A task representing the asynchronous operation. Task DeleteDeployedSnapshotAsync(int instanceId, CancellationToken cancellationToken = default); // Notify-and-fetch: PendingDeployment staging store /// /// Stages a flattened instance config for an in-flight deployment. Supersession: /// any prior pending row for the same InstanceId is removed first, so at most /// one pending row exists per instance (safe because the per-instance operation lock /// serializes same-instance deploys). Does NOT call — /// the caller commits, mirroring the other Add/Delete repository methods. /// /// The pending deployment to stage. /// A cancellation token that can be used to cancel the operation. /// A task representing the asynchronous operation. Task AddPendingDeploymentAsync(PendingDeployment pending, CancellationToken cancellationToken = default); /// /// Gets a pending deployment by its deployment ID (the fetch key). /// /// The deployment ID. /// A cancellation token that can be used to cancel the operation. /// The pending deployment, or null if not found. Task GetPendingDeploymentByIdAsync(string deploymentId, CancellationToken cancellationToken = default); /// /// Gets the pending deployment staged for a given instance (there is at most one per instance /// by design — supersedes and /// inserts only if absent). Used by startup reconcile: /// when reports a row already exists (a concurrent /// reconcile from the other node, or an in-flight deploy), the handler reads that existing row /// so a second concurrently-missing node can fetch the same pending config with its (multi-use, /// TTL-bound) token instead of being omitted from the gap. Defensive against >1 row: returns /// the most recently created one. /// /// The instance whose pending deployment to read. /// A cancellation token that can be used to cancel the operation. /// The pending deployment for the instance, or null if none is staged. Task GetPendingDeploymentByInstanceIdAsync(int instanceId, CancellationToken cancellationToken = default); /// /// Deletes a pending deployment by its deployment ID. No-op if not found. Does NOT /// call — the caller commits, mirroring the other /// Add/Delete repository methods. /// /// The deployment ID to delete. /// A cancellation token that can be used to cancel the operation. /// A task representing the asynchronous operation. Task DeletePendingDeploymentByIdAsync(string deploymentId, CancellationToken cancellationToken = default); /// /// Purges all pending deployments whose ExpiresAtUtc is at or before /// (TTL maintenance). This is a self-contained maintenance /// operation: it commits its own delete and returns the number of rows removed. /// /// The current UTC time; rows with ExpiresAtUtc <= nowUtc are purged. /// A cancellation token that can be used to cancel the operation. /// The number of pending deployments purged. Task PurgeExpiredPendingDeploymentsAsync(DateTimeOffset nowUtc, CancellationToken cancellationToken = default); // Startup reconciliation: expected-set query and insert-if-absent staging /// /// Returns the set of instances that central considers deployed for the given site — the join of /// DeployedConfigSnapshot (by InstanceId) with Instance (where SiteId == siteId). /// Instances without a snapshot are excluded. No ConfigurationJson is loaded; the full /// config is fetched on demand via the HTTP endpoint using a freshly-minted token from /// . /// /// The site primary key to filter on. /// A cancellation token that can be used to cancel the operation. /// All deployed instances for the site, as lightweight projections. Task> GetExpectedDeploymentsForSiteAsync(int siteId, CancellationToken cancellationToken = default); /// /// Inserts a for the instance ONLY IF no pending row already /// exists for that InstanceId. An existing pending row signals an in-flight deploy that /// is already delivering to the node — do NOT supersede it (contrast with /// , which supersedes). Returns true if the row /// was staged, false if an existing row was found and left untouched. /// This method is self-contained: it commits its own save and returns a meaningful result, /// matching the convention of . /// /// The instance to stage the pending deployment for. /// The deployment ID (fetch key). /// Revision hash of the flattened configuration. /// JSON-serialized flattened configuration. /// Short-TTL fetch token the site node will present to the HTTP endpoint. /// UTC timestamp for this pending row. /// UTC expiry after which the token is no longer valid. /// A cancellation token that can be used to cancel the operation. /// true if staged; false if a pending row already existed and was left unchanged. Task StagePendingIfAbsentAsync(int instanceId, string deploymentId, string revisionHash, string configurationJson, string token, DateTimeOffset createdAtUtc, DateTimeOffset expiresAtUtc, CancellationToken cancellationToken = default); // Instance lookups for deployment pipeline /// /// Gets an instance by ID. /// /// The instance ID. /// A cancellation token that can be used to cancel the operation. /// The instance, or null if not found. Task GetInstanceByIdAsync(int instanceId, CancellationToken cancellationToken = default); /// /// Gets an instance by unique name. /// /// The unique instance name. /// A cancellation token that can be used to cancel the operation. /// The instance, or null if not found. Task GetInstanceByUniqueNameAsync(string uniqueName, CancellationToken cancellationToken = default); /// /// Updates an instance. /// /// The instance to update. /// A cancellation token that can be used to cancel the operation. /// A task representing the asynchronous operation. Task UpdateInstanceAsync(Instance instance, CancellationToken cancellationToken = default); /// /// Removes an instance and everything that depends on it: deployment /// records, deployed config snapshot, attribute/alarm overrides, and /// connection bindings. /// /// The instance ID to delete. /// A cancellation token that can be used to cancel the operation. /// A task representing the asynchronous operation. Task DeleteInstanceAsync(int instanceId, CancellationToken cancellationToken = default); /// /// Saves all pending changes to the database. /// /// A cancellation token that can be used to cancel the operation. /// A task representing the number of entities saved. Task SaveChangesAsync(CancellationToken cancellationToken = default); }