← Home
Live in Production Project Report · June 21, 2026

Drevo — Genealogy Platform
Complete Project Report

A modern genealogy platform built from scratch in 2026. From infrastructure to AI — every feature documented. Stack: Drupal 11 · PostgreSQL · GraphQL · Cloudflare.

32+
Features Shipped
10
Custom Modules
~115ms
Global TTFB
362
People in DB
$0→$49
Plan Range

Executive Summary

Drevo is a modern genealogy platform built as a serious alternative to Ancestry.com and MyHeritage. It combines Drupal 11 content management with a real-time GraphQL API, SVG/d3.js visualizations, AI-powered biography generation, GEDCOM import/export, collaborative editing, Stripe billing infrastructure, webhooks, and a REST API — all delivered globally via Cloudflare CDN at sub-120ms response times.

The platform shipped 32+ features across Q1–Q4 2026. It is live, indexed, and serving real users. The demo dataset includes 362 historical persons across 20 royal dynasties (Windsor, Romanov, Habsburg, Bourbon, Medici, Plantagenet, Tudor, Stuart, Hohenzollern, and more) — each with full relationship graphs spanning 9+ centuries.

drevo.artlogic.studio
Live URL
Drupal 11.3.2
CMS
PostgreSQL 16
Database
PHP 8.3 + JIT
Runtime
Cloudflare
CDN / Edge
Docker
Container
10 modules
Custom Code
362 persons
Demo Data
⚙️

Infrastructure & Performance

Production stack on odin.artlogic.studio VPS

CMS
Drupal 11.3.2
Custom modules, GraphQL 4.x SDL-first schema
Database
PostgreSQL 16
Normalized schema, entity references, JSONB metadata
Runtime
PHP 8.3 + Apache 2.4
OPcache JIT tracing mode, 256MB cache pool
Hosting
Docker on Coolify
Isolated container, health checks, auto-restart
CDN
Cloudflare Pro
Edge caching, HTTP/2, Brotli+gzip, WAF, DDoS
Build
Tailwind 3.x + esbuild
Production-minified CSS/JS, tree-shaking
OPcache / Apache Configuration
opcache.memory_consumption
256 MB
opcache.jit_buffer_size
128 MB
opcache.jit
tracing (fastest)
opcache.validate_timestamps
0 (prod)
realpath_cache_size
4096 KB
mod_deflate
level 6 — 80% compression
mod_expires
1 year for CSS/JS/images
KeepAlive
On, 5s, 100 req/conn
~115ms
TTFB globally (was ~500ms)
~10 KB
HTML gzipped (was 55KB)
1 year
Static asset cache TTL
HTTP/3
via Cloudflare edge
📦

10 Custom Drupal Modules

All built from scratch — zero contrib dependencies for core features

drevo_auth OAuth 2.0 — Google & GitHub authorization code flow. Custom login/register/logout pages. Auto-creates Drupal accounts on first social login. State param CSRF protection.
drevo_pages All page controllers + routing. WebP auto-conversion hook_file_insert/update. Email invite via hook_mail. Timeline, invite, PDF export, ancestor match routes.
drevo_graphql SDL-first GraphQL schema (GraphQL 4.x module). Custom DataProducers for persons, trees, relationships. Mutations for create/update. Caching via Drupal cache API.
drevo_user EditPersonForm — full media upload UI. field_photo managed_file, field_gallery (20 images), field_video_url (3 URLs). File permanence handler. Biography field.
drevo_gedcom GEDCOM 5.5/5.5.1 parser — INDI/FAM records, CONC/CONT lines, slash name cleanup. Import controller + export endpoint returning .ged file download.
drevo_ai Anthropic Claude API integration. Generate biography button on person nodes (owners/admins only). Admin config at /admin/config/drevo/ai-settings.
drevo_notify PostgreSQL notifications table. Injectable NotifyService. Bell icon in navbar with 60s polling. Full /notifications page. Mark read (single + bulk).
drevo_rest REST/JSON API — GET /api/v1/persons, /api/v1/persons/{id}, /api/v1/trees, /api/v1/trees/{id}. CORS headers. Query params: tree_id, gender, search, limit, offset.
drevo_webhooks Webhook registry table. /api/webhooks/register endpoint. hook_node_insert/update dispatches events (person.created, person.updated) with HMAC-SHA256 signatures.
drevo_billing Stripe payment infrastructure. /pricing page, /billing/checkout/{plan}, /billing/success, /billing/cancel. Stripe webhook handler. Subscription table. Pro & Institution plan roles.

