Skip to main content 홈 크리에이터 thomasmoreai legal-skills-open kvkk-compliance
kvkk-compliance KVKK and GDPR compliance patterns - consent management, right to erasure, breach notification, audit logging, cookie consent, and data classification.
설치로 이동 Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/ThomasMoreAI/legal-skills-open --skill kvkk-compliance명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... 이 저장소의 다른 Skills fetching-arbitration-rules Use when retrieving arbitration institutional rules (ICC, LCIA, SCC, SIAC, HKIAC, VIAC, МКАС/МАК при ТПП України, UNCITRAL) — fetching current version, verifying redaction applicable to the date of arbitration agreement, constructing URLs for official rule texts
determining-pl-request-regime Use when choosing the Polish legal regime for letters, requests, applications, complaints, petitions, public-information requests, KPA filings, PPSA complaints, RODO access requests, registry extracts, court-file access, tax/ZUS/cudzoziemcy/USC procedures, or professional lawyer letters. Prevents mixing UDIP, KPA, PPSA, RODO, registry, special-procedure, and advocate/radca letter regimes.
applying-new-york-convention Use when preparing applications for recognition and enforcement of foreign arbitral awards in Poland, applications for setting aside arbitral awards under KPC art. 1205–1211, or opposing such applications — mapping Article V of the 1958 New York Convention to art. 1214–1215 of the Polish KPC, identifying grounds for refusal, structuring public policy arguments
name kvkk-compliance title KVKK & GDPR Compliance Patterns description KVKK and GDPR compliance patterns - consent management, right to erasure, breach notification, audit logging, cookie consent, and data classification. author vibeeval author_url https://github.com/vibeeval/vibecosystem/tree/main/skills/kvkk-compliance license MIT version 0.1.0 execution_mode open jurisdiction cross-jurisdiction practice data-protection language en
KVKK & GDPR Compliance Patterns
Practical patterns for Turkish KVKK (Law No. 6698) and EU GDPR data protection compliance.
KVKK vs GDPR Comparison
Aspect KVKK (Turkey) GDPR (EU) Authority KVKK Board (Kisisel Verileri Koruma Kurumu) National DPAs + EDPB Consent Explicit, no pre-ticked boxes Freely given, specific, informed Breach notification "As soon as possible" to Board 72 hours to DPA DPO requirement VERBiS registration Mandatory for public bodies + large-scale Right to erasure Article 7 - withdrawal + deletion Article 17 - "Right to be forgotten" Data transfer abroad Board approval or adequate country Adequacy decision, SCCs, or BCRs Fines Up to ~2M TL per violation Up to 20M EUR or 4% global turnover Legal bases 5 in Article 5 + explicit consent 6 in Article 6 + explicit consent
Data Classification
enum DataCategory {
PERSONAL = 'personal' ,
SPECIAL = 'special_category' ,
ANONYMOUS = 'anonymous' ,
PSEUDONYMOUS = 'pseudonymous' ,
}
interface DataField {
name : string
category : DataCategory
retentionDays : number
:
:
}
: [] = [
{ : , : . , : , : , : },
{ : , : . , : , : , : },
{ : , : . , : , : , : },
]
requiresExplicitConsent
boolean
encryptAtRest
boolean
const
USER_DATA_FIELDS
DataField
name
'email'
category
DataCategory
PERSONAL
retentionDays
730
requiresExplicitConsent
false
encryptAtRest
false
name
'healthRecords'
category
DataCategory
SPECIAL
retentionDays
365
requiresExplicitConsent
true
encryptAtRest
true
name
'analyticsId'
category
DataCategory
PSEUDONYMOUS
retentionDays
365
requiresExplicitConsent
false
encryptAtRest
false
Consent Management
interface ConsentRecord {
userId : string ; purpose : string ; granted : boolean
timestamp : Date ; ipAddress : string ; version : string
}
const CONSENT_PURPOSES = [
{ id : 'essential' , label : 'Service operation' , required : true },
{ id : 'analytics' , label : 'Usage analytics' , required : false },
{ id : 'marketing' , label : 'Marketing emails' , required : false },
{ id : 'third_party' , label : 'Third-party sharing' , required : false },
] as const
async function recordConsent (userId : string , purposeId : string , granted : boolean , meta : { ip: string ; userAgent: string } ): Promise <ConsentRecord > {
return db.consentRecords .create ({
data : { userId, purpose : purposeId, granted, timestamp : new Date (), ipAddress : meta.ip , version : CURRENT_CONSENT_VERSION },
})
}
async function hasActiveConsent (userId : string , purposeId : string ): Promise <boolean > {
const latest = await db.consentRecords .findFirst ({
where : { userId, purpose : purposeId },
orderBy : { timestamp : 'desc' },
})
return latest?.granted === true
}
Right to Erasure (Soft Delete + Anonymization) const GRACE_PERIOD_DAYS = 30
async function requestAccountDeletion (userId : string ): Promise <void > {
await db.users .update ({ where : { id : userId }, data : { status : 'deletion_pending' , deactivatedAt : new Date () } })
await db.deletionRequests .create ({
data : { userId, requestedAt : new Date (), gracePeriodEndsAt : new Date (Date .now () + GRACE_PERIOD_DAYS * 86400000 ), status : 'pending' },
})
}
async function purgeExpiredAccounts ( ): Promise <void > {
const expired = await db.deletionRequests .findMany ({
where : { status : 'pending' , gracePeriodEndsAt : { lte : new Date () } },
})
for (const req of expired) {
await db.$transaction(async (tx) => {
await tx.users .update ({
where : { id : req.userId },
data : { email : `deleted-${req.userId} @anon.local` , fullName : 'Deleted User' , phone : null , address : null , status : 'deleted' },
})
await tx.consentRecords .updateMany ({
where : { userId : req.userId },
data : { userId : `deleted-${req.userId} ` , ipAddress : 'REDACTED' }
})
await tx.orders .updateMany ({ where : { userId : req.userId }, data : { userEmail : null , userName : 'Deleted User' } })
await tx.deletionRequests .update ({ where : { id : req.id }, data : { status : 'completed' , completedAt : new Date () } })
})
}
}
Cookie Consent Flow const COOKIE_CATEGORIES = {
necessary : { name : 'Strictly Necessary' , required : true },
functional : { name : 'Functional' , required : false },
analytics : { name : 'Analytics' , required : false },
marketing : { name : 'Marketing' , required : false },
} as const
type CookiePrefs = Record <keyof typeof COOKIE_CATEGORIES , boolean >
function applyCookiePreferences (prefs : CookiePrefs ): void {
initSessionCookies ()
prefs.analytics ? initGoogleAnalytics () : removeAnalyticsCookies ()
prefs.marketing ? initMarketingPixels () : removeMarketingCookies ()
document .cookie = `cookie_consent=${JSON .stringify(prefs)} ; path=/; max-age=${365 * 86400 } ; SameSite=Lax; Secure`
}
Data Breach Notification (72-Hour Rule) const NOTIFICATION_DEADLINE_HOURS = 72
async function reportBreach (breach : { detectedAt: Date ; severity: string ; affectedCount: number ; dataTypes: string []; description: string } ): Promise <void > {
const record = await db.dataBreaches .create ({ data : { ...breach, notifiedAuthorityAt : null , notifiedUsersAt : null } })
const deadline = new Date (breach.detectedAt .getTime () + NOTIFICATION_DEADLINE_HOURS * 3600000 )
await notifyDataProtectionAuthority ({ breachId : record.id , deadline, ...breach })
if (breach.severity === 'high' || breach.severity === 'critical' ) {
await notifyAffectedUsers (record.id )
}
}
Audit Logging (Who, What, When, Which Data) interface AuditLogEntry {
actorId : string ; actorRole : string
action : 'read' | 'create' | 'update' | 'delete' | 'export'
resourceType : string ; resourceId : string
fieldsAccessed : string []; ipAddress : string
justification ?: string
}
async function logDataAccess (entry : AuditLogEntry ): Promise <void > {
await db.$executeRaw `
INSERT INTO audit_logs (actor_id, actor_role, action, resource_type, resource_id, fields_accessed, ip_address, justification, timestamp)
VALUES (${entry.actorId} , ${entry.actorRole} , ${entry.action} , ${entry.resourceType} , ${entry.resourceId} , ${JSON .stringify(entry.fieldsAccessed)} , ${entry.ipAddress} , ${entry.justification || null } , NOW())
`
}
function auditMiddleware (resourceType : string ) {
return (req : Request , res : Response , next : NextFunction ) => {
const origJson = res.json .bind (res)
res.json = (body : unknown ) => {
const actionMap : Record <string , string > = {
GET : 'read' , POST : 'create' , PUT : 'update' , PATCH : 'update' , DELETE : 'delete'
}
logDataAccess ({
actorId : req.user ?.id || 'anon' ,
actorRole : req.user ?.role || 'unknown' ,
action : actionMap[req.method ] || 'read' ,
resourceType,
resourceId : req.params .id || 'list' ,
fieldsAccessed : Object .keys ((body as Record <string , unknown >) || {}),
ipAddress : req.ip || '' ,
}).catch (console .error )
return origJson (body)
}
next ()
}
}
Privacy Policy Checklist Controller identity [ ] Company name, address, contact, VERBiS number
Data collected [ ] Full list of categories with examples
Legal basis [ ] Purpose + legal basis for each activity
Retention periods [ ] How long each type is kept
Data subject rights [ ] Access, rectification, erasure, portability, objection
Consent withdrawal [ ] Clear opt-out instructions
Cookie policy [ ] Categories, purposes, opt-out
International transfer [ ] Countries, safeguards (SCCs, adequacy)
Third parties [ ] Processors and sub-processors
Automated decisions [ ] Profiling details, right to object
Breach procedure [ ] Notification timeline and method
DPO contact [ ] Data Protection Officer details
DPA Template Reference Every third-party processor needs a Data Processing Agreement with these clauses:
Subject & duration What data, how long, why
Processor obligations Process only on documented instructions
Sub-processors Prior written auth, flow-down obligations
Security measures Encryption, access controls, incident response
Audit rights Controller can inspect compliance
Data return/deletion Return or destroy data at contract end
Breach notification Notify controller without undue delay
International transfer SCCs if data leaves TR/EU
Contrast: GOOD vs BAD Consent
function BadForm ( ) {
return (
<form >
<label > <input type ="checkbox" /> I agree to privacy policy, marketing, tracking, and sharing.</label >
<button > Sign Up</button >
</form >
)
}
function GoodForm ( ) {
return (
<form >
<fieldset >
<legend > Data Processing Consent</legend >
<label > <input type ="checkbox" checked disabled /> Account operation (required)</label >
<label > <input type ="checkbox" name ="analytics" /> Usage analytics</label >
<label > <input type ="checkbox" name ="marketing" /> Marketing emails</label >
<label > <input type ="checkbox" name ="third_party" /> Partner sharing (<a href ="/privacy" > details</a > )</label >
</fieldset >
<p > Change preferences anytime in account settings.</p >
<button > Sign Up</button >
</form >
)
}
Core rule : Compliance is not a one-time feature. Build data protection into every flow, log every access, and assume regulators will ask "show me the evidence."