Skip to main content

The Refresh Loop

If UCSD is the source of truth and the platform is a mirror, something has to keep the mirror current. That something is a timer function in CameraOperation that wakes every five minutes, pulls the whole fleet from UCSD, and reconciles it into the platform's own stores — without rewriting documents that didn't actually change.

The one idea to hold on to​

Jobs_UcsdCameraConfigRefresher is a five-minute reconcile: pull from UCSD, diff against what's stored, and upsert only the differences — into several stores at once, with an audit trail. A single UCSD device fans out into four Cosmos documents plus a SQL row:

Each of those is an Upsert… that first computes what changed and writes a patch if the document exists, or adds it if it's new — one device's data reshaped for each store's purpose (intended config, camera config, static identity, operational seed, and the RBAC row).

Diffing is change-aware, and encryption-aware​

The refresher doesn't blindly overwrite. It builds a patch of only the changed properties, and crucially it does so through the encryption service, so it compares decrypted values:

var patchDictionary = await ChangeDetectionMethods.GetDocumentChangesForIncludedProperties(
currentAcqDevice, acqDevice, propertyNames, _encryptionService);

Every change becomes an audit event capturing the before/after, so there's a record of what the refresh altered and when.

Gotcha: compare decrypted, or every run looks like a change

Encrypted fields (credentials, addresses) get a fresh random IV on every encryption, so the same plaintext encrypts to a different ciphertext each time (the incomparable-ciphertext property from the Infrastructure encryption lesson). If the diff compared ciphertext, every credential would look changed on every run — re-encrypting and re-auditing constantly. That's why the change detection is handed the encryption service: it decrypts to compare.

Wrapping up​

The refresh loop is a five-minute, change-aware reconcile from UCSD into four Cosmos documents and a SQL row per device — patching only real differences, comparing decrypted values so re-encryption doesn't masquerade as change, auditing everything, and bounded for scale. Auto-bootstrap of new cameras is production-and-flag gated.

The last piece is what "bootstrapping" a camera actually means — seeding its orchestration state and encrypting its credentials: Bootstrap & Credentials.