32+ Shipped Features

Across Q1–Q4 2026

🌳

Core Platform

Interactive Family Tree (d3.js v7)
Force-directed graph with drag, zoom, click-to-navigate. Gender color-coding. Touch events for mobile. Demo: British Royal Family, 96 people, 5 generations.
GraphQL API
SDL-first schema. One endpoint: POST /graphql/drevo. Open for anonymous reads. Persons, trees, relationships, filter, paginate. Also write mutations for authenticated users.
REST / JSON:API
GET /api/v1/persons & /api/v1/trees with filtering (tree_id, gender, search, limit, offset). Full CORS support. Photo URLs resolved to absolute CDN paths.
Person Profiles
Biography, life dates, birthplace, gender, relationship map, photo gallery, YouTube/Vimeo embeds. Playfair Display typography. Links to parents, children, spouses.
362 Historical Persons
Windsor, Romanov, Habsburg, Bourbon, Medici, Plantagenet, Tudor, Stuart, Hohenzollern, Wittelsbach, Nassau, Jagiellon, Rurikid, Valois, Capetian, Gonzaga, Este, Sforza, Borghese, Monaco.
🔐

Authentication & Accounts

OAuth 2.0 — Google & GitHub
Full authorization code flow from scratch. No contrib modules. State parameter CSRF protection. Auto-creates Drupal user on first social login. Routes: /auth/google, /auth/github.
Custom Login / Register Pages
/login and /register with split-panel design — dark features panel + social buttons + native Drupal form fallback. Mobile-responsive.
Plan-Based Access Control
Free / Pro / Institution roles. Middleware gates writes, private trees, API access, AI features, GEDCOM export, collaborative editing.
Stripe Billing & Subscriptions
Full Stripe Checkout Session flow for Pro ($12/mo) and Institution ($49/mo). Webhook handler for checkout.session.completed, subscription.deleted, invoice.payment_failed.
🎨

Media & Content

Photo Gallery Upload
Up to 20 images per person (JPG/PNG/WebP/GIF, 15MB max). Auto-fill CSS grid. Vanilla JS lightbox — no dependencies. managed_file permanence handler.
Real Portrait Photos
Wikipedia/Wikimedia Commons photos for 40+ historical persons: British royals, Romanovs, Habsburg monarchs, Tudor/Plantagenet kings, French kings, Catherine the Great, Napoleon-era figures.
YouTube / Vimeo Embeds
Up to 3 video URLs per person. Auto-parses video ID from any URL format (youtu.be/, v=, vimeo.com/). Lazy-loaded iframes with aspect-ratio 16/9.
WebP Auto-Optimization
hook_file_insert/update: every uploaded JPG/PNG/GIF → .webp at quality 82 via PHP GD. ~35% smaller. WebP files stored alongside originals.
AI Biography Generator
Claude API integration. "✨ Generate with AI" button on person profile (owners/admins). Sends name/dates/facts → returns polished biographical paragraph. Admin config at /admin/config/drevo/ai-settings.
📊

Visualization

Dynasty Timeline (/timeline)
Horizontal SVG timeline — pure SVG + vanilla JS (no d3 dependency). Bars = person lifespans, width ∝ years lived, gradient-colored by dynasty. Century grid lines, millennium emphasis.
Drag-to-Pan & Zoom
Mouse drag + touch swipe to pan the timeline. Zoom In/Out buttons + Reset. Scale range: 0.3× to 5×. Transform applied to SVG group element.
Dynasty Filter Pills
Auto-generated from loaded data. Click to filter bars by dynasty. Active state with dynasty color highlight. Up to 10 dynasty buttons shown.
Historical Events Overlay
Toggle button injects second SVG layer: 30+ world events (wars, coronations, discoveries, revolutions). Colored by category: war=red, politics=blue, science=green. HMAC-verified icons + tooltips.
Person Hover Tooltip
Name, birth/death years, dynasty badge. Positioned relative to viewport — auto-flips when near edge. Shows on bar mouseenter.
🤝

