GDPR and Data Privacy Compliance for Web Applications | SoniNow Blog

Limited TimeLearn More

gdprprivacycompliancedata protectionlegal

GDPR and Data Privacy Compliance for Web Applications

Published

2026-06-23

Read Time

6 mins

GDPR and Data Privacy Compliance for Web Applications

The General Data Protection Regulation (GDPR) governs the processing of personal data for individuals in the European Union — regardless of where your application is based. Non-compliance can result in fines of up to €20 million or 4% of global annual turnover.

Consent Management Platform Integration

Under GDPR, consent must be freely given, specific, informed, and unambiguous. Pre-checked consent boxes are illegal. Implement a consent management platform that records granular user preferences and maintains an audit trail.

// Consent record structure
interface ConsentRecord {
  userId: string;
  timestamp: string;
  ipAddress: string;
  userAgent: string;
  consents: {
    necessary: true,  // Always required
    analytics: boolean,
    marketing: boolean,
    functional: boolean,
  };
  version: string;
  signature: string;  // HMAC for tamper evidence
}

// Consent banner logic
function getConsentStatus(userId: string): ConsentStatus {
  const record = await ConsentModel.findOne({ userId })
    .sort({ timestamp: -1 });

  if (!record) return { status: 'pending', version: CURRENT_VERSION };

  // Check if consent version matches current policy version
  if (record.version !== CURRENT_VERSION) return { status: 'update_needed' };
  // Check if consent is older than 6 months (requires renewal)
  if (Date.now() - new Date(record.timestamp).getTime() > 180 * 86400000) {
    return { status: 'expired' };
  }

  return { status: 'valid', consents: record.consents };
}

Store consent records as part of your audit trail — include timestamp, IP address, user agent, and the exact version of the privacy policy at the time of consent. Make it as easy to withdraw consent as it was to give it.

Data Subject Access Request (DSAR) Handling

Individuals have the right to access any personal data you hold about them within 30 days. Automate DSAR processing to meet this deadline efficiently.

// DSAR processing pipeline
async function processDSAR(userId: string): Promise<Buffer> {
  const user = await UserModel.findById(userId).lean();

  const personalData = {
    account: {
      email: user.email,
      name: user.name,
      createdAt: user.createdAt,
      lastLogin: user.lastLogin,
    },
    communications: await CommunicationModel.find({ userId }).lean(),
    orders: await OrderModel.find({ userId }).populate('items').lean(),
    analytics: await AnalyticsModel.find({ anonymousId: user.anonymousId })
      .select('pageViews sessions -_id').lean(),
    consentHistory: await ConsentModel.find({ userId }).lean(),
    supportTickets: await TicketModel.find({ userId }).lean(),
  };

  // Generate structured JSON export or CSV
  const exportData = anonymizeThirdPartyReferences(personalData);
  return await createEncryptedExport(exportData, user.email);
}

Implement a DSAR portal where users can initiate requests and track progress. For manual DSARs, maintain an internal SLA tracking system that escalates approaching the 30-day deadline. Redact or pseudonymize data that references other individuals.

Cookie Compliance

The ePrivacy Directive (Cookie Law) requires explicit consent for non-essential cookies — analytics, marketing, and personalization. Essential cookies (session, CSRF, load balancing) are exempt.

// Cookie categorization in consent banner
const COOKIE_LEGEND = {
  essential: {
    cookies: ['sid', 'csrf-token', 'locale'],
    purpose: 'Session management, security, user preferences',
    consent: 'required',
  },
  analytics: {
    cookies: ['_ga', '_gid', '_ga_*', 'cluid'],
    purpose: 'Site usage analytics, page views, navigation paths',
    consent: 'optional',
  },
  marketing: {
    cookies: ['_fbp', 'ads_prefs', 'tracking_id'],
    purpose: 'Personalized advertising, campaign attribution',
    consent: 'optional',
  },
};

// Conditionally load tracking scripts based on consent
function loadAnalytics(): void {
  if (getCookieConsent('analytics')) {
    // Load Google Analytics or Plausible
    initializeAnalytics();
  }
}

For EU visitors, block all non-essential cookies until explicit consent is given. Use a cookie scanner to document all cookies set by your application and third-party scripts. Re-run the scanner after any dependency update or third-party script addition.

Privacy Policy and Data Processing Records

