Implementation of Regional Legal Documents (Privacy Policy by Country)
A site operating in multiple jurisdictions must provide legal documents in compliance with local legislation. GDPR in EU, CCPA in California, 152-FL in Russia, PIPEDA in Canada — requirements differ, documents differ.
User Jurisdiction Detection
class UserJurisdiction
{
public function detect(Request $request): string
{
// First check explicit user choice (cookie)
if ($country = $request->cookie('user_country')) {
return $country;
}
// Geolocation by IP via MaxMind GeoIP2
$reader = new \GeoIp2\Database\Reader(storage_path('geoip/GeoLite2-Country.mmdb'));
$record = $reader->country($request->ip());
$isoCode = $record->country->isoCode;
return $isoCode ?? 'DEFAULT';
}
public function getRegulation(string $countryCode): string
{
return match(true) {
in_array($countryCode, EU_COUNTRIES) => 'gdpr',
$countryCode === 'US' => 'ccpa',
$countryCode === 'RU' => 'rfz152',
in_array($countryCode, ['UA', 'BY', 'KZ']) => 'cis',
default => 'default',
};
}
}
Document Structure
resources/legal/
├── privacy-policy/
│ ├── gdpr.{en,ru,de}.md
│ ├── ccpa.en.md
│ ├── rfz152.ru.md
│ └── default.{en,ru}.md
├── cookie-policy/
│ └── ...
└── terms-of-service/
└── ...
Routing and Display
Route::get('/legal/privacy-policy', function (Request $request) {
$jurisdiction = app(UserJurisdiction::class)->detect($request);
$regulation = app(UserJurisdiction::class)->getRegulation($jurisdiction);
$locale = app()->getLocale();
$document = LegalDocument::where([
'type' => 'privacy-policy',
'regulation' => $regulation,
'locale' => $locale,
])->first()
?? LegalDocument::where([
'type' => 'privacy-policy',
'regulation' => 'default',
'locale' => $locale,
])->first();
return view('legal.document', ['document' => $document, 'regulation' => $regulation]);
});
Document Versioning
CREATE TABLE legal_documents (
id BIGSERIAL PRIMARY KEY,
type TEXT, -- privacy-policy, terms, cookie-policy
regulation TEXT, -- gdpr, ccpa, rfz152, default
locale CHAR(2),
version TEXT, -- 2.3.1
content TEXT,
effective_at DATE,
is_current BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ DEFAULT NOW()
);
When updating document — new record with effective_at in future. Automatically switches to new version on effective date.
Consent and Storage
Users from EU (GDPR) must explicitly accept documents. Storage:
UserConsent::create([
'user_id' => auth()->id(),
'document_id' => $document->id,
'ip_address' => request()->ip(),
'user_agent' => request()->userAgent(),
'accepted_at' => now(),
]);
Timeline
Regional documents system with jurisdiction detection and versioning: 4–6 business days.







