Skip to main content
Wildo.ai Coming soon

Files and storage

Let background work produce durable files

Services and scheduled batches can write artifacts through the same configured storage providers without a browser upload.

A scheduled background job writes an archive to storage.

Let background work produce durable files

Files are also outputs: archives, reports and reusable artifacts produced by background work. Wildo’s storage contract can accept those bytes from a service or batch, using its execution and storage identity.

The producer chooses the artifact’s content, name and lifecycle. Storage placement and credentials use the same provider machinery as other managed file operations.

Example — Write a daily audit archive

A scheduled batch collects an eligible day of audit records and writes a named JSON artifact. Running without a browser request does not require the batch to construct an object-store client or receive a root credential.

For engineers

A background writer already has bytes, so it calls a configured storage provider with a readable stream, content type, byte size and execution context. If the artifact needs file routes, sharing or the normal file lifecycle, its producer must also create and maintain a file record; a direct storage write alone does not register a FILES row.

The audit archive batch uses application-owned managed or local storage. A user-delegated Drive connection is not an application-wide background storage credential.

Resolve storage through the running service

The audit batch receives FileStorageRouterBackendService through its service dependencies. After checking that archival is enabled and storage is configured, it selects the first configured provider in this ordered list:

if (!fileStorageRouter.isConfigured()) {
  // The batch logs the missing storage configuration and skips this tick.
  return summary();
}

const storageProvider = fileStorageRouter.resolveProvider([
  FileStorageAccepted.WILDO_MANAGED,
  FileStorageAccepted.LOCAL_DIRECTORY,
]);

This is a selected excerpt from the archive batch, with its logging shortened. The router supplies the provider used by the write below. The batch does not supply access keys in the upload call; the chosen provider handles its configured credentials and placement policy.

Producer responsibilityStorage responsibility
Select the records and serialize an artifact.Accept the byte stream through the provider contract.
Supply MIME type and actual byte length.Perform the write using the configured storage identity.
Choose a destination name and replacement policy.Apply the provider’s key layout and scope options.
Record the result and own retention or file registration.Return the write result; a raw object does not create a file record.

Use a real artifact shape and a deliberate key

The archive writer in audit-logs-archive.batch.backend.service.ts includes its application and day-window provenance in the JSON and selects a deterministic daily file name. Comments are omitted; day-window selection occurs earlier. The storageProvider is the result of the selection above.

const day = dayKey(windowStart);

const payload = {
  schemaVersion: 1 as const,
  kind: 'audit-log-archive' as const,
  applicationId: applicationId ?? null,
  dayWindowUtc: day,
  windowStart: windowStart.toISOString(),
  windowEnd: windowEnd.toISOString(),
  archivedAt,
  recordCount: records.length,
  truncated,
  records,
};
const buffer = Buffer.from(JSON.stringify(payload), 'utf-8');

await storageProvider.upload(
  Readable.from([buffer]),
  randomUUID(),
  'application/json',
  buffer.byteLength,
  executionContext,
  {
    folderPath: AUDIT_ARCHIVE_FOLDER,
    fileName: `audit-archive-${day}.json`,
    includeApplicationId: true,
  },
);

Make scheduling and lifecycle explicit

The archive batch is registered by the engine’s custom-batch manifest and enabled through auditTrail.archiveAfterDays; storage configuration alone does not turn it on. The horizon selects older, complete UTC day windows, not the current day’s unfinished records. Its named output supports repeated writes to the same daily destination. The payload records whether the selected window was truncated, so consumers can distinguish a complete window from a partial artifact.

For another service or scheduled job, decide whether outputs should replace a deterministic key or create a new version, how they become discoverable, and who removes them. Bind application or platform-service credentials according to the producer’s identity plane. Broker publication is only dispatch: successful artifact production also requires execution and a completed storage write.

Building a B2B product or an internal tool?

Wildo is not self-service yet. Tell us what you have in mind and we will say plainly whether it fits, and what happens next.