הטמעת יומן הסכמות — יומן הסכמות משתמש

כאשר הרגולטורים דורשים הוכחה להסכמת משתמשים, היעדר יומן מעקב מסכן את העסק שלכם בקנסות משמעותיים. אנו מיישמים Consent Log — יומן הסכמות בלתי ניתן לשינוי שמתעד כל פעולה ומספק API לניהול וייצוא נתונים. הצוות שלנו מטפל בכל התהליך: ביקורת, פיתוח, פריסה ותמיכה, ומספק פתרון אמין שגדל עם העסק שלכם.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
הטמעת יומן הסכמות — יומן הסכמות משתמש
בינוני
~2-3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1365
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113
  • פיתוח אתר עבור SBH Partners
    פיתוח אתר עבור SBH Partners
    1201
  • פיתוח אתר עבור Red Pear
    פיתוח אתר עבור Red Pear
    619

במהלך ביקורת ציות ל-GDPR בפורטל לקוחות, זיהינו היעדר יומן הסכמות בלתי ניתן לשינוי. הרגולטור דרש הוכחה—ללא יומן הסכמות החברה הסתכנה בקנס של עד 20 מיליון אירו או 4% מהמחזור השנתי. בקשה אופיינית: לספק היסטוריית שינויי הסכמות עבור כל משתמש ב-3 השנים האחרונות. ללא יומן, לא ניתן לעשות זאת—תצטרך להודות בהיעדר נתונים או לזייף רשומות. הפרקטיקה השיפוטית מאשרת שחברות ללא יומן הסכמות מפסידות בתיקים. פיתחנו פתרון שלא רק מתעד כל פעולת משתמש אלא גם מספק API לניהול וייצוא נתונים. הניסיון שלנו: מעל 30 פרויקטים שבהם יומן ההסכמות הפך לבסיס לביטחון משפטי. לפי GDPR (https://en.wikipedia.org/wiki/General_Data_Protection_Regulation), יש לקבל הסכמה באופן חוקי ומוכח. יומן הסכמות הוא הדרך היחידה להבטיח ביקורת שקופה. רגולטורים מטילים קנסות של מיליארדי אירו בשנה על הפרות כאלה.

מה צריך להכיל יומן הסכמות?

GDPR דורש תיעוד של ההקשר של כל אירוע:

  • חותמת זמן של ההסכמה
  • מי נתן הסכמה (משתמש או מזהה אנונימי)
  • למה בדיוק ניתנה הסכמה (קטגוריות ספציפיות: אנליטיקה, שיווק וכו')
  • גרסת המסמך שהמשתמש עיין בה
  • שיטת קבלת ההסכמה (באנר, תיבת סימון, API)
  • כתובת IP ו-user-agent לצורך קביעת סמכות שיפוט
מאפיין ללא יומן עם יומן הסכמות
יכולת להוכיח שהתקבלה הסכמה לא כן, עד לשנייה
זמן תגובה ל-DSAR 5–7 ימים של איסוף ידני 5 דקות דרך API
עלות עיבוד בקשה אחת ל-DSAR עד 2000 אירו זניחה
סיכון לקנס בשל חוסר הוכחה גבוה (עד 20 מיליון אירו) ממוזער

סכמת מסד נתונים

CREATE TABLE consent_events (
    id BIGSERIAL PRIMARY KEY, -- Идентификация
    user_id BIGINT REFERENCES users(id) ON DELETE SET NULL,
    anonymous_id UUID, -- для неавторизованных
    session_id VARCHAR(100),
    -- Данные согласия
    event_type VARCHAR(20) NOT NULL, -- 'granted', 'denied', 'withdrawn', 'updated'
    categories JSONB NOT NULL, -- {"analytics": true, "marketing": false, ...}
    document_version VARCHAR(20), -- версия Privacy Policy
    method VARCHAR(30), -- 'banner', 'settings_page', 'api', 'import'
    -- Контекст
    ip_address INET,
    user_agent TEXT,
    country_code CHAR(2),
    language_code CHAR(5),
    -- Аудит
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    -- Запрет обновления строк (immutable audit log)
    updated_at TIMESTAMPTZ,
    CONSTRAINT no_updates CHECK (updated_at IS NULL)
);
-- Индексы для быстрого поиска
CREATE INDEX idx_consent_user ON consent_events(user_id) WHERE user_id IS NOT NULL;
CREATE INDEX idx_consent_anon ON consent_events(anonymous_id) WHERE anonymous_id IS NOT NULL;
CREATE INDEX idx_consent_date ON consent_events(created_at);
CREATE INDEX idx_consent_type ON consent_events(event_type);

איך ליישם יומן הסכמות בלתי ניתן לשינוי?

אנו משתמשים בשילוב של אילוצי SQL וארכיטקטורה שמונעת עדכון רשומות. בנוסף, אנו יכולים להוסיף hash של השורה הקודמת לשרשרת—גישת בלוקצ'יין ללא בלוקצ'יין. תוצאה: ביטחון שהיומן לא נפגם. לחיפושים מהירים—אינדקסים על user_id ו-anonymous_id. כל הקוד מכוסה בבדיקות אי-שינוי.

אירוע: משתמש נותן הסכמה לאנליטיקה ושיווק דרך באנר. הטבלה מקבלת: חותמת זמן, user_id (או anonymous_id), קטגוריות CREATE TABLE consent_events ( id BIGSERIAL PRIMARY KEY, -- Идентификация user_id BIGINT REFERENCES users(id) ON DELETE SET NULL, anonymous_id UUID, -- для неавторизованных session_id VARCHAR(100), -- Данные согласия event_type VARCHAR(20) NOT NULL, -- 'granted', 'denied', 'withdrawn', 'updated' categories JSONB NOT NULL, -- {"analytics": true, "marketing": false, ...} document_version VARCHAR(20), -- версия Privacy Policy method VARCHAR(30), -- 'banner', 'settings_page', 'api', 'import' -- Контекст ip_address INET, user_agent TEXT, country_code CHAR(2), language_code CHAR(5), -- Аудит created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- Запрет обновления строк (immutable audit log) updated_at TIMESTAMPTZ, CONSTRAINT no_updates CHECK (updated_at IS NULL) ); -- Индексы для быстрого поиска CREATE INDEX idx_consent_user ON consent_events(user_id) WHERE user_id IS NOT NULL; CREATE INDEX idx_consent_anon ON consent_events(anonymous_id) WHERE anonymous_id IS NOT NULL; CREATE INDEX idx_consent_date ON consent_events(created_at); CREATE INDEX idx_consent_type ON consent_events(event_type); , גרסה "v2.1", שיטה "באנר", IP מגרמניה, user-agent של Chrome על Windows. כל השורות רק מוכנסות, לעולם לא מעודכנות.

תיעוד הסכמות

import uuid
from datetime import datetime
import hashlib

class ConsentLogger:
    def __init__(self, db, geoip):
        self.db = db
        self.geoip = geoip

    def log(self, request, categories: dict, event_type: str, user_id=None, document_version='v1.0'):
        # Определить анонимный идентификатор
        anonymous_id = self._get_or_create_anonymous_id(request)
        country = self.geoip.country(request.remote_addr)
        self.db.execute("""
            INSERT INTO consent_events (user_id, anonymous_id, session_id, event_type, categories, document_version, method, ip_address, user_agent, country_code, created_at)
            VALUES (%s, %s, %s, %s, %s::jsonb, %s, %s, %s, %s, %s, %s)
        """, (
            user_id,
            anonymous_id,
            request.session.get('id'),
            event_type,
            json.dumps(categories),
            document_version,
            'banner',
            request.remote_addr,
            request.user_agent.string[:500],
            country,
            datetime.utcnow()
        ))

    def _get_or_create_anonymous_id(self, request):
        cookie_id = request.cookies.get('consent_id')
        if cookie_id:
            return cookie_id
        return str(uuid.uuid4())

    def get_user_consent_history(self, user_id: int):
        return self.db.query("""
            SELECT event_type, categories, document_version, created_at, ip_address
            FROM consent_events
            WHERE user_id = %s
            ORDER BY created_at DESC
        """, (user_id,))

    def get_current_consent(self, user_id: int) -> dict:
        """Актуальное согласие пользователя"""
        latest = self.db.query_one("""
            SELECT categories
            FROM consent_events
            WHERE user_id = %s AND event_type IN ('granted', 'updated')
            ORDER BY created_at DESC
            LIMIT 1
        """, (user_id,))
        return latest['categories'] if latest else {}

API לניהול הסכמות

@app.route('/api/my/consent', methods=['GET'])
@login_required
def get_my_consent():
    """Текущее согласие пользователя"""
    current = consent_logger.get_current_consent(current_user.id)
    history = consent_logger.get_user_consent_history(current_user.id)
    return jsonify({
        'current': current,
        'history': [{
            'event': r['event_type'],
            'categories': r['categories'],
            'version': r['document_version'],
            'date': r['created_at'].isoformat(),
        } for r in history[:10]]
    })

@app.route('/api/my/consent', methods=['DELETE'])
@login_required
def withdraw_consent():
    """Отзыв согласия на маркетинговую обработку"""
    consent_logger.log(
        request,
        categories={'analytics': False, 'marketing': False, 'preferences': False},
        event_type='withdrawn',
        user_id=current_user.id
    )
    # Удалить данные из маркетинговых систем
    revoke_from_mailchimp(current_user.email)
    revoke_from_facebook_custom_audience(current_user.email)
    return jsonify({'status': 'withdrawn'})

ייצוא לרגולטור

def export_consent_for_user(user_id: int) -> dict:
    """Отчёт для ответа на запрос регулятора или DSAR"""
    records = db.query("""
        SELECT * FROM consent_events
        WHERE user_id = %s
        ORDER BY created_at
    """, (user_id,))
    return {
        'user_id': user_id,
        'consent_history': [{
            'timestamp': r['created_at'].isoformat(),
            'event': r['event_type'],
            'categories': r['categories'],
            'document_version': r['document_version'],
            'ip': str(r['ip_address']),
            'method': r['method']
        } for r in records],
        'exported_at': datetime.utcnow().isoformat(),
        'format_version': '1.0'
    }

ייצוא דרך API מקצר את זמן התגובה ל-DSAR מ-5 ימים ל-5 דקות—פי 1440 מהר יותר מאיסוף ידני.

תהליך היישום ולוח זמנים

  1. ניתוח—אנו בוחנים את מערכת ההסכמות הקיימת ומזהים פערים.
  2. עיצוב—סכמת מסד נתונים, API, פורמטי ייצוא.
  3. יישום—כתיבת קוד, מיגרציות, הגדרת אינדקסים.
  4. בדיקות—בדיקות יחידה, בדיקות אי-שינוי אינטגרטיביות, עומס עד 1000 בקשות/שנייה.
  5. פריסה—פריסה לסביבת ייצור, ייעוץ לצוות.

יישום מפתח—2 עד 3 ימי עבודה. אינטגרציה עם מערכות legacy מורכבות עשויה להאריך ל-5 ימים. השלמנו מעל 30 פרויקטים של יומן הסכמות ב-6 שנות עבודה—הניסיון המצטבר עוזר להימנע מטעויות אופייניות.

מה כלול בעבודה

  • קוד מודול יומן ההסכמות ב-Python/Django או Node.js
  • מיגרציות SQL ליצירת טבלת {"analytics": true, "marketing": true} ואינדקסים
  • REST API לניהול הסכמות (נוכחית, ביטול, היסטוריה)
  • ייצוא נתונים ל-DSAR בפורמט JSON, מוכן לשליחה לרגולטור
  • הוראות לאינטגרציה בחזית (באנר הסכמות, דף הגדרות)
  • בדיקות עומס: עד 1000 בקשות בשנייה
  • ייעוץ משפטי (אילו קטגוריות לתעד, תקופת שמירה—בדרך כלל 3 שנים)
שלב מה אנו עושים תוצאה
ניתוח ביקורת זרימת ההסכמות הנוכחית, איתור נקודות תורפה דוח עם המלצות
עיצוב סכמה import uuid from datetime import datetime import hashlib class ConsentLogger: def __init__(self, db, geoip): self.db = db self.geoip = geoip def log(self, request, categories: dict, event_type: str, user_id=None, document_version='v1.0'): # Определить анонимный идентификатор anonymous_id = self._get_or_create_anonymous_id(request) country = self.geoip.country(request.remote_addr) self.db.execute(""" INSERT INTO consent_events (user_id, anonymous_id, session_id, event_type, categories, document_version, method, ip_address, user_agent, country_code, created_at) VALUES (%s, %s, %s, %s, %s::jsonb, %s, %s, %s, %s, %s, %s) """, ( user_id, anonymous_id, request.session.get('id'), event_type, json.dumps(categories), document_version, 'banner', request.remote_addr, request.user_agent.string[:500], country, datetime.utcnow() )) def _get_or_create_anonymous_id(self, request): cookie_id = request.cookies.get('consent_id') if cookie_id: return cookie_id return str(uuid.uuid4()) def get_user_consent_history(self, user_id: int): return self.db.query(""" SELECT event_type, categories, document_version, created_at, ip_address FROM consent_events WHERE user_id = %s ORDER BY created_at DESC """, (user_id,)) def get_current_consent(self, user_id: int) -> dict: """Актуальное согласие пользователя""" latest = self.db.query_one(""" SELECT categories FROM consent_events WHERE user_id = %s AND event_type IN ('granted', 'updated') ORDER BY created_at DESC LIMIT 1 """, (user_id,)) return latest['categories'] if latest else {} , אינדקסים, ארכיטקטורת API תיעוד סכמה
יישום כתיבת @app.route('/api/my/consent', methods=['GET']) @login_required def get_my_consent(): """Текущее согласие пользователя""" current = consent_logger.get_current_consent(current_user.id) history = consent_logger.get_user_consent_history(current_user.id) return jsonify({ 'current': current, 'history': [{ 'event': r['event_type'], 'categories': r['categories'], 'version': r['document_version'], 'date': r['created_at'].isoformat(), } for r in history[:10]] }) @app.route('/api/my/consent', methods=['DELETE']) @login_required def withdraw_consent(): """Отзыв согласия на маркетинговую обработку""" consent_logger.log( request, categories={'analytics': False, 'marketing': False, 'preferences': False}, event_type='withdrawn', user_id=current_user.id ) # Удалить данные из маркетинговых систем revoke_from_mailchimp(current_user.email) revoke_from_facebook_custom_audience(current_user.email) return jsonify({'status': 'withdrawn'}) , נקודות קצה REST קוד עובד
בדיקות בדיקת אי-שינוי, בדיקות עומס 100% מעבר בדיקות
פריסה פריסה, ניטור רץ בסביבת ייצור

טעויות אופייניות ביישום יומן הסכמות

  • שמירת הסכמה נוכחית בלבד, ללא היסטוריית שינויים—אינו עומד בדרישות GDPR.
  • שימוש ב-UPDATE במקום INSERT—היומן הופך לניתן לכתיבה מחדש.
  • חוסר ב-anonymous_id למשתמשים לא מורשים—אי אפשר לשייך אירועים.
  • נתוני הקשר חסרים (IP, user-agent, שפה)—הרגולטור עשוי לדרוש אותם.
  • ייצוא DSAR לא מוגדר—יש לכתוב אותו תוך כדי תנועה בעת בקשה.

אנו מבטיחים שיישום יומן ההסכמות שלך יעמוד ברוחה ובאותה של GDPR. צור קשר להערכה חינמית של הפרויקט שלך. הזמן את היישום—קבל פתרון מוכן תוך מספר ימים.