Imagine: your mobile app with a million users in the EU. The DPA requests Records of Processing Activities—proof of compliance. If no log exists, a fine of up to 4% of annual turnover. That's exactly what happened to one of our clients: after an audit, they received a warning for undocumented data transfer to an advertising network. We implemented the log in 3 days, and during a re-inspection, the fine was avoided.
GDPR (Article 30) requires not just obtaining consent, but recording every operation: when, what data, for what purposes, and on what legal basis. For B2C apps with an EU audience, this means storing a machine-readable log. We offer a full cycle: audit of your current stack, schema design, middleware implementation, and client interface.
In practice, 60% of apps we've audited do not log data transfers to analytics services. That's a direct violation. Our solution automatically intercepts such operations and records them in an append-only log.
Which operations need logging?
Operations that must be logged:
- Data collection during registration: fields, timestamp, legal basis (consent/contract/legitimate interest)
- Transfer to third parties: sending email to Mailchimp, analytics to Firebase, ads to AdMob—each transfer with recipient and purpose
- Data updates: profile changes, email, phone
- Deletion: upon user request or after retention period expiry
- Access: when and by which staff member data was viewed (for enterprise apps)
Why must the log be append-only?
Editing or deleting log entries is itself a GDPR violation. Therefore, the log is append-only. Entries cannot be modified or deleted. Retention period is at least 3 years. For mobile apps with high operation frequency, this can be 50,000 to 500,000 entries per month. Proper indexing (user_id, operation_type, created_at) ensures fast search during audits.
Journal schema
data_processing_logs: id UUID PK user_id UUID FK NULLABLE -- null for anonymous operations 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 -- additional context created_at TIMESTAMPTZ DEFAULT NOW() Details on data type choice
For data categories, we use a string array rather than a separate table—this speeds up writes. Indexes on `user_id` and `operation_type` reduce search latency to 10 ms for 1 million records.How to implement the log server-side?
The most convenient approach is through middleware/aspects, rather than manually in every service. This reduces the risk of missing an operation. Example in Django:
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 What does the user see in the 'My Data' section?
Under GDPR, users have the right to see how their data has been processed. In the app, provide a section: "Settings → Privacy → Data Processing History". Show filtered log entries: only records with the current user's user_id, without technical details, with understandable operation descriptions.
struct DataProcessingEntry: Identifiable, Decodable { let id: UUID let operationDescription: String // "Your data was shared with an analytics service" let date: Date let dataCategories: [String] let purpose: String } Third parties are listed by official names (Google Analytics, Meta Pixel)—the user should recognize the service.
Integration with consent management
When consent for a specific purpose is withdrawn (e.g., marketing), create a log entry operation_type='consent_revoked' and stop transferring data to the corresponding third parties. This documents the withdrawal moment—important for DPA audits.
How we do it: implementation stages
- Data flow audit — identify all collection and transfer points. Analyze code, network request configs, SDK integrations (Firebase, AppsFlyer).
- Log schema design — tailored to your stack (PostgreSQL, MongoDB, BigQuery). Choose optimal model for your load.
- Middleware/aspect implementation — automatic logging of key operations. Set up triggers on critical endpoints.
- API for user history — with filtering, pagination, access rights.
- Client UI development — on SwiftUI / Jetpack Compose / Flutter — display understandable history.
- Integration with CMP (consent management platform) and handling consent withdrawal.
- API and audit documentation, team training.
Timelines and guarantee
| Stage | Duration |
|---|---|
| Data flow audit | 1–2 days |
| Schema design | 0.5–1 day |
| Middleware + API | 2–3 days |
| Client UI | 1–2 days |
| CMP integration | 1 day |
| Documentation | 0.5 day |
Full project from 5 to 10 days. We provide a guarantee of compliance with GDPR requirements and assistance during DPA audits. Our experience: over 5 years in mobile app development and compliance solutions. Get a consultation: send a description of your app, and we will estimate the scope of work.
Contact us for an audit—we will check your current log in 1 day. Order a data processing log implementation and protect your business from fines.
Comparison of logging approaches
| Approach | Effort | Risk of missing operations | Flexibility |
|---|---|---|---|
| Manual in each service | High | High | Low |
| Middleware/aspects | Medium | Low | High |
| DPA framework (OneTrust) | Low | Medium | Medium |
For most projects, we recommend the middleware approach. It balances implementation cost and coverage completeness. If API changes are frequent, you can migrate to a declarative DPA framework.







