@sylix/coworker 2.0.10 → 2.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/dist/commands/slash/config.d.ts.map +1 -1
  2. package/dist/commands/slash/config.js +23 -5
  3. package/dist/commands/slash/config.js.map +1 -1
  4. package/dist/commands/slash/todo.js +1 -1
  5. package/dist/commands/slash/todo.js.map +1 -1
  6. package/dist/core/CoWorkerAgent.d.ts.map +1 -1
  7. package/dist/core/CoWorkerAgent.js +6 -3
  8. package/dist/core/CoWorkerAgent.js.map +1 -1
  9. package/dist/permissions/PermissionInterceptor.js +1 -1
  10. package/dist/permissions/PermissionInterceptor.js.map +1 -1
  11. package/dist/skills/defaults/accessibility/screen-reader-testing.md +545 -0
  12. package/dist/skills/defaults/accessibility/wcag-audit-patterns.md +555 -0
  13. package/dist/skills/defaults/ai-ml/rag.md +276 -0
  14. package/dist/skills/defaults/backend-development/api-design-principles.md +528 -0
  15. package/dist/skills/defaults/backend-development/api-design.md +285 -0
  16. package/dist/skills/defaults/backend-development/architecture-patterns.md +494 -0
  17. package/dist/skills/defaults/backend-development/async-python.md +237 -0
  18. package/dist/skills/defaults/backend-development/auth-implementation-patterns.md +638 -0
  19. package/dist/skills/defaults/backend-development/bazel-build-optimization.md +387 -0
  20. package/dist/skills/defaults/backend-development/billing-automation/SKILL.md +566 -0
  21. package/dist/skills/defaults/backend-development/code-review-excellence.md +538 -0
  22. package/dist/skills/defaults/backend-development/cqrs-implementation.md +554 -0
  23. package/dist/skills/defaults/backend-development/database-design.md +305 -0
  24. package/dist/skills/defaults/backend-development/debugging-strategies.md +536 -0
  25. package/dist/skills/defaults/backend-development/e2e-testing-patterns.md +544 -0
  26. package/dist/skills/defaults/backend-development/error-handling-patterns.md +641 -0
  27. package/dist/skills/defaults/backend-development/fastapi-templates.md +559 -0
  28. package/dist/skills/defaults/backend-development/fastapi.md +309 -0
  29. package/dist/skills/defaults/backend-development/git-advanced-workflows.md +405 -0
  30. package/dist/skills/defaults/backend-development/microservices-patterns.md +595 -0
  31. package/dist/skills/defaults/backend-development/microservices.md +284 -0
  32. package/dist/skills/defaults/backend-development/monorepo-management.md +623 -0
  33. package/dist/skills/defaults/backend-development/nodejs-backend-patterns.md +1048 -0
  34. package/dist/skills/defaults/backend-development/nx-workspace-patterns.md +457 -0
  35. package/dist/skills/defaults/backend-development/paypal-integration/SKILL.md +478 -0
  36. package/dist/skills/defaults/backend-development/pci-compliance/SKILL.md +480 -0
  37. package/dist/skills/defaults/backend-development/python-anti-patterns.md +349 -0
  38. package/dist/skills/defaults/backend-development/python-background-jobs.md +364 -0
  39. package/dist/skills/defaults/backend-development/python-code-style.md +360 -0
  40. package/dist/skills/defaults/backend-development/python-configuration.md +368 -0
  41. package/dist/skills/defaults/backend-development/python-design-patterns.md +296 -0
  42. package/dist/skills/defaults/backend-development/python-error-handling.md +323 -0
  43. package/dist/skills/defaults/backend-development/python-packaging.md +887 -0
  44. package/dist/skills/defaults/backend-development/python-performance-optimization.md +874 -0
  45. package/dist/skills/defaults/backend-development/python-project-structure.md +252 -0
  46. package/dist/skills/defaults/backend-development/python-resilience.md +376 -0
  47. package/dist/skills/defaults/backend-development/python-resource-management.md +421 -0
  48. package/dist/skills/defaults/backend-development/python-type-safety.md +428 -0
  49. package/dist/skills/defaults/backend-development/sql-optimization-patterns.md +509 -0
  50. package/dist/skills/defaults/backend-development/stripe-integration/SKILL.md +522 -0
  51. package/dist/skills/defaults/backend-development/turborepo-caching.md +376 -0
  52. package/dist/skills/defaults/blockchain/defi-protocol-templates.md +430 -0
  53. package/dist/skills/defaults/blockchain/nft-standards.md +364 -0
  54. package/dist/skills/defaults/blockchain/solidity-security.md +514 -0
  55. package/dist/skills/defaults/blockchain/web3-testing.md +360 -0
  56. package/dist/skills/defaults/business/competitive-landscape/SKILL.md +527 -0
  57. package/dist/skills/defaults/business/market-sizing-analysis/SKILL.md +451 -0
  58. package/dist/skills/defaults/business/startup-financial-modeling/SKILL.md +494 -0
  59. package/dist/skills/defaults/business/startup-metrics-framework/SKILL.md +564 -0
  60. package/dist/skills/defaults/business/team-composition-analysis.md +437 -0
  61. package/dist/skills/defaults/compliance/employment-contract-templates/SKILL.md +527 -0
  62. package/dist/skills/defaults/compliance/gdpr-data-handling/SKILL.md +630 -0
  63. package/dist/skills/defaults/data-engineering/airflow-dag-patterns.md +436 -0
  64. package/dist/skills/defaults/data-engineering/airflow.md +519 -0
  65. package/dist/skills/defaults/data-engineering/data-quality.md +583 -0
  66. package/dist/skills/defaults/data-engineering/dbt-transformation-patterns.md +482 -0
  67. package/dist/skills/defaults/data-engineering/dbt.md +556 -0
  68. package/dist/skills/defaults/data-engineering/ml-pipeline-workflow/SKILL.md +247 -0
  69. package/dist/skills/defaults/data-engineering/spark-optimization.md +348 -0
  70. package/dist/skills/defaults/data-engineering/spark.md +411 -0
  71. package/dist/skills/defaults/database/postgresql.md +202 -0
  72. package/dist/skills/defaults/debugging/systematic-debugging.md +249 -0
  73. package/dist/skills/defaults/devops/architecture-decision-records.md +448 -0
  74. package/dist/skills/defaults/devops/changelog-automation.md +580 -0
  75. package/dist/skills/defaults/devops/cicd.md +314 -0
  76. package/dist/skills/defaults/devops/cloud.md +263 -0
  77. package/dist/skills/defaults/devops/code-review-excellence.md +299 -0
  78. package/dist/skills/defaults/devops/cost-optimization.md +295 -0
  79. package/dist/skills/defaults/devops/deployment-pipeline-design.md +356 -0
  80. package/dist/skills/defaults/devops/docker.md +281 -0
  81. package/dist/skills/defaults/devops/git-workflows.md +205 -0
  82. package/dist/skills/defaults/devops/github-actions.md +311 -0
  83. package/dist/skills/defaults/devops/gitlab-ci-patterns.md +266 -0
  84. package/dist/skills/defaults/devops/hybrid-cloud-networking.md +241 -0
  85. package/dist/skills/defaults/devops/istio-traffic-management.md +327 -0
  86. package/dist/skills/defaults/devops/kubernetes.md +339 -0
  87. package/dist/skills/defaults/devops/linkerd-patterns.md +311 -0
  88. package/dist/skills/defaults/devops/multi-cloud-architecture.md +181 -0
  89. package/dist/skills/defaults/devops/observability.md +243 -0
  90. package/dist/skills/defaults/devops/openapi-spec-generation.md +1024 -0
  91. package/dist/skills/defaults/devops/postmortem-writing.md +396 -0
  92. package/dist/skills/defaults/devops/prometheus-configuration.md +265 -0
  93. package/dist/skills/defaults/devops/secrets-management.md +341 -0
  94. package/dist/skills/defaults/devops/service-mesh-observability.md +385 -0
  95. package/dist/skills/defaults/devops/terraform-module-library.md +244 -0
  96. package/dist/skills/defaults/finance/backtesting-frameworks/SKILL.md +663 -0
  97. package/dist/skills/defaults/finance/risk-metrics-calculation/SKILL.md +557 -0
  98. package/dist/skills/defaults/frontend/accessibility-compliance.md +420 -0
  99. package/dist/skills/defaults/frontend/design-system-patterns.md +337 -0
  100. package/dist/skills/defaults/frontend/interaction-design.md +327 -0
  101. package/dist/skills/defaults/frontend/javascript.md +311 -0
  102. package/dist/skills/defaults/frontend/modern-javascript-patterns.md +927 -0
  103. package/dist/skills/defaults/frontend/react-native-design.md +440 -0
  104. package/dist/skills/defaults/frontend/react.md +345 -0
  105. package/dist/skills/defaults/frontend/responsive-design.md +472 -0
  106. package/dist/skills/defaults/frontend/tailwind-design-system.md +337 -0
  107. package/dist/skills/defaults/frontend/typescript-advanced-types.md +724 -0
  108. package/dist/skills/defaults/frontend/typescript.md +334 -0
  109. package/dist/skills/defaults/frontend/visual-design-foundations.md +326 -0
  110. package/dist/skills/defaults/frontend/web-component-design.md +279 -0
  111. package/dist/skills/defaults/game-development/godot-gdscript-patterns.md +188 -0
  112. package/dist/skills/defaults/game-development/unity-ecs-patterns.md +594 -0
  113. package/dist/skills/defaults/kubernetes/gitops-workflow.md +285 -0
  114. package/dist/skills/defaults/kubernetes/gitops.md +280 -0
  115. package/dist/skills/defaults/kubernetes/helm-chart-scaffolding.md +553 -0
  116. package/dist/skills/defaults/kubernetes/helm.md +343 -0
  117. package/dist/skills/defaults/kubernetes/k8s-manifest-generator.md +501 -0
  118. package/dist/skills/defaults/kubernetes/k8s-security-policies.md +342 -0
  119. package/dist/skills/defaults/kubernetes/manifests.md +330 -0
  120. package/dist/skills/defaults/kubernetes/security.md +337 -0
  121. package/dist/skills/defaults/llm-application/embedding-strategies.md +608 -0
  122. package/dist/skills/defaults/llm-application/hybrid-search-implementation.md +570 -0
  123. package/dist/skills/defaults/llm-application/hybrid-search.md +570 -0
  124. package/dist/skills/defaults/llm-application/langchain-architecture.md +666 -0
  125. package/dist/skills/defaults/llm-application/langchain.md +259 -0
  126. package/dist/skills/defaults/llm-application/llm-evaluation.md +695 -0
  127. package/dist/skills/defaults/llm-application/prompt-engineering-patterns.md +449 -0
  128. package/dist/skills/defaults/llm-application/prompt-engineering.md +219 -0
  129. package/dist/skills/defaults/llm-application/rag-implementation.md +434 -0
  130. package/dist/skills/defaults/llm-application/similarity-search-patterns.md +560 -0
  131. package/dist/skills/defaults/llm-application/similarity-search.md +560 -0
  132. package/dist/skills/defaults/llm-application/vector-index-tuning.md +523 -0
  133. package/dist/skills/defaults/mobile/mobile-android-design.md +440 -0
  134. package/dist/skills/defaults/mobile/mobile-ios-design.md +266 -0
  135. package/dist/skills/defaults/monitoring/distributed-tracing.md +436 -0
  136. package/dist/skills/defaults/monitoring/grafana-dashboards.md +370 -0
  137. package/dist/skills/defaults/monitoring/prometheus-configuration.md +379 -0
  138. package/dist/skills/defaults/monitoring/slo-implementation.md +323 -0
  139. package/dist/skills/defaults/refactoring/code-refactoring.md +349 -0
  140. package/dist/skills/defaults/security/anti-reversing-techniques/SKILL.md +559 -0
  141. package/dist/skills/defaults/security/auditor.md +168 -0
  142. package/dist/skills/defaults/security/binary-analysis-patterns/SKILL.md +438 -0
  143. package/dist/skills/defaults/security/memory-forensics/SKILL.md +483 -0
  144. package/dist/skills/defaults/security/mtls-configuration.md +349 -0
  145. package/dist/skills/defaults/security/protocol-reverse-engineering/SKILL.md +520 -0
  146. package/dist/skills/defaults/security/sast-configuration.md +182 -0
  147. package/dist/skills/defaults/security/security.md +313 -0
  148. package/dist/skills/defaults/security/stride-analysis.md +273 -0
  149. package/dist/skills/defaults/security/threat-mitigation-mapping.md +290 -0
  150. package/dist/skills/defaults/systems/bash-defensive-patterns/SKILL.md +539 -0
  151. package/dist/skills/defaults/systems/bats-testing-patterns/SKILL.md +631 -0
  152. package/dist/skills/defaults/systems/go-concurrency-patterns.md +657 -0
  153. package/dist/skills/defaults/systems/memory-safety-patterns.md +605 -0
  154. package/dist/skills/defaults/systems/rust-async-patterns.md +519 -0
  155. package/dist/skills/defaults/systems/shellcheck-configuration/SKILL.md +456 -0
  156. package/dist/skills/defaults/team-collaboration/multi-reviewer-patterns.md +126 -0
  157. package/dist/skills/defaults/team-collaboration/parallel-feature-development.md +151 -0
  158. package/dist/skills/defaults/testing/javascript-testing-patterns.md +1021 -0
  159. package/dist/skills/defaults/testing/python-testing-patterns.md +351 -0
  160. package/dist/skills/defaults/testing/testing.md +332 -0
  161. package/dist/skills/defaults/workflows/context-driven-development.md +384 -0
  162. package/dist/skills/defaults/workflows/track-management.md +592 -0
  163. package/dist/skills/defaults/workflows/workflow-patterns.md +622 -0
  164. package/dist/skills/index.d.ts +11 -0
  165. package/dist/skills/index.d.ts.map +1 -0
  166. package/dist/skills/index.js +129 -0
  167. package/dist/skills/index.js.map +1 -0
  168. package/dist/utils/character.js +6 -9
  169. package/dist/utils/character.js.map +1 -1
  170. package/dist/utils/contextManager.js +3 -7
  171. package/dist/utils/contextManager.js.map +1 -1
  172. package/dist/utils/inputbar.d.ts.map +1 -1
  173. package/dist/utils/inputbar.js +8 -1
  174. package/dist/utils/inputbar.js.map +1 -1
  175. package/dist/utils/output.d.ts.map +1 -1
  176. package/dist/utils/output.js +3 -35
  177. package/dist/utils/output.js.map +1 -1
  178. package/package.json +1 -1
