cratefield-module-waitlist 0.3.0

Cratefield module: per-product waitlist with confirm, position, referral codes
Documentation

cratefield-module-waitlist

Per-product waitlist for a Cratefield venture: POST /v1/waitlist joins, a signed confirmation link assigns a dense per-product position, referral codes credit the referrer, and a status endpoint shows the entry's place and share link.

use cratefield_module_waitlist::Waitlist;

let module = Waitlist::new()
    .products(["kontinuum", "undercover-rockstars"])
    .confirm_ttl_days(7)
    .referrals(true);

Joins may carry a free-form answers JSON object: .answers_schema(|answers| ..) validates it whenever answers are present, .require_answers(true) rejects joins without them, and the admin export carries the stored answers as a quoted CSV column.

Position semantics: positions are per product, assigned densely at confirm time from a per-product counter on waitlist_position_lock that the lock-taking UPDATE increments, inside one all-or-nothing Database::batch_atomic, so concurrent confirms of the same product serialize on every engine (D1, SQLite, Postgres) and never share a position; a UNIQUE(product, position) index backstops the allocation. Positions are never recomputed when rows are deleted.

Register the default mail templates in the venture's src/lib.rs:

use cratefield_core::Harness;
use cratefield_module_waitlist::default_templates;

let builder = Harness::builder().templates(default_templates());

Emits waitlist.joined and waitlist.confirmed; pair with cratefield-module-email-signup's .subscribe_on_waitlist_confirm(true) to mirror confirmed addresses into the signup list — no crate dependency between the modules.

See docs/ARCHITECTURE.md section 6 (Waitlist) and section 11.


MIT. Built in the open for Cratefield, a Factory Zero venture.