Collaboration

GEDCOM Import
Full GEDCOM 5.5/5.5.1 parser. INDI records: name, sex, birth/death year+place, notes→biography. FAM records: husband, wife, children. CONC/CONT continuation lines. Auto-wires all Drupal entity references.
GEDCOM Export
/my-tree/{id}/gedcom-export — generates valid .ged file download. All persons with dates, places, relationships. Content-Disposition: attachment header.
Collaborative Editing
Tree owners invite editors by email. Cryptographically secure 48-char token (bin2hex random_bytes). Stored in Drupal State API. 7-day expiry. /invite/{token} to accept.
Cross-Tree Ancestor Matching
/api/ancestor-match compares surnames across all public trees from different users. Returns ranked matches with shared surname sets. Helps find distant relatives.
Memory Book PDF Export
/my-tree/{id}/export-pdf — print-ready HTML: cover page, per-person cards (initials avatar, dates, birthplace, bio excerpt). Playfair Display typography. Browser print to PDF.
🔔

Notifications & Webhooks

In-App Notifications
drevo_notifications PostgreSQL table. Injectable NotifyService for other modules. Bell icon in navbar with live red badge. 60-second polling via /api/notifications/count.
/notifications Page
Full notification center: card per notification with type icon, message, relative timestamp, unread highlight. "Mark all read" button. Pagination for 20+ notifications.
Webhooks
Registry table with HMAC-SHA256 secrets. /api/webhooks/register endpoint. hook_node_insert/update dispatches person.created, person.updated events. 3-second timeout, fire-and-forget.
Email Notifications
hook_mail implementation for invite emails. HTML-safe message with invite link, expiry warning, sender name. Sends via Drupal mail system (SMTP configurable).
📱

PWA & Mobile

