Implementing Personal Data Processing Log in Mobile Apps
GDPR requires not only getting consent for data processing but documenting each processing operation (Article 30 — Records of Processing Activities). For B2C mobile apps with EU audience this means: maintain machine-readable log of what data, when, for what purposes, and what legal basis was used.
What to Log
Processing operations needing logs:
- Data collection at registration: fields, timestamp, legal basis (consent/contract/legitimate interest)
- Third-party transfers: sending email to Mailchimp, analytics to Firebase, ads to AdMob — each transfer with recipient and purpose
- Data changes: profile update, email, phone change
- Deletion: user request or retention period expiry
- Access: when and by whom from staff viewed data (corporate apps)
Log Schema
data_processing_logs:
id UUID PK
user_id UUID FK NULLABLE -- null for anonymous ops
operation_type VARCHAR -- 'collect', 'transfer', 'update', 'delete', 'access'
data_categories TEXT[] -- ['email', 'location', 'purchase_history']
purpose VARCHAR -- 'analytics', 'marketing', 'service_provision'
legal_basis VARCHAR -- 'consent', 'contract', 'legitimate_interest'
third_party VARCHAR NULLABLE -- 'firebase', 'mailchimp', null
actor_type VARCHAR -- 'user', 'system', 'staff'
actor_id UUID NULLABLE -- Staff ID when actor_type='staff'
ip_address INET NULLABLE
metadata JSONB -- extra context
created_at TIMESTAMPTZ DEFAULT NOW()
Log — append-only. Records not edited or deleted (deleting log records itself is breach). Log retention — minimum 3 years.
Auto-Logging on Server
Easiest via middleware/aspects, not manually in each service:
# Django middleware example
class DataProcessingLogMiddleware:
LOGGED_ENDPOINTS = {
'POST /api/auth/register': ('collect', ['email', 'name'], 'contract'),
'PUT /api/user/profile': ('update', ['profile_data'], 'contract'),
'DELETE /api/user': ('delete', ['all_user_data'], 'legal_obligation'),
}
def process_response(self, request, response):
key = f"{request.method} {request.path}"
if key in self.LOGGED_ENDPOINTS and response.status_code < 400:
op_type, categories, basis = self.LOGGED_ENDPOINTS[key]
DataProcessingLog.objects.create(
user_id=request.user.id if request.user.is_authenticated else None,
operation_type=op_type,
data_categories=categories,
legal_basis=basis,
ip_address=get_client_ip(request)
)
return response
Client: "My Data"
Per GDPR, user can see how their data was processed. In app — "Settings → Privacy → Processing History". Show filtered log: only user's records, no technical details, clear descriptions.
struct DataProcessingEntry: Identifiable, Decodable {
let id: UUID
let operationDescription: String // "Your data shared with analytics service"
let date: Date
let dataCategories: [String]
let purpose: String
}
Third parties listed by official names (Google Analytics, Meta Pixel) — user should recognize service.
Consent Management Integration
On consent revocation (e.g., marketing) — create log entry operation_type='consent_revoked' and stop data transfer to corresponding third parties. Documents revocation moment — important for DPA audit.
Timeline — 1–3 days: log schema, middleware for auto-logging key ops, API for history read, client UI.







