Standard membership management, libertarian-extended.
Full association and party administration as the foundation, meritocratic governance as the differentiator.
Lapis Cloud is the successor to the PZB (PdV Party Central Bank) — a federated server network with a private-law-association character for the membership management of associations and parties. Every server is sovereign but can federate with other Lapis Cloud instances.
Lapis Cloud covers two orthogonal layers:
-
Standard membership management — everything a modern association or party administration needs (member master data, contribution management, events, communication, GDPR, reporting, donation receipts, etc.), at a level that makes parallel specialist tools unnecessary.
-
Innovative libertarian extensions — meritocratic voting, an internal currency ("Libertaler"), internal crowdfunding, pseudonymity with transparency, a right of secession via federation.
The explicit ambition: to become the de facto standard for membership management of associations and parties — completeness over elegance, compliance-first (GDPR, association law, party law, tax law), usable without prior IT knowledge.
Originally developed for the Partei der Vernunft (PdV), Lapis Cloud is open source and open to any organization — political parties, traditional associations, professional bodies, cooperatives, foundations, NGOs.
|
Tip
|
Conceptual details, roadmap, and design decisions are maintained in the project vault, not in this repository. This README describes only the technical scope. |
-
Lapis Net — a fully decentralized P2P sister project, sharing the same libertarian core principles (meritocratic scoring, self-organization, voluntary association) but differing in implementation (P2P nodes instead of federated servers, cryptographic trust instead of server federation).
-
PZB (https://gitlab.com/pdv7/pzb) — the existing predecessor repository. Kept as a reference (architecture decisions, code patterns) but not adopted 1:1 — Lapis Cloud is a clean reimplementation.
-
Lapis Cloud Mobile — companion app (Kotlin Multiplatform, Android + iOS): login, video-conference join, a home hub that opens the main web sections (including events), and the member-card download. Not in any app store yet. Its section and video features need the optional WebView bridge on the server (off by default, see
CHANGELOG.md[0.22.0]); its member tile "Veranstaltungen" uses the section keymy-events, which needs a server fromv0.29.0on (an older server answers400and the app shows a hint). Fromv0.30.0on the server also offers a bridge route and the section keyencounterfor the encounter space ("Begegnungsraum"); the app has no tile for it yet. -
kUML — the modeling language used for every diagram in this repository (see below).
-
lapisproject-dev/Lapis-Cloud-Ops(private) — the real, filled-in deployment config (.env, rendered LiveKit/coturn configs, certs, branding) for the instances this project’s maintainer actually operates. This repo’s owndeploy/example/is the generic, public template anyone can self-host from; the Ops repo is the maintainer’s own real-world instantiation of it, kept private because it identifies real organizations and infrastructure. See the NOTE block indeploy/example/README.adocfor the split.
-
Language: Kotlin
-
Server framework: Ktor
-
Database access: Exposed (Kotlin SQL framework)
-
Database migrations: Flyway
-
Web UI framework: KVision (Kotlin/JS)
-
Frontend-backend communication: Kilua RPC (type-safe RPC between the KVision client and the Ktor server)
-
AI assistance / agentic layer: Koog (JetBrains, Kotlin-native agent framework, multi-LLM without lock-in)
-
Deployment: Docker Compose (
deploy/example/). Sincev0.31.1(V1.9.93) the server image is built once per release tag by CI and published to GHCR (ghcr.io/lapisproject-dev/lapis-cloud:<version>); hosts pull it instead of compiling the sources (LAPIS_IMAGE_TAGin.env, rollback = previous tag). The pipeline has run and is verified: the published imageghcr.io/lapisproject-dev/lapis-cloud:0.31.1(the first image; later tags such as0.39.0follow the same route, an instance moves by settingLAPIS_IMAGE_TAG) is public — seedocs/architecture/ci-pipeline.adocanddeploy/example/README.adoc. A local source build stays available throughdocker-compose.build.yml.
Current release: v0.39.0 (database schema V117; a feature release on v0.38.0 with the waves V1.9.200 to V1.9.206 and two fixes. Behaviour changes first: (1) tenders (Ausschreibungen) bound to an adopted resolution, with a list, a detail page and board actions; LTR only, nothing is booked in LTR yet (the payout is a later wave), and guests cannot bid; (2) a menu search in the sidebar and a Ctrl+K / Cmd+K command palette; (3) events are a table with a detail page (registrations overview, seat counter for members, an optional registrant message, CSV export of the registrations); (4) a guided finance setup (Finanzen > Kontenplan & Journal > Einrichtung) with a standard chart of accounts for associations, which is a proposal a tax advisor must confirm; the account mapping moved there from the payment configuration page, and activating online payment now refuses while that mapping is incomplete (a gateway that is already active is not switched off by this); (5) inline field rows with one date-time group, amounts with thousands separators and a stake suggestion in the social compose form; (6) a readable time axis on the price chart. Three additive migrations (V115 to V117); no new environment variable. The staging seed top-up parts matter only on the seeded staging and demo instances. Checked in headless Chrome only: not looked at on real phones or devices, the CSV not opened in a real Excel or LibreOffice, the standard chart not checked against the official DATEV SKR42; see CHANGELOG.md [0.39.0]; underneath it v0.38.0 (database schema V114; a feature release on v0.37.7 with the waves V1.9.182 to V1.9.199 and one contacts-list fix. Behaviour changes first: (1) agreement texts (Vertragstexte) are a table with a detail page, and every text version saved from now on is Markdown (rendered by the server and sanitised; existing versions stay plain and unchanged, the consent hash is unchanged); (2) travel expenses get report attachments (PDF, JPEG, PNG), receipt upload directly in the add form, organisation documents for members (PDF, XLSX, XLS) on the settings page and a Markdown hint text; (3) a new Lapis Cloud logo and favicons (an operator logo keeps priority); (4) a wide page shell and master-detail tables for Gremien, Sitzungen, Anträge (with one decision selector), rooms, catering and shifts; (5) collapsible page intros and a "Hilfe und Feedback" menu, one back button, a unified control bar for the video conference and the encounter room, the LTR account with progressive disclosure and a renamed carpool view; (6) the contacts list no longer shows each contact several times. Three additive migrations (V112 to V114); no new environment variable. Checked in headless Chrome only: not looked at on real phones or devices, in Safari or by a screen reader; no virus scan and no retention period for uploaded travel expense files; see CHANGELOG.md [0.38.0]; underneath it v0.37.7 (database schema V111, unchanged; a client-only release on v0.37.6 with four waves, V1.9.171, V1.9.173, V1.9.180 and V1.9.181. Behaviour changes first: (1) every date and time field of the application offers the browser’s calendar and time picker (event form, travel expenses, volunteer allowances, accounting and SEPA filters, audit log, DSGVO forms and all other screens; the old text field remains as fallback; time fields step in 5 minutes on planning screens and 1 minute elsewhere; year and month filters are number fields); (2) the settings pairs of Auktion, Mahnwesen, Forderungs-Mahnwesen, Online-Zahlung and SEPA-Lastschrift no longer show both 'activate' and 'deactivate' at once, only the applicable one, with the state as text; (3) the travel expense draft shows the days as one full-width row per day, with the return time marked optional and a note that the days update after saving. No migration, no new environment variable. Checked in automated browser tests (headless Chrome) only; nobody clicked the native pickers, and Safari, Firefox, real phones and screen readers were not tried (the picker display follows the browser or operating-system locale, not the application language); see CHANGELOG.md [0.37.7]; underneath it v0.37.6 (database schema V111; a feature release on v0.37.5 with seven waves, V1.9.164 to V1.9.170. Behaviour changes first: (1) the video conference has three more reactions (laughter, amazement, question) and the encounter room offers the same set (plus flowers, and crying as an opt-in per room); (2) the control bar of the encounter room stays in view; (3) the assembly room is built as a theatre (tables centred in the parterre, seats in two loges) and has an optional grid map of the present members (stage 3, wave 1; off by default, switched on per closed assembly room, positions only in server memory, guests and friends never appear on it and get no packet) that opens as a layer from the control bar, with anchor buttons that answer every click; (4) the device picker of the video conference no longer disappears when the browser has not yet allowed camera and microphone (one button asks, on a click only); (5) the online window of an event opens 30 minutes before the start instead of 15, on every instance. One additive migration (V111, tested on PostgreSQL 17); no new environment variable. Looked at by the owner on a staging instance: the hall layout and the map layer; not looked at on real phones, in Safari or by a screen reader, and the stage-3 notice text for the map is still a draft without legal review; a known gap between speaking and hearing in a large room (about five seconds at the 95th percentile in the load test) is not part of this release; see CHANGELOG.md [0.37.6]; underneath it v0.37.5 (database schema V110; a patch release on v0.37.4 with two small waves: nothing changes for the people using the application. The load test showed that the TURN relay of the deployment example ran out of its 20 relay ports with eight relay clients and constant table changes (about a quarter of their connections ran into the time limit); the example now has 100 ports, and the load-test tool stops runs where nobody could enter the room and no longer ends healthy runs on one or two unlucky calls; measured on a test instance with the load-test tool, not with real browsers; no migration, no new environment variable; see CHANGELOG.md [0.37.5]; underneath it v0.37.4, a patch release on v0.37.3 with one wave: nothing changes for the people using the application. The load test of the encounter tables found that, on staging, a coturn on the Docker bridge with external-ip did not relay for clients while LiveKit ran on the same host, so the deployment example now runs coturn in host networking (and documents an nftables rule against UDP replies with TTL 1), the load-test tool can spread its participants over processes and respects the server’s table-change cooldown, and the server gained an unused LiveKit call (updateSubscriptions) for the planned stage 3; verified on staging only with the load-test tool, not with real browsers, and the cause of the TTL 1 replies inside coturn is not understood; no migration, no new environment variable; see CHANGELOG.md [0.37.4]; underneath it v0.37.3, a patch release on v0.37.2 with four small waves: the friend-registration confirmation no longer claims an account was created, table cards show the table top with the seats on a ring (one table per row on a 320 px phone), unavailable options in event rooms are named instead of refused with a generic error, and the release image build falls back to other base-image registries when the ECR pull limit is hit; nothing of it seen in a real browser window, the new CI steps not yet run on GitHub; see CHANGELOG.md [0.37.3]; underneath it v0.37.2, a release on v0.37.1 with two waves: event rooms can be recorded and live-streamed — off by default on three levels (instance switch, release of the single event, start by the moderation), only after everybody who enters has acknowledged the current consent text, with a banner for everybody in the room (one additive migration V110, nothing of it seen in a real browser, call or against a real LiveKit, the consent texts are unreviewed drafts and the legal position depends on the country), and recordings are composed more reliably (bounded video inputs, up to three attempts; not yet confirmed on the real recording that showed the hang); see CHANGELOG.md [0.37.2]; underneath it v0.37.1, a patch release on v0.37.0 with two fix waves: the encounter room seat drawings line up with the seats and the hints and the podium are no longer covered (measured in a browser test, not looked at in a real browser window), and participant recordings no longer let the audio fall behind the picture (proven with generated files; on a real recording only after "Neu berechnen"; existing recordings need the raw files); no migration, no new environment variable, see CHANGELOG.md [0.37.1]; underneath it v0.37.0, a feature release on v0.36.0: messages on a confirmed carpool ride, country of residence and nationality at registration and in the member roster, camera filters (light, colour, skin smoothing) in your own camera image, an optional recording of the pulpit and an optional member finder (both off until an administrator switches them on after an operator notice), encounter entry notices administered per instance (non-members acknowledge the changed notice again), fixed room templates for the encounter space and a load-test tool with a run sheet for the encounter tables — none of it has been seen yet by real people in a real browser window or call, the pulpit recording and the load-test media layer have never run against a real LiveKit, the load-test tool never against a real instance, the skin smoothing was never judged on real faces, the translations were written by the model and every operator notice and consent text is an unreviewed draft; see CHANGELOG.md [0.37.0] for the behaviour changes, the migrations V105 to V109 and the honest limitations). Lapis Cloud contains standard membership management (members, contributions, events, communication, GDPR, accounting),
the meritocratic governance layer (voting, elections, systemic consensus, LTR economy), federation, video conferencing and many optional modules.
-
Not yet released:
CHANGELOG.md[Unreleased]is empty; everything up to V1.9.206 is inv0.39.0. -
CHANGELOG.mdis the authoritative release history; the long-form narrative is in docs/release-history.adoc. -
Website: https://cloud.lapisproject.dev
-
Feature documentation: docs/features/index.adoc
-
Architecture documents: docs/architecture/
Each feature has its own document under docs/features/.
| Feature | Description |
|---|---|
Video conferencing, LiveKit-based, for committee sessions; friends can join like guests (V1.9.126), optional noise suppression with an instance default (V1.9.124), reactions and a raised-hand queue (V1.9.127), a display-only timer (V1.9.133) |
|
Board-published tasks bound to an adopted resolution; bids in LTR (guests cannot bid), award, acceptance; list and detail screens; no payout yet |
|
Events as a table with a detail page, registrations overview, seat counter, registrant message and CSV export |
|
Search field in the sidebar and a Ctrl+K / Cmd+K dialog |
|
Guided setup of chart of accounts and account mapping; standard association chart as a proposal; gate for the payment activation |
|
Card and PayPal checkout for contributions and donations, with webhook handling |
|
Read-only machine-to-machine REST API under |
|
Signed outbound webhooks for fixed domain events |
|
Embeddable script for partner websites: login, join link, donation and event registration |
|
Editorial article/news workflow with an approval gate |
|
Contact management for prospects and supporters who are not members |
|
CSV and MT940 bank statement upload with matching against open contributions |
|
DATEV-EXTF Buchungsstapel export of posted journal entries |
|
Contribution relief (deferral, exemption, reduction) (V1.4.10) |
Member requests for deferral, exemption or reduction of contributions |
Self-service travel expense reports following the PdV form: a day grid with tiered day allowances and meal deductions, mileage with passengers, receipted costs, advance and payout or donation waiver, and a SEPA credit transfer file ( |
|
Tax-privileged volunteer and instructor payments with annual caps |
|
Optional statute Q&A with verified citations (off by default) |
|
Board-only aggregate map of member postal-code distribution |
|
Member count history per status |
|
HTML mailing content and asynchronous send path |
|
Mailing lists whose recipients are computed from a rule at send time; mandatory lists without opt-out |
|
Committees whose members are computed from a rule instead of seat rows; a vote freezes its electorate when it is opened |
|
Lapis video conference created on the first join, entry into an encounter space, guests without an account |
|
Setting to show or hide the active member count on public pages |
|
Icon navigation and overview pages for the public site |
|
Carpooling bulletin board for members; since V1.9.125 guests and friends can ride along (six methods open to them) |
|
Regional chapters ("Gliederungsverwaltung", Landesverbände) (V1.9.13/V1.9.14) |
Optional regional chapters with chapter-scoped officer access |
Management of membership tiers and their amounts |
|
Voluntary member photos and public profiles with consent |
|
Election lifecycle screen: committee, candidacies, voting booth, results |
|
Voting panel inside the video-conference room |
|
Web client for systemic consensus (Konsensieren) |
|
Non-binding anonymous opinion polls |
Self-hosting with Docker Compose: see deploy/example/README.adoc (quick start, updating, backup and restore, optional modules).
Consistent across all Lapis and kUML projects (see CLAUDE.md):
-
All documentation in Asciidoctor (
.adoc) — noREADME.md -
All diagrams in kUML, no PlantUML/Mermaid/draw.io/ASCII art
-
Diagrams embedded via the
[kuml]macro of the kuml-asciidoc extension (Maven Central) — source inline in the.adocdocument is the single source of truth, never replaced by a pre-rendered image. Exception: GitHub’s built-in.adocviewer does not load the extension, so it cannot execute[kuml]blocks — for diagrams meant to be visible there (like the conference-room diagram indocs/features/video-conferencing.adoc), commit a companionimage::docs/images/<name>.svg[…]reference immediately above the[kuml]block, purely as a GitHub-preview fallback, and re-render it by hand whenever the model changes (see the note above the diagram indocs/features/video-conferencing.adocfor the exact command). Nothing enforces that the two stay in sync — this is a deliberate, manual trade-off, not an automated build step.
[kuml, filename-without-extension, svg]<kUML source>
-
The default branch is always
master, nevermain -
Feature branches stay local and are never pushed
-
Releases happen via a local squash-merge onto
master, then push -
Never
--forcepush without an explicit instruction
Details: CLAUDE.md in this repository.