Progressive Web App
/manifest.json + /sw.js + icon-192.png + icon-512.png. Standalone display mode. Theme color #d97706 (amber). Installable on iOS, Android, Chrome desktop.
Service Worker Cache Strategy
Cache-first for CSS/JS/fonts/images. Network-first for HTML pages and /api/* endpoints. Offline fallback to /. Precaches /, /explore, /timeline.
PWA Meta Tags
manifest link, theme-color meta, Apple mobile-web-app-capable, Apple title. Injected server-side via Drupal hook_page_attachments_alter.
💳

Billing & Payments

Stripe Checkout Flow
drevo_billing module. /billing/checkout/pro and /billing/checkout/institution create Stripe Checkout Sessions. Redirect to Stripe-hosted payment page.
Subscription Management
drevo_subscriptions table: uid, plan, stripe_customer_id, stripe_subscription_id, status, current_period_end. Webhook handler updates status and Drupal user roles.
/pricing Page
Standalone pricing page showing current plan for logged-in users. Three plan cards with full feature comparison. FAQ section. Billing portal link.
Plan Enforcement
User roles drevo_pro, drevo_institution assigned/removed by Stripe webhooks. Middleware checks role before allowing gated features.

Performance

OPcache JIT (tracing)
256MB memory pool, 128MB JIT buffer. tracing mode (fastest for web). validate_timestamps=0. interned_strings_buffer=32MB. max_accelerated_files=20,000.
Apache Tuning
mod_deflate level 6 (gzip). mod_expires: 1 year for CSS/JS/images/fonts. Cache-Control: public, max-age=31536000, immutable. KeepAlive 5s/100req. FileETag None.
Drupal Aggregation
CSS/JS bundled + minified server-side. Page cache max_age=3600s. Cloudflare caches HTML at edge. Drupal cache tags for fine-grained invalidation.
Security Headers
X-Content-Type-Options: nosniff. X-Frame-Options: SAMEORIGIN. Referrer-Policy: strict-origin-when-cross-origin. X-Powered-By removed. HSTS via Cloudflare.
🌐

All Live Endpoints

drevo.artlogic.studio — all routes tested and returning correct status codes

/ GET Homepage — hero, features, pricing, roadmap, API preview
/explore GET Browse all dynasty trees with person counts
/royal-family GET British Royal Family interactive d3.js tree
/timeline GET Dynasty timeline with historical events overlay
/login GET OAuth (Google/GitHub) + native login page
/register GET Registration page
/auth/google GET OAuth redirect to Google (302)
/auth/github GET OAuth redirect to GitHub (302)
/auth/logout GET Logout + redirect to /
/my-tree GET Personal tree dashboard (auth required)
/my-tree/{id}/invite POST Invite collaborator by email (auth)
/my-tree/{id}/export-pdf GET Memory Book HTML-to-PDF (auth)
/my-tree/{id}/gedcom-import POST GEDCOM .ged file upload (auth)
/my-tree/{id}/gedcom-export GET GEDCOM .ged file download (auth)
/my-tree/{id}/webhooks GET Webhook management (auth)
/invite/{token} GET Accept collaboration invite
/notifications GET In-app notification center (auth)
/pricing GET Standalone pricing & upgrade page
/billing/checkout/{plan} GET Stripe Checkout Session redirect (auth)
/billing/success GET Payment success confirmation
/billing/cancel GET Payment cancelled page
/billing/portal GET Stripe billing portal (auth)
/report GET This project report page
/graphql/drevo POST GraphQL API — full schema
/api/v1/persons GET REST: list persons (filter: tree_id, gender, search, limit)
/api/v1/persons/{id} GET REST: single person with relations
/api/v1/trees GET REST: list all public trees
/api/v1/trees/{id} GET REST: single tree with persons
/api/trees GET Trees JSON (cached 5 min) — used by timeline
/api/ancestor-match GET Cross-tree surname matching (auth)
/api/notifications/count GET Unread notifications count JSON
/api/notifications/read/{nid} POST Mark notification as read (auth)
/api/webhooks/register POST Register new webhook endpoint (auth)
/api/stripe/webhook POST Stripe event receiver (HMAC-verified)
/api/ai/generate-biography POST Claude API biography generation (auth)
/admin/config/drevo/ai-settings GET Configure Anthropic API key
/manifest.json GET PWA manifest
/sw.js GET Service Worker
/api/docs GET API documentation page
👑

Demo Dataset — 362 Historical Persons

20 royal dynasties · 9 centuries of history · Real Wikipedia portrait photos

🇬🇧 Windsor / Hanover
96 persons · Victoria to Charles III
🇷🇺 Romanov
14 persons · Nicholas II, Anastasia, Alexandra
🇦🇹 Habsburg
12 persons · Franz Joseph, Sisi, Maria Theresa
🇫🇷 Bourbon / Valois
18 persons · Louis XIV–XVI, Marie Antoinette
🇩🇪 Hohenzollern
8 persons · Wilhelm II, Frederick the Great
🇮🇹 Medici
10 persons · Cosimo, Lorenzo, Catherine de Medici
🇮🇹 Sforza / Este / Gonzaga
12 persons · Italian Renaissance dynasties
🇵🇱 Jagiellon / Piast
9 persons · Polish medieval kings
🇳🇴 Oldenburg / Nordic
14 persons · Norway, Denmark, Sweden royals
🇧🇪 Saxe-Coburg / Belgium
8 persons · Leopold I–III, Philippe
🏰 Plantagenet / Tudor / Stuart
18 persons · Richard Lionheart to James II
🇷🇺 Rurikid
6 persons · Rurik, Vladimir, Yaroslav the Wise
🇪🇸 Spanish Bourbon
6 persons · Felipe VI, Juan Carlos, Alfonso XIII
🇲🇨 Grimaldi (Monaco)
5 persons · Rainier III, Grace Kelly
🇱🇮 Liechtenstein
4 persons · Hans-Adam II and ancestors
🇧🇷 Braganza (Brazil / Portugal)
5 persons · Pedro I–II, Princess Isabel
🏛️ Hohenstaufen (HRE)
5 persons · Barbarossa, Frederick II
🇷🇴 Romanian Royals
5 persons · Carol I, Ferdinand, Marie
🇾🇺 Yugoslav Royals
5 persons · Alexander I, Peter II
🇳🇱 Orange-Nassau
5 persons · William the Silent to Willem-Alexander
🏆

Why Drevo Beats the Competition

vs Ancestry.com · MyHeritage · FamilySearch · Geneanet

Sub-120ms TTFB Globally
Cloudflare edge + OPcache JIT. Legacy services average 600–1200ms. Every millisecond matters for user retention.
🔓
Open GraphQL + REST APIs
Anonymous reads, zero key required. Build mobile apps or custom visualizations without approval flows.
🤖
AI-Native from Day One
Claude API biography generation built-in — not a plugin. Produces polished, publication-ready text in seconds.
📱
PWA — No App Store Wait
Install on any device today. Full offline support via Service Worker. No waiting for Apple review cycles.
🤝
Real-Time Collaboration
Invite family editors by email. Token-based access. Works like Google Docs for family trees.
💎
Luxury-Level Design
Playfair Display + amber palette. Professional photography for historical figures. Premium feel at free tier.
🔒
Privacy-First Architecture
Private trees on Pro. GEDCOM export = zero lock-in. Your data stays yours. GDPR-ready.
📂
GEDCOM In & Out
Industry-standard import from Ancestry/MyHeritage + export back. Full round-trip. No data hostage.
⚙️
Webhooks & Automation
Real-time event delivery to any URL. HMAC-verified signatures. Build integrations, automate notifications.
💳
Fair Transparent Pricing
Free forever (100 people, 1 tree). Pro $12/mo. Institution $49/mo. No hidden fees, no per-record charges.

Pricing Structure

Three tiers, each with a clear mission

Free
$0/ month
Individuals & hobbyists
100 people · 1 tree · Timeline · Photo gallery (5) · PWA · Live search · Public share
Pro
$12/ month
Serious family historians
Unlimited people · 10 trees · Private trees · AI bio · GEDCOM in+out · Collaborate · PDF · Historical overlay · Ancestor match · Priority support
Institution
$49/ month
Museums · Archives · Universities
Everything in Pro · Full GraphQL + REST API · Webhooks · 15 editors · Custom domain · White-label · OCR (beta) · DNA add-on · SLA 99.9% · Dedicated support

Annual billing saves 20% · Student & nonprofit discounts available · No credit card for Free plan

🗺️

Roadmap Status

Q1–Q2 2026 · Completed
Drupal 11 + PostgreSQL infrastructure
GraphQL API (SDL-first, read + filter)
d3.js interactive family tree
British Royal Family demo (96 people)
Live full-text search
HTTPS · Cloudflare · Responsive design
Q3 2026 · Completed
OAuth 2.0 — Google & GitHub login
User accounts + plan-based access
GraphQL mutations (write API)
GEDCOM import + photo gallery
AI biography generator (Claude)
Dynasty timeline visualization
Historical events overlay
Cross-tree ancestor matching
Collaborative editing (email invite)
Memory Book PDF export
WebP auto-optimization
In-app notification system
PWA Service Worker + icons
OPcache JIT + Apache performance tuning
Q4 2026 · In Progress
GEDCOM export (.ged download)
REST / JSON:API endpoints
Webhooks with HMAC signatures
Stripe billing infrastructure
iOS app (Swift + GraphQL)
Android app (Kotlin + GraphQL)
Offline mode for mobile
Push notifications (mobile)
2027 · Future · Planned
DNA matching (23andMe, AncestryDNA)
Geographic map view
OCR document scanning
Multi-language UI (10+ languages)
Newspaper archive integration
White-label for institutions
AI relationship suggestions
Public family graph explorer
🔧

Remaining Configuration

Manual steps to enable all paid features

!
Anthropic API Key
/admin/config/drevo/ai-settings — paste sk-ant-... key to enable AI biography generation
!
Google OAuth
Create OAuth app at console.cloud.google.com → set Client ID + Secret in drevo_auth.settings
!
GitHub OAuth
Create OAuth app at github.com/settings/developers → set Client ID + Secret in drevo_auth.settings
!
Stripe Keys
/admin/config → drevo_billing.settings — add publishable key, secret key, webhook secret, price IDs for Pro & Institution
!
SMTP Mail
Configure Drupal mail system (SMTP module recommended) so invite emails are delivered

drevo.artlogic.studio

Built by Artlogic Studio · June 21, 2026