curl --request PUT \
--url https://api.example.com/{collection}/{id} \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"field_name": "<any>"
}
'{
"_id": "<string>",
"updated_at": "<string>",
"updated_by": "<string>",
"...": "<any>"
}Update an existing document with validation, versioning, and permission checks
curl --request PUT \
--url https://api.example.com/{collection}/{id} \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"field_name": "<any>"
}
'{
"_id": "<string>",
"updated_at": "<string>",
"updated_by": "<string>",
"...": "<any>"
}Documentation Index
Fetch the complete documentation index at: https://mintlify.com/KTS-o7/permission-mongo/llms.txt
Use this file to discover all available pages before exploring further.
updated_at and updated_byupdated_at timestampupdated_by to current user IDcurl -X PUT https://api.example.com/users/507f1f77bcf86cd799439011 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "John Updated",
"status": "inactive"
}'
curl -X PUT https://api.example.com/orders/ORD-12345 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "shipped",
"tracking_number": "1Z999AA10123456784"
}'
{
"_id": "507f1f77bcf86cd799439011",
"name": "John Updated",
"email": "john@example.com",
"role": "member",
"status": "inactive",
"created_at": "2024-03-15T10:30:00Z",
"updated_at": "2024-03-16T15:45:00Z",
"created_by": "user_123",
"updated_by": "user_456",
"company_id": "company_456"
}
replaceOne operation with merged document:
// Fetch existing document
oldDoc, err := collection.FindOne(ctx, bson.M{"_id": objectID}).Decode(&doc)
// Merge update into existing document
for k, v := range updateDoc {
mergedDoc[k] = v
}
mergedDoc["updated_at"] = time.Now().UTC()
mergedDoc["updated_by"] = authCtx.UserID
// Replace document
result, err := collection.ReplaceOne(ctx, bson.M{"_id": objectID}, mergedDoc)
updated_at, updated_by (handlers_crud.go:364-365)deny_write policies:
// Check deny_write fields
deniedFields := h.getDenyWriteFields(authCtx, collection)
for field := range updateDoc {
for _, denied := range deniedFields {
if field == denied {
return ErrForbidden // Cannot modify this field
}
}
}
policies:
users:
member:
actions: [read, update]
fields:
deny_write: [role, company_id, created_by, created_at]
immutableFields := collConfig.GetImmutableFields()
for _, field := range immutableFields {
if _, changed := updateDoc[field]; changed {
oldVal := oldDoc[field]
newVal := updateDoc[field]
if oldVal != newVal {
return ErrImmutableField
}
}
}
fields:
email:
type: string
immutable: true # Cannot be changed after creation
user_id:
type: string
immutable: true
if collConfig.Versioning.Enabled && h.version != nil {
h.saveVersionSnapshot(id, collection, oldDoc, authCtx.UserID)
}
full - Store complete document snapshotdiff - Store only changed fieldsmetadata - Store minimal metadata onlychanges := computeChanges(oldDoc, mergedDoc)
// Changes: [{field: "status", from: "active", to: "inactive"}, ...]
auditEvent := &audit.AuditEvent{
TenantID: authCtx.TenantID,
UserID: authCtx.UserID,
Action: "update",
Collection: collection,
DocID: id,
Changes: changes,
Success: true,
}
{
"error": "Cannot modify immutable field",
"code": "schema_validation",
"details": {
"field": "email"
}
}
{
"error": "Authentication required"
}
{
"error": "You don't have permission to modify this field",
"code": "forbidden",
"details": {
"field": "role"
}
}
{
"error": "Document not found",
"code": "document_not_found",
"details": {
"collection": "users",
"id": "507f1f77bcf86cd799439011"
}
}
{
"error": "Failed to update document",
"code": "internal_error",
"details": {
"error": "database write failed"
}
}
function preUpdate(event) {
// event.before = original document
// event.after = merged document to be saved
// Validate business logic
if (event.after.status === 'published' && !event.after.reviewed_by) {
throw new Error('Cannot publish without review');
}
// Auto-compute fields
if (event.after.price !== event.before.price) {
event.after.price_updated_at = new Date();
}
return event;
}
function postUpdate(event) {
// event.before = original document
// event.after = updated document
// Trigger side effects
if (event.after.status !== event.before.status) {
sendStatusChangeNotification(event.after);
}
// Update related documents
if (event.after.name !== event.before.name) {
updateRelatedRecords(event.after._id, event.after.name);
}
}
curl -X PUT https://api.example.com/tasks/task_789 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"status": "completed"}'
curl -X PUT https://api.example.com/users/me \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"bio": "Software engineer",
"avatar_url": "https://example.com/avatar.jpg"
}'
curl -X PUT https://api.example.com/products/SKU-12345 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"price": 29.99,
"stock": 150,
"on_sale": true,
"discount_percent": 10
}'