@@ -0,0 +1,630 @@
1
+ ---
2
+ name: gdpr-data-handling
3
+ description: Implement GDPR-compliant data handling with consent management, data subject rights, and privacy by design. Use when building systems that process EU personal data, implementing privacy controls, or conducting GDPR compliance reviews.
4
+ ---
5
+
6
+ # GDPR Data Handling
7
+
8
+ Practical implementation guide for GDPR-compliant data processing, consent management, and privacy controls.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Building systems that process EU personal data
13
+ - Implementing consent management
14
+ - Handling data subject requests (DSRs)
15
+ - Conducting GDPR compliance reviews
16
+ - Designing privacy-first architectures
17
+ - Creating data processing agreements
18
+
19
+ ## Core Concepts
20
+
21
+ ### 1. Personal Data Categories
22
+
23
+ | Category | Examples | Protection Level |
24
+ | ---------------------- | --------------------------- | ------------------ |
25
+ | **Basic** | Name, email, phone | Standard |
26
+ | **Sensitive (Art. 9)** | Health, religion, ethnicity | Explicit consent |
27
+ | **Criminal (Art. 10)** | Convictions, offenses | Official authority |
28
+ | **Children's** | Under 16 data | Parental consent |
29
+
30
+ ### 2. Legal Bases for Processing
31
+
32
+ ```
33
+ Article 6 - Lawful Bases:
34
+ ├── Consent: Freely given, specific, informed
35
+ ├── Contract: Necessary for contract performance
36
+ ├── Legal Obligation: Required by law
37
+ ├── Vital Interests: Protecting someone's life
38
+ ├── Public Interest: Official functions
39
+ └── Legitimate Interest: Balanced against rights
40
+ ```
41
+
42
+ ### 3. Data Subject Rights
43
+
44
+ ```
45
+ Right to Access (Art. 15) ─┐
46
+ Right to Rectification (Art. 16) │
47
+ Right to Erasure (Art. 17) │ Must respond
48
+ Right to Restrict (Art. 18) │ within 1 month
49
+ Right to Portability (Art. 20) │
50
+ Right to Object (Art. 21) ─┘
51
+ ```
52
+
53
+ ## Implementation Patterns
54
+
55
+ ### Pattern 1: Consent Management
56
+
57
+ ```javascript
58
+ // Consent data model
59
+ const consentSchema = {
60
+ userId: String,
61
+ consents: [
62
+ {
63
+ purpose: String, // 'marketing', 'analytics', etc.
64
+ granted: Boolean,
65
+ timestamp: Date,
66
+ source: String, // 'web_form', 'api', etc.
67
+ version: String, // Privacy policy version
68
+ ipAddress: String, // For proof
69
+ userAgent: String, // For proof
70
+ },
71
+ ],
72
+ auditLog: [
73
+ {
74
+ action: String, // 'granted', 'withdrawn', 'updated'
75
+ purpose: String,
76
+ timestamp: Date,
77
+ source: String,
78
+ },
79
+ ],
80
+ };
81
+
82
+ // Consent service
83
+ class ConsentManager {
84
+ async recordConsent(userId, purpose, granted, metadata) {
85
+ const consent = {
86
+ purpose,
87
+ granted,
88
+ timestamp: new Date(),
89
+ source: metadata.source,
90
+ version: await this.getCurrentPolicyVersion(),
91
+ ipAddress: metadata.ipAddress,
92
+ userAgent: metadata.userAgent,
93
+ };
94
+
95
+ // Store consent
96
+ await this.db.consents.updateOne(
97
+ { userId },
98
+ {
99
+ $push: {
100
+ consents: consent,
101
+ auditLog: {
102
+ action: granted ? "granted" : "withdrawn",
103
+ purpose,
104
+ timestamp: consent.timestamp,
105
+ source: metadata.source,
106
+ },
107
+ },
108
+ },
109
+ { upsert: true }
110
+ );
111
+
112
+ // Emit event for downstream systems
113
+ await this.eventBus.emit("consent.changed", {
114
+ userId,
115
+ purpose,
116
+ granted,
117
+ timestamp: consent.timestamp,
118
+ });
119
+ }
120
+
121
+ async hasConsent(userId, purpose) {
122
+ const record = await this.db.consents.findOne({ userId });
123
+ if (!record) return false;
124
+
125
+ const latestConsent = record.consents
126
+ .filter((c) => c.purpose === purpose)
127
+ .sort((a, b) => b.timestamp - a.timestamp)[0];
128
+
129
+ return latestConsent?.granted === true;
130
+ }
131
+
132
+ async getConsentHistory(userId) {
133
+ const record = await this.db.consents.findOne({ userId });
134
+ return record?.auditLog || [];
135
+ }
136
+ }
137
+ ```
138
+
139
+ ```html
140
+ <!-- GDPR-compliant consent UI -->
141
+ <div class="consent-banner" role="dialog" aria-labelledby="consent-title">
142
+ <h2 id="consent-title">Cookie Preferences</h2>
143
+
144
+ <p>
145
+ We use cookies to improve your experience. Select your preferences below.
146
+ </p>
147
+
148
+ <form id="consent-form">
149
+ <!-- Necessary - always on, no consent needed -->
150
+ <div class="consent-category">
151
+ <input type="checkbox" id="necessary" checked disabled />
152
+ <label for="necessary">
153
+ <strong>Necessary</strong>
154
+ <span>Required for the website to function. Cannot be disabled.</span>
155
+ </label>
156
+ </div>
157
+
158
+ <!-- Analytics - requires consent -->
159
+ <div class="consent-category">
160
+ <input type="checkbox" id="analytics" name="analytics" />
161
+ <label for="analytics">
162
+ <strong>Analytics</strong>
163
+ <span>Help us understand how you use our site.</span>
164
+ </label>
165
+ </div>
166
+
167
+ <!-- Marketing - requires consent -->
168
+ <div class="consent-category">
169
+ <input type="checkbox" id="marketing" name="marketing" />
170
+ <label for="marketing">
171
+ <strong>Marketing</strong>
172
+ <span>Personalized ads based on your interests.</span>
173
+ </label>
174
+ </div>
175
+
176
+ <div class="consent-actions">
177
+ <button type="button" id="accept-all">Accept All</button>
178
+ <button type="button" id="reject-all">Reject All</button>
179
+ <button type="submit">Save Preferences</button>
180
+ </div>
181
+
182
+ <p class="consent-links">
183
+ <a href="/privacy-policy">Privacy Policy</a> |
184
+ <a href="/cookie-policy">Cookie Policy</a>
185
+ </p>
186
+ </form>
187
+ </div>
188
+ ```
189
+
190
+ ### Pattern 2: Data Subject Access Request (DSAR)
191
+
192
+ ```python
193
+ from datetime import datetime, timedelta
194
+ from typing import Dict, List, Optional
195
+ import json
196
+
197
+ class DSARHandler:
198
+ """Handle Data Subject Access Requests."""
199
+
200
+ RESPONSE_DEADLINE_DAYS = 30
201
+ EXTENSION_ALLOWED_DAYS = 60 # For complex requests
202
+
203
+ def __init__(self, data_sources: List['DataSource']):
204
+ self.data_sources = data_sources
205
+
206
+ async def submit_request(
207
+ self,
208
+ request_type: str, # 'access', 'erasure', 'rectification', 'portability'
209
+ user_id: str,
210
+ verified: bool,
211
+ details: Optional[Dict] = None
212
+ ) -> str:
213
+ """Submit a new DSAR."""
214
+ request = {
215
+ 'id': self.generate_request_id(),
216
+ 'type': request_type,
217
+ 'user_id': user_id,
218
+ 'status': 'pending_verification' if not verified else 'processing',
219
+ 'submitted_at': datetime.utcnow(),
220
+ 'deadline': datetime.utcnow() + timedelta(days=self.RESPONSE_DEADLINE_DAYS),
221
+ 'details': details or {},
222
+ 'audit_log': [{
223
+ 'action': 'submitted',
224
+ 'timestamp': datetime.utcnow(),
225
+ 'details': 'Request received'
226
+ }]
227
+ }
228
+
229
+ await self.db.dsar_requests.insert_one(request)
230
+ await self.notify_dpo(request)
231
+
232
+ return request['id']
233
+
234
+ async def process_access_request(self, request_id: str) -> Dict:
235
+ """Process a data access request."""
236
+ request = await self.get_request(request_id)
237
+
238
+ if request['type'] != 'access':
239
+ raise ValueError("Not an access request")
240
+
241
+ # Collect data from all sources
242
+ user_data = {}
243
+ for source in self.data_sources:
244
+ try:
245
+ data = await source.get_user_data(request['user_id'])
246
+ user_data[source.name] = data
247
+ except Exception as e:
248
+ user_data[source.name] = {'error': str(e)}
249
+
250
+ # Format response
251
+ response = {
252
+ 'request_id': request_id,
253
+ 'generated_at': datetime.utcnow().isoformat(),
254
+ 'data_categories': list(user_data.keys()),
255
+ 'data': user_data,
256
+ 'retention_info': await self.get_retention_info(),
257
+ 'processing_purposes': await self.get_processing_purposes(),
258
+ 'third_party_recipients': await self.get_recipients()
259
+ }
260
+
261
+ # Update request status
262
+ await self.update_request(request_id, 'completed', response)
263
+
264
+ return response
265
+
266
+ async def process_erasure_request(self, request_id: str) -> Dict:
267
+ """Process a right to erasure request."""
268
+ request = await self.get_request(request_id)
269
+
270
+ if request['type'] != 'erasure':
271
+ raise ValueError("Not an erasure request")
272
+
273
+ results = {}
274
+ exceptions = []
275
+
276
+ for source in self.data_sources:
277
+ try:
278
+ # Check for legal exceptions
279
+ can_delete, reason = await source.can_delete(request['user_id'])
280
+
281
+ if can_delete:
282
+ await source.delete_user_data(request['user_id'])
283
+ results[source.name] = 'deleted'
284
+ else:
285
+ exceptions.append({
286
+ 'source': source.name,
287
+ 'reason': reason # e.g., 'legal retention requirement'
288
+ })
289
+ results[source.name] = f'retained: {reason}'
290
+ except Exception as e:
291
+ results[source.name] = f'error: {str(e)}'
292
+
293
+ response = {
294
+ 'request_id': request_id,
295
+ 'completed_at': datetime.utcnow().isoformat(),
296
+ 'results': results,
297
+ 'exceptions': exceptions
298
+ }
299
+
300
+ await self.update_request(request_id, 'completed', response)
301
+
302
+ return response
303
+
304
+ async def process_portability_request(self, request_id: str) -> bytes:
305
+ """Generate portable data export."""
306
+ request = await self.get_request(request_id)
307
+ user_data = await self.process_access_request(request_id)
308
+
309
+ # Convert to machine-readable format (JSON)
310
+ portable_data = {
311
+ 'export_date': datetime.utcnow().isoformat(),
312
+ 'format_version': '1.0',
313
+ 'data': user_data['data']
314
+ }
315
+
316
+ return json.dumps(portable_data, indent=2, default=str).encode()
317
+ ```
318
+
319
+ ### Pattern 3: Data Retention
320
+
321
+ ```python
322
+ from datetime import datetime, timedelta
323
+ from enum import Enum
324
+
325
+ class RetentionBasis(Enum):
326
+ CONSENT = "consent"
327
+ CONTRACT = "contract"
328
+ LEGAL_OBLIGATION = "legal_obligation"
329
+ LEGITIMATE_INTEREST = "legitimate_interest"
330
+
331
+ class DataRetentionPolicy:
332
+ """Define and enforce data retention policies."""
333
+
334
+ POLICIES = {
335
+ 'user_account': {
336
+ 'retention_period_days': 365 * 3, # 3 years after last activity
337
+ 'basis': RetentionBasis.CONTRACT,
338
+ 'trigger': 'last_activity_date',
339
+ 'archive_before_delete': True
340
+ },
341
+ 'transaction_records': {
342
+ 'retention_period_days': 365 * 7, # 7 years for tax
343
+ 'basis': RetentionBasis.LEGAL_OBLIGATION,
344
+ 'trigger': 'transaction_date',
345
+ 'archive_before_delete': True,
346
+ 'legal_reference': 'Tax regulations require 7 year retention'
347
+ },
348
+ 'marketing_consent': {
349
+ 'retention_period_days': 365 * 2, # 2 years
350
+ 'basis': RetentionBasis.CONSENT,
351
+ 'trigger': 'consent_date',
352
+ 'archive_before_delete': False
353
+ },
354
+ 'support_tickets': {
355
+ 'retention_period_days': 365 * 2,
356
+ 'basis': RetentionBasis.LEGITIMATE_INTEREST,
357
+ 'trigger': 'ticket_closed_date',
358
+ 'archive_before_delete': True
359
+ },
360
+ 'analytics_data': {
361
+ 'retention_period_days': 365, # 1 year
362
+ 'basis': RetentionBasis.CONSENT,
363
+ 'trigger': 'collection_date',
364
+ 'archive_before_delete': False,
365
+ 'anonymize_instead': True
366
+ }
367
+ }
368
+
369
+ async def apply_retention_policies(self):
370
+ """Run retention policy enforcement."""
371
+ for data_type, policy in self.POLICIES.items():
372
+ cutoff_date = datetime.utcnow() - timedelta(
373
+ days=policy['retention_period_days']
374
+ )
375
+
376
+ if policy.get('anonymize_instead'):
377
+ await self.anonymize_old_data(data_type, cutoff_date)
378
+ else:
379
+ if policy.get('archive_before_delete'):
380
+ await self.archive_data(data_type, cutoff_date)
381
+ await self.delete_old_data(data_type, cutoff_date)
382
+
383
+ await self.log_retention_action(data_type, cutoff_date)
384
+
385
+ async def anonymize_old_data(self, data_type: str, before_date: datetime):
386
+ """Anonymize data instead of deleting."""
387
+ # Example: Replace identifying fields with hashes
388
+ if data_type == 'analytics_data':
389
+ await self.db.analytics.update_many(
390
+ {'collection_date': {'$lt': before_date}},
391
+ {'$set': {
392
+ 'user_id': None,
393
+ 'ip_address': None,
394
+ 'device_id': None,
395
+ 'anonymized': True,
396
+ 'anonymized_date': datetime.utcnow()
397
+ }}
398
+ )
399
+ ```
400
+
401
+ ### Pattern 4: Privacy by Design
402
+
403
+ ```python
404
+ class PrivacyFirstDataModel:
405
+ """Example of privacy-by-design data model."""
406
+
407
+ # Separate PII from behavioral data
408
+ user_profile_schema = {
409
+ 'user_id': str, # UUID, not sequential
410
+ 'email_hash': str, # Hashed for lookups
411
+ 'created_at': datetime,
412
+ # Minimal data collection
413
+ 'preferences': {
414
+ 'language': str,
415
+ 'timezone': str
416
+ }
417
+ }
418
+
419
+ # Encrypted at rest
420
+ user_pii_schema = {
421
+ 'user_id': str,
422
+ 'email': str, # Encrypted
423
+ 'name': str, # Encrypted
424
+ 'phone': str, # Encrypted (optional)
425
+ 'address': dict, # Encrypted (optional)
426
+ 'encryption_key_id': str
427
+ }
428
+
429
+ # Pseudonymized behavioral data
430
+ analytics_schema = {
431
+ 'session_id': str, # Not linked to user_id
432
+ 'pseudonym_id': str, # Rotating pseudonym
433
+ 'events': list,
434
+ 'device_category': str, # Generalized, not specific
435
+ 'country': str, # Not city-level
436
+ }
437
+
438
+ class DataMinimization:
439
+ """Implement data minimization principles."""
440
+
441
+ @staticmethod
442
+ def collect_only_needed(form_data: dict, purpose: str) -> dict:
443
+ """Filter form data to only fields needed for purpose."""
444
+ REQUIRED_FIELDS = {
445
+ 'account_creation': ['email', 'password'],
446
+ 'newsletter': ['email'],
447
+ 'purchase': ['email', 'name', 'address', 'payment'],
448
+ 'support': ['email', 'message']
449
+ }
450
+
451
+ allowed = REQUIRED_FIELDS.get(purpose, [])
452
+ return {k: v for k, v in form_data.items() if k in allowed}
453
+
454
+ @staticmethod
455
+ def generalize_location(ip_address: str) -> str:
456
+ """Generalize IP to country level only."""
457
+ import geoip2.database
458
+ reader = geoip2.database.Reader('GeoLite2-Country.mmdb')
459
+ try:
460
+ response = reader.country(ip_address)
461
+ return response.country.iso_code
462
+ except:
463
+ return 'UNKNOWN'
464
+ ```
465
+
466
+ ### Pattern 5: Breach Notification
467
+
468
+ ```python
469
+ from datetime import datetime
470
+ from enum import Enum
471
+
472
+ class BreachSeverity(Enum):
473
+ LOW = "low"
474
+ MEDIUM = "medium"
475
+ HIGH = "high"
476
+ CRITICAL = "critical"
477
+
478
+ class BreachNotificationHandler:
479
+ """Handle GDPR breach notification requirements."""
480
+
481
+ AUTHORITY_NOTIFICATION_HOURS = 72
482
+ AFFECTED_NOTIFICATION_REQUIRED_SEVERITY = BreachSeverity.HIGH
483
+
484
+ async def report_breach(
485
+ self,
486
+ description: str,
487
+ data_types: List[str],
488
+ affected_count: int,
489
+ severity: BreachSeverity
490
+ ) -> dict:
491
+ """Report and handle a data breach."""
492
+ breach = {
493
+ 'id': self.generate_breach_id(),
494
+ 'reported_at': datetime.utcnow(),
495
+ 'description': description,
496
+ 'data_types_affected': data_types,
497
+ 'affected_individuals_count': affected_count,
498
+ 'severity': severity.value,
499
+ 'status': 'investigating',
500
+ 'timeline': [{
501
+ 'event': 'breach_reported',
502
+ 'timestamp': datetime.utcnow(),
503
+ 'details': description
504
+ }]
505
+ }
506
+
507
+ await self.db.breaches.insert_one(breach)
508
+
509
+ # Immediate notifications
510
+ await self.notify_dpo(breach)
511
+ await self.notify_security_team(breach)
512
+
513
+ # Authority notification required within 72 hours
514
+ if self.requires_authority_notification(severity, data_types):
515
+ breach['authority_notification_deadline'] = (
516
+ datetime.utcnow() + timedelta(hours=self.AUTHORITY_NOTIFICATION_HOURS)
517
+ )
518
+ await self.schedule_authority_notification(breach)
519
+
520
+ # Affected individuals notification
521
+ if severity.value in [BreachSeverity.HIGH.value, BreachSeverity.CRITICAL.value]:
522
+ await self.schedule_individual_notifications(breach)
523
+
524
+ return breach
525
+
526
+ def requires_authority_notification(
527
+ self,
528
+ severity: BreachSeverity,
529
+ data_types: List[str]
530
+ ) -> bool:
531
+ """Determine if supervisory authority must be notified."""
532
+ # Always notify for sensitive data
533
+ sensitive_types = ['health', 'financial', 'credentials', 'biometric']
534
+ if any(t in sensitive_types for t in data_types):
535
+ return True
536
+
537
+ # Notify for medium+ severity
538
+ return severity in [BreachSeverity.MEDIUM, BreachSeverity.HIGH, BreachSeverity.CRITICAL]
539
+
540
+ async def generate_authority_report(self, breach_id: str) -> dict:
541
+ """Generate report for supervisory authority."""
542
+ breach = await self.get_breach(breach_id)
543
+
544
+ return {
545
+ 'organization': {
546
+ 'name': self.config.org_name,
547
+ 'contact': self.config.dpo_contact,
548
+ 'registration': self.config.registration_number
549
+ },
550
+ 'breach': {
551
+ 'nature': breach['description'],
552
+ 'categories_affected': breach['data_types_affected'],
553
+ 'approximate_number_affected': breach['affected_individuals_count'],
554
+ 'likely_consequences': self.assess_consequences(breach),
555
+ 'measures_taken': await self.get_remediation_measures(breach_id),
556
+ 'measures_proposed': await self.get_proposed_measures(breach_id)
557
+ },
558
+ 'timeline': breach['timeline'],
559
+ 'submitted_at': datetime.utcnow().isoformat()
560
+ }
561
+ ```
562
+
563
+ ## Compliance Checklist
564
+
565
+ ```markdown
566
+ ## GDPR Implementation Checklist
567
+
568
+ ### Legal Basis
569
+
570
+ - [ ] Documented legal basis for each processing activity
571
+ - [ ] Consent mechanisms meet GDPR requirements
572
+ - [ ] Legitimate interest assessments completed
573
+
574
+ ### Transparency
575
+
576
+ - [ ] Privacy policy is clear and accessible
577
+ - [ ] Processing purposes clearly stated
578
+ - [ ] Data retention periods documented
579
+
580
+ ### Data Subject Rights
581
+
582
+ - [ ] Access request process implemented
583
+ - [ ] Erasure request process implemented
584
+ - [ ] Portability export available
585
+ - [ ] Rectification process available
586
+ - [ ] Response within 30-day deadline
587
+
588
+ ### Security
589
+
590
+ - [ ] Encryption at rest implemented
591
+ - [ ] Encryption in transit (TLS)
592
+ - [ ] Access controls in place
593
+ - [ ] Audit logging enabled
594
+
595
+ ### Breach Response
596
+
597
+ - [ ] Breach detection mechanisms
598
+ - [ ] 72-hour notification process
599
+ - [ ] Breach documentation system
600
+
601
+ ### Documentation
602
+
603
+ - [ ] Records of processing activities (Art. 30)
604
+ - [ ] Data protection impact assessments
605
+ - [ ] Data processing agreements with vendors
606
+ ```
607
+
608
+ ## Best Practices
609
+
610
+ ### Do's
611
+
612
+ - **Minimize data collection** - Only collect what's needed
613
+ - **Document everything** - Processing activities, legal bases
614
+ - **Encrypt PII** - At rest and in transit
615
+ - **Implement access controls** - Need-to-know basis
616
+ - **Regular audits** - Verify compliance continuously
617
+
618
+ ### Don'ts
619
+
620
+ - **Don't pre-check consent boxes** - Must be opt-in
621
+ - **Don't bundle consent** - Separate purposes separately
622
+ - **Don't retain indefinitely** - Define and enforce retention
623
+ - **Don't ignore DSARs** - 30-day response required
624
+ - **Don't transfer without safeguards** - SCCs or adequacy decisions
625
+
626
+ ## Resources
627
+
628
+ - [GDPR Full Text](https://gdpr-info.eu/)
629
+ - [ICO Guidance](https://ico.org.uk/for-organisations/guide-to-data-protection/guide-to-the-general-data-protection-regulation-gdpr/)
630
+ - [EDPB Guidelines](https://edpb.europa.eu/our-work-tools/general-guidance/gdpr-guidelines-recommendations-best-practices_en)