4.6 KiB
Rezervovator
Booking system for sport/service facilities. Full-stack Rust: Leptos 0.6 (SSR + hydration) on Actix Web, PostgreSQL via sqlx. Crate name is rezervator, product name is "Rezervovator".
One crate, compiled twice by cargo-leptos:
- server binary — feature
ssr(Actix, sqlx, lettre, charts-rs) - browser WASM — feature
hydrate, targetwasm32-unknown-unknown
Every change must compile for both. Server-only code and imports go behind #[cfg(feature = "ssr")] / cfg_if!.
Commands
cargo leptos watch # dev server with reload (needs config.toml + running Postgres)
cargo leptos build --release # production build -> target/release/rezervator + target/site
cargo check --features ssr # type-check the server side
cargo check --lib --features hydrate --target wasm32-unknown-unknown # type-check the WASM side
Run both cargo check commands after any change; a plain cargo check (no features) checks neither side properly.
There are no unit tests, and end2end/ is still the untouched Leptos template (it asserts "Welcome to Leptos") — it does not test this app. Don't claim something is tested because these pass.
Running locally
config.toml(gitignored) is read from the working directory, or from-c <path>. Copyconfig_sample.toml. The bind address comes from[network]there, not fromLEPTOS_SITE_ADDR.- Migrations in
migrations/are embedded bysqlx::migrate!()and run on startup. - First start seeds an
admin/adminuser, a placeholder company, empty mail templates and an appearance row (create_admin,check_company,check_messages,check_appearanceinsrc/main.rs). - With
transport = "File"e-mails are written as.emlintoMaildir/instead of being sent. assets/is copied totarget/siteon build.assets/data/(banner.css, uploaded banner) is untracked but required: the page links/data/<css_name>and uploads are written totarget/site/data/at runtime, relative to the working directory. A rebuild wipestarget/site, so runtime uploads there are lost in dev.
Layout
src/main.rs— Actix setup: config, pool, migrations, seeding, session + auth middleware,/api/*server fns,/upload.src/app.rs—<App/>, router, shared contexts (MenuHelper,MenuOpener,DialogHelper).src/backend/— server functions per domain, plusdata.rs(all DTOs/entities shared by server and client) andauth_middleware.rs(redirects unauthenticated/admin*page requests to/login).src/pages/— page and dialog components;src/components/— reusable pieces (DataForm,QuestionDialog,ModalDialog,ServerErr,ValidationErr,AdminPortal).src/locales/—trl()and the translation catalogue.src/error.rs—AppError;src/config.rs—config.tomlstructs (ssr only);src/validator.rs— client-side form validation helper.assets/vendor/— third-party admin template (Bootstrap based). Don't edit or reformat it; app styles go tostyle/main.scss.
Routes: / public booking form, /login, /admin, /admin/settings, /admin/mail_settings, /admin/bookings, /admin/customers, /admin/appearance.
Domain model
property is a bookable thing with a price and slot length. A booking is one reservation_sum (date, customer, total price, state New → Approved / Canceled, public uuid) with one or more reservation rows (property + from/to time). opening_hour rows are per weekday, closing_time rows are date ranges when booking is closed. Customers are matched by e-mail. The public form is protected by a proof-of-work captcha (leptos-captcha).
Conventions
- Code, comments, identifiers, log messages and commit messages are in English. UI strings are English keys translated at runtime (see
.claude/rules/frontend.md). - Commit messages are always written in English, even when the conversation is in Czech: short past-tense sentences ending with a period, e.g. "Added setting for closing days."
- The project has no rustfmt config and the code is not rustfmt-formatted. Don't run
cargo fmtover existing files; match the surrounding style and keep diffs limited to what you changed. - Leptos is 0.6 — use the 0.6 API (
create_signal,create_resource,create_server_action,#[component]returningimpl IntoView), not 0.7/0.8 (signal(),Resource::new, …). wasm-bindgenis pinned to=0.2.100; it must match the wasm-bindgen version of the installed cargo-leptos. Don't bump it on its own.- Version lives in
Cargo.tomland is shown in the page footer.
Detailed rules are in .claude/rules/: backend.md, frontend.md, database.md.