Skip to main content
Wildo.ai Coming soon

Privacy and subject rights

Keep each kind of data for a declared period

An application states how long each class of data is kept and why, each resource says when its clock starts, and a scheduled job deletes what has expired through the application's normal deletion path.

What it is
Mechanism — something you declare.
What it does
A period per class, with a reason. The classes are the application's records, files, audit logs, operational logs and business records a statute requires kept. A declared period needs a number of days and a stated rationale. A class nobody has decided is left out of the schedule and reported as undecided. It is never read as "kept forever", and no period is defaulted.
What you decide
Declare dataRetention in the application configuration, and a retentionBinding with a class and a start point on each resource whose data should expire.
Where it stops
A resource with no binding is kept until it is erased, and is reported as unbound so the gap stays visible.
Each data class binds a retention period to several resources, whose expired rows are removed by scheduled deletion.
Drawn for Privacy and subject rights, the area this capability belongs to.

An application declares a retention schedule: for each class of data, how many days it is kept and the reason for that period. Each resource that holds such data binds itself to a class and names the moment its clock starts. A scheduled job then deletes every bound record whose period has ended.

The problem it solves

A privacy notice has to say how long data is kept, and an operator has to be able to show that it is true. Neither is possible when the period exists only as a sentence in a document, or as a number per table that nobody keeps consistent. What an operator actually decides is a handful of periods: customer data, files, audit records, operational logs, business records. Those are the classes this mechanism uses.

What it does

A period per class, with a reason. The classes are the application’s records, files, audit logs, operational logs and business records a statute requires kept. A declared period needs a number of days and a stated rationale. A class nobody has decided is left out of the schedule and reported as undecided. It is never read as “kept forever”, and no period is defaulted.

The clock starts where the purpose ends. A resource names its start point: when the record was created, when it was last updated, when a declared closing date is set (a ticket closed, a contract ended), at the end of the calendar year the record was created, or when its organization is marked for deletion. A record with a closing date that is still open never expires.

Deletion through the application, not beside it. The job deletes through the application’s own service layer, the path the tenant purge also uses, so the record’s dependants, files and search index entries follow it. It runs on both supported databases. A bound resource may not use a database-side expiry, which would delete with no application code running.

A period change needs no backfill. The expiry is computed from the current schedule on every run, so shortening or lengthening a period applies on the next run.

Records kept hidden are disposed of too. A record an erasure or a tenant teardown retained and hid is deleted at the end of its class period.

What you decide

Declare dataRetention in the application configuration, and a retentionBinding with a class and a start point on each resource whose data should expire.

Selected from wildo.saas.config.ts; the audit-log, operational-log and business-records classes are omitted.

dataRetention: {
  [DataRetentionClass.RESOURCE_DATA]: {
    retentionDays: 30,
    rationale:
      'Kept while it is in use — a workspace\'s todos while the account exists, a team goal until it is achieved or abandoned — and after that point held 30 days so a mistake can be undone, then erased. No statutory duty applies to a test application\'s task data.',
  },
  [DataRetentionClass.FILES]: {
    retentionDays: 30,
    rationale: 'Follows the rows that reference them: attachments and generated documents have no purpose beyond their record, so they share its 30-day window.',
  },
  // …
},

Selected from team-goals.resources-config.ts; the explanatory comment above the binding is omitted.

retentionBinding: {
  retentionClass: DataRetentionClass.RESOURCE_DATA,
  startPoint: RetentionStartPoint.CLOSURE_EVENT,
  closureFieldName: 'closedAt',
},

Each class carries a number of days and the reason for it. The team goal binds itself to the application-records class and starts its clock at closedAt, so an open goal never expires however old it is, and a closed one falls due for deletion 30 days after it closed.

Limits

A resource with no binding is kept until it is erased, and is reported as unbound so the gap stays visible. The job deletes in bounded batches per run, so a large backlog can take several runs.

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.