wp-campmanager

Decision log

The authoritative record of decisions. A decision lands here when the owner makes or confirms it. Later decisions may refine or supersede earlier ones; the later entry says so. “Architecture §N” refers to the architecture page. Names of plugins, modules, hooks and code identifiers are placeholders.

ID Date Decision Notes
D-001 2026-10-09 Scale target: 500–2,000 registrations per season, multi-year retention Measured 2026: ~200 per organization and season. Retention still matters
D-002 2026-10-09 Payments already run online via WooCommerce; WooCommerce stays the payment engine. Goal: smoother, not replaced  
D-003 2026-10-09 Multiple organizations eventually Refined by D-008, D-009
D-004 2026-10-09 Admin users are a team with distinct roles → role-based permissions needed  
D-005 2026-10-09 The current Google setup spans multiple spreadsheets and script projects  
D-006 2026-10-15 Build, don’t buy: no existing product met at least 3 of 7 hard criteria  
D-007 2026-10-15 Base: WordPress + WooCommerce. Payment rails today: Stripe via WooPayments on store.refisz.hu Confirmed 2026-10-23
D-008 2026-10-15 The parallel K/FF column blocks are a data-entry workaround → events are created dynamically. Two organizations from day one: REFISZ and IVK (Ifjúságépítők, ifjusagepitok.com). One organization-agnostic codebase, one deployment per organization  
D-009 2026-10-15 Organizations are completely separate: no shared people or data, separate installs; only the plugin code is shared  
D-010 2026-10-15 No grouping layer above events: the event is the top-level unit. Seasons are grouped by dates, labels and filters Form and registration details refined by D-030, D-031
D-011 2026-10-23 Architecture planned from first principles; earlier exploratory analyses serve only as background  
D-012 2026-10-23 Overall shape: layered, with strict separations between core and features, so parts can later be published one by one as open source (the eventual intention). Both organizations’ deployments must work at the same time; deployment should be automated. Lean on WordPress core as much as possible (reactive UI, API, permissions…). Forms: no paywalled key features, and no bending the architecture around a form plugin Details in D-014, D-025
D-013 2026-10-23 Config changes after registration: each registration keeps the tariff snapshot it registered under. Personal facts (tier choice, aid, staff status, deadline passed, quota position) still recompute automatically. Event config edits reach existing registrations only through an explicit re-price action with a preview, which writes adjustment lines Architecture §5
D-014 2026-10-23 Forms: our own implementation on top of WordPress core building blocks; no form plugin. Deployment details deferred. Plugin names are placeholders Details in D-020
D-015 2026-10-23 Storage: own database tables for the domain (events, tiers, people, registrations, ledger, payments, serials, mail log, submissions, notes, audit). WordPress posts only for documents edited in the block editor (forms, mail templates); each submission references the form version it answered. Our own audit trail and notes replace WordPress revisions and comments Target: low-end shared hosting, good to 500 registrants, functional to 1,000
D-016 2026-10-23 Schema changes: WordPress’s schema tool for creating tables and adding columns, plus ordered upgrade steps (drops, renames, data moves) tracked by a schema version. Until production data exists, no migrations at all: during development everything is dropped and recreated freely, with test fixtures (users per role + realistic anonymized data) Migrations start at the first production deployment
D-017 2026-10-23 Serials and side effects: each event’s arrival serial comes from a counter assigned inside the submit transaction, with a uniqueness rule as safety net. Side effects (mail, third-party hooks) are queued and run only after the data is saved Verified in a prototype
D-018 2026-10-23 Payments via WooCommerce: only through WooCommerce’s own API, so both of its order-storage modes work. One hidden product line per order with name and amount set per order (coupons keep working). WooCommerce payment and refund events write ledger lines exactly once, keyed by WooCommerce order and refund IDs Verified in a prototype. Open: the coupon-covered part of an order needs its own wallet ledger line (wallet design)
D-019 2026-10-23 REST API follows WordPress core conventions (paging, search, sorting, totals, schemas), so the admin screens use WordPress’s own data layer and admin components (DataViews/DataForm) Verified in a prototype
D-020 2026-10-23 Forms implementation: forms are block documents built from our own field blocks; the public page uses WordPress’s Interactivity API and renders correctly before any script runs; the server validates against the same form definition (only declared, visible fields accepted); each submission stores the form and its version. Work list: quota locking, stable field keys and pickers for conditions, spam protection, file upload, prefill for known people, staff form, embed block Verified in a prototype
D-021 2026-10-23 Admin actions as WordPress abilities (create payment link, award aid, re-price, call up from waitlist, …): schema-checked input, permission check and REST access come from WordPress. Admin table data stays on our own REST API (D-019) Verified in a prototype
D-022 2026-10-23 Minimum versions: WordPress 7.0+, PHP 8.2+ Revisit if a host turns out older
D-023 2026-10-23 UI language is Hungarian only, written directly in the code, with no translation layer. Internationalization is far off and can be added later  
D-024 2026-10-23 No blanket “reproduce the old system first” rule. Today’s behavior is the default reference; every deviation is decided explicitly and recorded here  
D-025 2026-10-23 Packaging: a core plugin plus one extension plugin per feature, in one repository with one version number; extensions use only core’s public API. Core itself is internally modular with strict boundaries Architecture §3
D-026 2026-10-23 Financial aid as two separate extensions: (1) adjudicated aid (request → decision, payment blocked until decided, self-declared amount); (2) sponsor/church support (directory, conditions, contributions). The subsidized tier with a quota stays in core’s tier ladder Architecture §3
D-027 2026-10-23 (Superseded by D-028.) Participants get WordPress user accounts  
D-028 2026-10-23 Registration does not require a WordPress account. Editing an account’s profile never changes an existing registration. Without an account, a personal secret link opens the registration’s status page, including payment status. A WordPress account is an extra layer that owns registrations: it can hold several people (guardian, youth leader registering a group), register them for several events (e.g. both REFISZ camps), see all outstanding balances together and pay them at once. Participants must be trackable year to year Editability refined by D-035. Architecture §4
D-029 2026-10-23 Identity model, in core: a WordPress account owns 0..n people (stable identity across years; editable profile used for prefilling); registrations made for one of these people are linked to them and tracked year to year. People can be transferred between accounts. Guest registrations create no person record and are never matched: guest registration is deliberately semi-anonymous and untracked, and organizers get no manual linking tool. A guest may later attach their registration to an account via its secret link. An account can pay all its registrations in one order, split into each registration’s ledger Architecture §4
D-030 2026-10-23 A registration is for exactly one event. Attending two events (e.g. both REFISZ camps) means registering twice; an account can reuse its saved person for the basic data, but the registrations are otherwise fully separate: own serial, status, secret link and ledger. Budgets and accounting are completely separate per event Architecture §4
D-031 2026-10-23 One form per event. A form belongs to exactly one event; the event is fixed by which form is opened. An event may have several forms (e.g. participant and staff form, as today) Supersedes the shared-forms part of D-010
D-032 2026-10-23 Extension surface, by purpose: anything that shapes behavior or money (fee components, payment guards, ledger line sources, conditions, portal sections, admin sections, form blocks, payment methods) goes through typed PHP interfaces registered with core. Reacting to what happened goes through WordPress actions fired after the data is saved, with stable documented names, open to any plugin Architecture §6
D-033 2026-10-23 Every action writes its audit entry together with its own changes, so neither exists without the other Architecture §2, §7
D-034 2026-10-23 The WooCommerce integration is a separate extension plugin of ours on core’s payments interface; core has no WooCommerce dependency at all. Refines D-025 Architecture §3
D-035 2026-10-23 Registration data is editable per field. Each form field defines whether it can be edited after submit, with locks by date/time or set manually. Organizers with the right permission can correct any field at any time. Registrants (via secret link or owner account) see all their submitted data and can edit the editable fields. The original submission stays as the unchanged record, and every edit is audited Architecture §4
D-036 2026-10-23 A person record is optional under accounts too: a registration made from an account may be linked to a person or stay independent (untracked, like a guest). A youth leader can register a group without creating person records. Default flows must be seamless: guest registration, and “create account → person created automatically → register”. Multi-person flows may be more involved, with short explanations Architecture §4
D-037 2026-10-23 Money uses WooCommerce-compatible shapes: a currency code on every monetary record, decimals and rounding following WooCommerce conventions; multi-currency possible but not built. Cash and bank transfers are recorded by staff in core. Payment methods are pluggable, so more automatic methods can be added without changing core Architecture §5
D-038 2026-10-23 Secret registration links are stored readable, so every email can carry the registrant’s link. They are treated as secrets: never logged, masked in exports Architecture §7