Under GDPR's accountability principle, you must maintain records of processing activities (ROPA). Your privacy policy must specify:

  • The categories of personal data collected
  • The purposes of processing (legal basis)
  • Data retention periods
  • Third-party data processors and sub-processors
  • International data transfer mechanisms
  • Individual rights (access, rectification, erasure, portability)
# Record of Processing Activities (ROPA) entry
processing_activity:
  name: "User account management"
  data_categories:
    - identity: [name, email, phone]
    - technical: [ip_address, user_agent, browser_fingerprint]
    - usage: [login_timestamps, feature_usage]
  purposes:
    - "Service delivery and account management"
    - "Security and fraud prevention"
  legal_basis: "Contractual necessity (Art. 6(1)(b))"
  retention: "Account life + 90 days after deletion request"
  processors:
    - name: "Railway"
      purpose: "Hosting infrastructure"
      data_transfer: "Standard Contractual Clauses"
    - name: "PostHog"
      purpose: "Product analytics"
      data_transfer: "Adequacy decision (US Data Privacy Framework)"

Update the ROPA whenever you add a new data processing activity or engage a new processor. Link each processing activity to its legal basis and verify that consent or legitimate interest assessments are documented.

Data Minimization and Retention

Collect only the personal data you genuinely need. Define retention schedules for each data category and implement automated purging.

// Automated data retention enforcement
async function enforceRetentionPolicies(): Promise<void> {
  const now = new Date();

  // Delete raw analytics data older than 26 months
  await AnalyticsModel.deleteMany({
    createdAt: { $lt: new Date(now.getTime() - 26 * 30 * 86400000) },
  });

  // Anonymize support tickets after 3 years (keep aggregated metrics)
  await TicketModel.updateMany(
    { createdAt: { $lt: new Date(now.getTime() - 3 * 365 * 86400000) } },
    { $set: { userId: null, email: null, name: 'Anonymized' } }
  );

  // Permanently delete accounts with deletion requests older than 90 days
  const deletionCutoff = new Date(now.getTime() - 90 * 86400000);
  const requestsToExecute = await DeletionRequestModel.find({
    requestedAt: { $lt: deletionCutoff },
    status: 'pending',
  });

  for (const request of requestsToExecute) {
    await permanentlyDeleteUser(request.userId);
    request.status = 'completed';
    await request.save();
  }
}

Data Breach Notification Procedures

GDPR requires notification to supervisory authorities within 72 hours of becoming aware of a personal data breach. Maintain a documented breach response plan.

// Breach notification workflow
async function handleDataBreach(breach: DataBreachReport): Promise<void> {
  // 1. Contain the breach
  await containBreach(breach);

  // 2. Assess risk to data subjects
  const riskLevel = assessRisk(breach);

  // 3. Notify DPO and legal team
  await notifyInternal({
    severity: riskLevel,
    affectedRecords: breach.affectedUserIds.length,
    dataTypes: breach.dataCategories,
    timeElapsed: Date.now() - breach.detectedAt,
  });

  // 4. Notify supervisory authority (within 72 hours)
  if (riskLevel === 'high' || riskLevel === 'medium') {
    await notifySupervisoryAuthority({
      name: 'SoniNow',
      breachDescription: formatBreachDescription(breach),
      affectedCount: breach.affectedUserIds.length,
      likelyConsequences: assessConsequences(breach),
      mitigationMeasures: breach.mitigationSteps,
      dpoContact: '[email protected]',
    });
  }

  // 5. Notify affected data subjects
  if (riskLevel === 'high') {
    await notifyDataSubjects(breach);
  }

  // 6. Document the breach
  await BreachLogModel.create({
    ...breach,
    notifiedAuthority: true,
    notifiedSubjects: riskLevel === 'high',
    timestamp: new Date(),
  });
}

International Data Transfers

Following Schrems II and the EU-US Data Privacy Framework, document your transfer mechanisms for data leaving the EEA. For US-based processors, verify participation in the Data Privacy Framework. For other countries, implement Standard Contractual Clauses or Binding Corporate Rules.

GDPR compliance is an ongoing commitment, not a one-time project. Our <a href="/services/web-development">web development services</a> include privacy-by-design architecture, consent management implementation, and compliance documentation. Contact SoniNow to ensure your application meets GDPR requirements.