docs/Security/PerUserDataAudit2025-12-23/QUICK_REFERENCE.md
collapsed field from Swimlanescollapsed field from Listscollapsed statuscollapse() mutation from SwimlanesThese are NOW per-user and persisted:
Where it's stored:
user.profileEvery time you move a card:
userPositionHistory collectionMeteor.call('userPositionHistory.undo', historyId)Meteor.call('userPositionHistory.createCheckpoint', boardId, name)All UI preference data is validated:
UserPositionHistory
{
userId: String,
boardId: String,
entityType: 'card' | 'list' | 'swimlane' | 'checklist' | 'checklistItem',
entityId: String,
actionType: 'move' | 'create' | 'delete',
previousState: Object,
newState: Object,
isCheckpoint: Boolean,
checkpointName: String,
createdAt: Date
}
// Create a checkpoint
Meteor.call('userPositionHistory.createCheckpoint', boardId, 'name');
// Undo a change
Meteor.call('userPositionHistory.undo', historyId);
// Get recent history
Meteor.call('userPositionHistory.getRecent', boardId, 50, (err, result) => {
// result is array of history entries
});
// Get checkpoints
Meteor.call('userPositionHistory.getCheckpoints', boardId, (err, checkpoints) => {
// result is array of checkpoints
});
// Restore to checkpoint
Meteor.call('userPositionHistory.restoreToCheckpoint', checkpointId);
cards.js
move() now automatically tracks changesUserPositionHistory.trackChange()swimlanes.js
collapsed field removed (use profile.collapsedSwimlanes)collapse() mutation removedlists.js
collapsed field removed (use profile.collapsedLists)users.js
getListWidthFromStorage() with validationsetSwimlaneHeightToStorage() with validationclient/lib/localStorageValidator.js
- validateAndCleanLocalStorage()
- shouldRunCleanup()
- getValidatedLocalStorageData()
- setValidatedLocalStorageData()
- validators object with all validation functions
models/lib/userStorageHelpers.js
- getValidatedNumber()
- setValidatedNumber()
- getValidatedBoolean()
- setValidatedBoolean()
models/userPositionHistory.js
- UserPositionHistory collection
- Helpers: getDescription(), canUndo(), undo()
- Meteor methods for interaction
server/migrations/ensureValidSwimlaneIds.js
- Runs automatically on startup
- Fixes cards/lists without swimlaneId
- Rescues orphaned data
Runs on server startup:
Finds cards without swimlaneId
Finds orphaned cards
Adds validation hooks
Tracking:
Migrations.findOne({ name: 'ensure-valid-swimlane-ids' })
// Shows results of migration
// Swimlane with board-level collapse
{
_id: 'swim123',
title: 'Development',
collapsed: true // ❌ Shared with all users!
}
// Card without swimlaneId
{
_id: 'card456',
title: 'Fix bug',
swimlaneId: undefined // ❌ No swimlane!
}
// Swimlane - no collapsed field
{
_id: 'swim123',
title: 'Development',
// collapsed: removed ✅
}
// User's profile - has per-user settings
{
_id: 'user789',
profile: {
collapsedSwimlanes: {
'board123': {
'swim123': true // ✅ Per-user!
}
},
listWidths: {
'board123': {
'list456': 300 // ✅ Per-user!
}
}
}
}
// Card with swimlaneId
{
_id: 'card456',
title: 'Fix bug',
swimlaneId: 'swim123' // ✅ Always set!
}
// Position history entry
{
_id: 'hist789',
userId: 'user789',
boardId: 'board123',
entityType: 'card',
entityId: 'card456',
actionType: 'move',
previousState: { swimlaneId: 'swim123', listId: 'list456', sort: 1 },
newState: { swimlaneId: 'swim123', listId: 'list789', sort: 2 },
createdAt: ISODate('2025-12-23T07:00:00Z')
}
A: Make sure you're using the new per-user settings methods:
user.setCollapsedSwimlane(boardId, swimlaneId, true);
user.getCollapsedSwimlaneFromStorage(boardId, swimlaneId);
A: Migration found cards pointing to deleted swimlanes. They're safe in the rescue swimlane. You can move them to proper swimlanes.
A: That's intentional - we only keep valid data. Invalid/corrupted data is removed automatically during daily cleanup.
A: Use the Meteor method:
Meteor.call('userPositionHistory.createCheckpoint', boardId, 'Before big changes');
A: Use the Meteor method:
Meteor.call('userPositionHistory.undo', historyEntryId);
| File | Purpose |
|---|---|
| models/userPositionHistory.js | Position history collection |
| client/lib/localStorageValidator.js | Data validation |
| server/migrations/ensureValidSwimlaneIds.js | Automatic migration |
| models/swimlanes.js | Swimlane model |
| models/lists.js | List model |
| models/cards.js | Card model with tracking |
See detailed documentation:
Status: ✅ Ready for use
Last Updated: 2025-12-23