Change History
Q-Framework enables automatic change history tracking with a single entity declaration. No separate audit logic implementation is required.
Enabling Change History
java
@QfEntity(
appKey = "app",
name = @QfI18n(defaultMessage = "Product", texts = { @QfI18nText(locale = "ko", message = "상품") }),
autoHistoryEnabled = true // this single declaration enables change history
)
public class ProductEntity {
@QfListAttribute(sortable = true)
@QfCreateAttribute(requiredOn = @QfRequiredOn(always = true))
@QfUpdateAttribute
@QfDisplayLabel(text = "Product Name")
private String name;
@QfListAttribute(sortable = true)
@QfCreateAttribute
@QfUpdateAttribute
@QfDisplayLabel(text = "Price")
private Integer price;
}Auto-Generated History API
GET /api/app/products/{id}/historyExample Response
json
{
"success": true,
"data": [
{
"historyId": "h-001",
"action": "UPDATE",
"changedAt": "2026-03-15T10:30:00",
"changedBy": "user-123",
"changedByName": "Jane Smith",
"changes": [
{
"field": "price",
"fieldLabel": "Price",
"before": "10000",
"after": "12000"
}
]
},
{
"historyId": "h-000",
"action": "CREATE",
"changedAt": "2026-03-01T09:00:00",
"changedBy": "user-100",
"changedByName": "John Doe"
}
]
}Automatic CRUD Audit Annotations (Modifier)
Automatically records the creator, updater, creation timestamp, and update timestamp.
java
@QfEntity(
appKey = "app",
name = @QfI18n(defaultMessage = "Product", texts = { @QfI18nText(locale = "ko", message = "상품") }),
autoHistoryEnabled = true
)
public class ProductEntity {
// ... business fields ...
@QfCreatedBy // automatically records creator ID
private String createdBy;
@QfCreatedAt // automatically records creation timestamp
private LocalDateTime createdAt;
@QfUpdatedBy // automatically records updater ID
private String updatedBy;
@QfUpdatedAt // automatically records update timestamp
private LocalDateTime updatedAt;
}Fields declared with @QfCreatedBy, @QfCreatedAt, @QfUpdatedBy, and @QfUpdatedAt are automatically populated from the current user information returned by QfUserProvider. No manual assignment is needed.
Frontend History UI
vue
<template>
<!-- History view UI rendered automatically -->
<QfEntityHistory
client-app="app"
entity="product"
:entity-id="productId"
/>
</template>History Retention Policy
yaml
qf:
history:
retention-days: 365 # history retention period (days)
max-records: 1000 # maximum history records per entityTIP
History data is stored in a separate history table. Main table performance is not affected.
Next Steps
- Excel Features — Bulk data processing
- SPI Extensions — Customize the history store