Skip to content

Latest commit

 

History

History
100 lines (91 loc) · 9.45 KB

File metadata and controls

100 lines (91 loc) · 9.45 KB

vutuv architecture

How the vutuv codebase is put together, one document per subsystem, plus the stack conventions and the context-module map below.

Setup, tests and deployment live in Developing vutuv; installing and operating vutuv in Running your own vutuv.

Subsystem documents

Document Covers
realtime.md the LiveView app shell, live pages, reload-free updates over PubSub, presence & online dots, notifications, Berlin-time post stamps, the live people counter
social-graph.md follows, vernetzt (mutual follows), per-follow mute, blocking, personal notes
fediverse.md follow-only ActivityPub federation: WebFinger, actors, the inbox, signed deliveries
posts-and-feed.md posts, deny-based audiences, the /feed timeline, likes/bookmarks/reposts, reply threads, post images
translations.md declared post languages, on-demand Ollama translation, the cache + job queue, what never translates
i18n.md the interface languages: how a request gets its locale, the Gettext catalogs and their extract/merge traps, per-locale email bodies, locale-sensitive formatting, and how to add a language
search.md the search page, query operators, post full-text search
messages.md 1:1 direct messages, message requests, unread-email nudges
profiles.md what a profile shows: owner vs. public view, the job-title line, education, section ordering, contact details & maps, the Mastodon/Bluesky card, BookWyrm reviews
job-references.md Arbeitszeugnisse: private-by-default upload, CV linkage, PDF/OCR text extraction, and the AI review (daily-fetched prompt, the context-window trap, the queue)
organizations.md verified organization pages at /organizations: the domain-proof trust model (DNS TXT / well-known file), lifecycle states, engagement, moderation, agent formats
jobs.md job postings at /jobs/:slug: the 90-day lifecycle & sweeper, structured location (offline GeoNames), the salary model, visibility gates, the AGG hint, easy apply, JSON-LD & agent formats
settings-and-account.md the settings hub, onboarding, username changes, LinkedIn import, GDPR export, the CV (Lebenslauf) download
mentions.md @handle mentions: the shared grammar, existence validation (anti-reservation), handle availability (anti-hijack), and rewriting mentions + notifying authors when a member renames
authentication.md passwordless PIN login, passkeys, server-side sessions
account-activity.md the append-only account-activity log: what changed on an account, when, from where and how it was confirmed; the member's page, the admin's page, retention
moderation.md reports, freezes, the strike ladder, reporter trust, evidence screenshots
agents-and-seo.md agent formats (.md/.txt/.json/.xml/.vcf), the member directory, sitemap/RSS/JSON-LD, Open Graph, how to read the Search Console reports
email.md the Emailer chokepoint, multipart bodies, opt-outs, bounces & deliverability
images.md the AVIF pipeline, kept originals, fingerprinted filenames, the shared images table and its backfill, URL screenshots, AI image moderation (Ollama)
video.md video on posts: the ffmpeg pipeline and its resumable job, the AI check over the stills, the post that waits for its clip, the player and the range-answering proxy, what federates and what the Mastodon API says
attachments.md files on posts and messages: the upload chokepoint, the format read from the bytes, the PDF gate and why a raw-byte scan is not enough, the two on-disk copies, the per-member budget
admin.md the admin panel: live dashboard, member browser, account deletion, newsletter & audiences, daily report
ads.md the daily text ad: booking, review, serving
company-pages.md the site footer, the English /system/investors and /system/media-kit pages, brand assets, and the daily head-count history behind the growth curve
api.md /api/2.0: personal access tokens, OAuth 2, webhooks, developer docs
mastodon-api.md the Mastodon-compatible client API on mastodon.<PHX_HOST>: what phone clients can do, and what they cannot yet

