
Let people start before they sign in
A person may want to try an application before creating an account. They might draft notes or prepare an initial piece of work, then sign in when they are ready to keep it.
Wildo lets participating resources belong to an anonymous session. That session has an identity and its own data scope, so the visitor’s work is separate from other visitors’ records.
When the session becomes associated with an authenticated account, the resource’s policy decides what happens to that work. The application can carry it over, replace existing account records of that type at conversion, or discard the temporary records.
Example — Keep the notes you made while trying the app
A visitor writes draft notes in Wonder Todos before signing in. The draft-note resource permits anonymous use and selects ADD, so those notes can become owned by the authenticated account alongside its existing notes.
For engineers
Enable visitor sessions for the user type
Wonder Todos enables this in backend-api/src/saas-config.backend.ts, inside the destination user type’s auth configuration:
anonymousSessionsEnabled: true,
This is the authentication opt-in, not a resource permission. The resource declaration below separately admits anonymous participation and assigns operation roles. Both decisions must match the intended visitor experience.
Give the resource an explicit policy
This excerpt from Wonder Todos’ draft-notes.resources-config.ts connects anonymous participation, the transfer policy and the CREATE roles. Source comments are omitted; later READ, LIST and mutation variants continue below:
mainSchema: DraftNotes_Schema,
resourceIdentifier: TasksManager_ResourceType.DRAFT_NOTES,
resourceFieldIdentifier: TasksManager_ResourceFieldIdentifier[TasksManager_ResourceType.DRAFT_NOTES],
resourceRelationships: resourcesRelationships,
isSystemResource: false,
isAnonymizable: true,
transpositionPolicy: ResourceTranspositionPolicy.ADD,
systemAccessPolicy: { exportSubject: ResourceSystemAccessMode.ALLOWED },
portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.SUBJECT_PROVIDED },
coreOperations: [
CoreResourceOperation.READ,
CoreResourceOperation.LIST,
CoreResourceOperation.CREATE,
CoreResourceOperation.UPDATE,
CoreResourceOperation.DELETE,
CoreResourceOperation.UPDATE_MANY,
],
customOperation: {} as Record<string, never>,
operationsConfiguration: {
[CoreResourceOperation.CREATE]: {
variants: [{
variantType: ResourceOperationVariantType.API_CALL,
isDefault: true,
roles: [CORE_APP_ROLES.APP_USER, CORE_APP_ROLES.APP_ANONYMOUS],
riskLevel: ResourceOperationRiskLevel.LOW,
}],
},
isAnonymizable is the historical API name for pre-sign-in resource participation. transpositionPolicy: ADD carries the visitor’s rows into the account without replacing its existing rows. The CREATE variant explicitly admits both APP_USER and APP_ANONYMOUS; the resource’s scope still determines which rows each caller owns.
Link the session to the authenticated identity
The authentication service issues and verifies the anonymous session identity. Conversion also checks whether the destination user type enables anonymous sessions. The ownership pass selects still-anonymous rows for that session and reassigns them to the authenticated user.
The actual ownership values make another pass safe for already-transferred rows: they no longer match the still-anonymous selection. Outcomes are recorded per resource type, so a later reconciliation can continue work that did not complete during conversion.
Decide what should survive trying the product
ADD preserves the account’s existing collection and adds the visitor’s work. REPLACE expresses that the visitor’s collection wins at conversion time. DISCARD removes the temporary records instead of moving them. Choose the policy according to what the record means: draft work and disposable trial state may deserve different treatment.
| Policy | At conversion | On reconciliation |
|---|---|---|
ADD | Move still-anonymous rows to the account. | Move rows still left on the anonymous identity. |
REPLACE | Remove the account’s existing rows of that type, then move the visitor’s rows. | Move remaining visitor rows without deleting the account’s rows again. |
DISCARD | Delete the temporary anonymous rows. | Retry deletion of remaining temporary rows. |
If the initial REPLACE deletion fails, repair can leave both sets in the account. This preserves work added after conversion instead of rerunning a destructive replacement later. The outcome is not an atomic all-resource transfer: per-resource results identify what still needs reconciliation.
The sign-in flow establishes the relationship between the session and account; a browser-supplied user identifier does not establish ownership. Participating resources remain private to the session before conversion and to the account afterwards.
This mechanism concerns continuity before and after sign-in. Erasure retention answers a separate question about what happens to records when a person’s data is erased.