The stack

  • Views: mostly Phoenix 1.8 HTML modules with embed_templates (no phoenix_view dependency); LiveView is being adopted incrementally for the real-time parts (see realtime.md)
  • Routes: Verified routes (~p"..." sigils). Profiles live at the URL root, GitHub-style: /:slug is the profile and all per-user sub-pages hang off it (/:slug/links, /:slug/followers, /:slug/following, /:slug/connections, ...). The legacy /users/:slug/... URLs, /sessions/new and /search_queries/... 301 to their new homes (/login, /logout, /search). The user scope is the last in the router, so static routes always win; Vutuv.Accounts.ReservedSlugs keeps users from registering a slug that equals a route prefix. The URL-root namespace is shared with organizations: an organization can claim a member-style @handle and serve at /:handle too, with global uniqueness guaranteed by the handles registry table (see organizations.md, #941). The old read-only /api/1.0 JSON API was removed in favor of /api/2.0; only the session-aware vCard survived, at /:slug/vcard
  • Forms: <.form> component with <.inputs_for> for nested forms
  • Assets: esbuild + Tailwind CSS v4; dark mode follows the system (prefers-color-scheme, no toggle) — legacy pages get their dark styles centrally from assets/css/components.css
  • HTTP server: Bandit
  • Pagination: browse pages (followers, tags, the admin member browser) use offset pagination — Vutuv.Pages.paginate/3 on the query plus the <.pager> component for the numbered links; feed LiveViews (notifications) use cursor pagination instead — Vutuv.Activity.notifications_page/2 behind a numbered "Load 50 of 80 more" button that appends to the stream. Displayed counts (badges, follower numbers) are compacted site-wide via VutuvWeb.UI.compact_count/1: exact up to 999, then 1K/80K/5M. The one exception is the people counter — the top bar's total of members here plus the Fediverse accounts following them — which shows the exact figure via delimited_count/1 so it visibly ticks (see realtime.md)
  • Ids: all database ids are UUID v7 (Vutuv.UUIDv7): time-ordered, minted in the app, never integers or UUID v4.

Context modules

Business logic is organized into Phoenix context modules under lib/vutuv/:

Context Schemas Purpose
Vutuv.Accounts User, Email, UsernameChange, SearchTerm, LoginPin Registration, PIN-based authentication, user management
Vutuv.Sessions UserSession Server-side per-device sessions: signed-in-devices list, remote logout, new-device security email
Vutuv.AccountEvents AccountEvent The append-only account-activity log: what changed on an account, when, from where and how it was confirmed (member + admin readers, key-whitelisted details, retention sweep)
Vutuv.Credentials UserCredential Passkeys (WebAuthn/FIDO2): enrolment + assertion verification for passkey login
Vutuv.ApiAuth Token, App, Grant, AuthCode API credentials: personal access tokens, OAuth 2 apps/grants/codes, scopes
Vutuv.Webhooks Subscription, Delivery Signed webhook deliveries to registered apps (queue, backoff, kill switch)
Vutuv.Profiles Address, PhoneNumber, SocialMediaAccount, Url, WorkExperience User profile data
Vutuv.Social Follow, Block, Group, Membership, UserLike, UserBookmark Follows (a mutual follow = vernetzt), per-follow mute, blocking, groups, liking/bookmarking people
Vutuv.Posts Post, PostDenial, PostImage, PostTag, PostLike, PostBookmark, PostRepost, PostReply Posts, deny-model audiences, the feed, likes/bookmarks/reposts, replies/threads
Vutuv.Tags Tag, UserTag, UserTagEndorsement Tagging and endorsements
Vutuv.PersonalNotes PersonalNote Private notes a member keeps about other accounts (members, pages, remote accounts)
Vutuv.Search (none — reads Accounts.SearchTerm) Search functionality (people by name and CV, organizations, tags; post full-text via Vutuv.Posts.search_public/2). Stores nothing about a query
Vutuv.Chat Conversation, Participant, Message 1:1 direct messages, message requests, unread email notifier
Vutuv.Moderation Case, Report, Strike Reports, the content freezer, the strike ladder, reporter trust
Vutuv.Notifications Emailer Email notifications
Vutuv.Newsletters Newsletter, NewsletterDelivery, NewsletterClick, NewsletterGroup, NewsletterGroupMember, Markdown Admin email newsletter ("Rundbrief"): draft, test send, broadcast, delivery log, link click tracking + success overview, and filter-built audience groups
Vutuv.Deliverability Event, MailLog, Watcher, Sweeper Bounce detection: deactivate dead addresses, freeze unreachable accounts, admin dashboard
Vutuv.Ads Ad The daily text ad: booking, billing record, serving