A backend API for coordinating spontaneous meetups with friends. Turn "Who's up for drinks?" into an actual hangout with minimal friction.
Sens-O-Matic streamlines group coordination by collecting structured availability, finding time overlaps algorithmically, and reducing back-and-forth messaging. See docs/SPEC.md for the full application specification.
Install from crates.io:
cargo install sens-o-maticRequires Rust 1.93+ (edition 2024) and just.
just buildStart the server on port 3000:
just runThe API will be available at http://localhost:3000.
Interactive API documentation is available via Swagger UI:
http://localhost:3000/swagger-ui/
OpenAPI spec is served at:
http://localhost:3000/api-docs/openapi.json
just testThe project includes comprehensive API tests using Hurl.
Run all API tests (builds, starts the server, runs tests, stops the server):
just test-apiIf you already have a server running, you can run the tests directly:
just hurl-testRun a specific test suite (requires running server):
just hurl entities
just hurl flowsTest categories:
| Directory | Description |
|---|---|
tests/hurl/entities/ |
CRUD operations for users, groups, pings, responses, hangouts |
tests/hurl/state_machine/ |
Ping lifecycle state transitions |
tests/hurl/flows/ |
End-to-end user flows |
tests/hurl/errors/ |
Validation and error handling |
tests/hurl/edge_cases/ |
Edge cases (no responses, cancellations, no overlap) |
src/
├── main.rs # Server entry point
├── lib.rs # Library exports
├── router.rs # Route definitions with OpenAPI
├── state.rs # In-memory state management
├── state_machine.rs # Ping lifecycle transitions
├── matching.rs # Time overlap algorithm
├── models/ # Domain types
└── handlers/ # API endpoints
-
docs/SPEC.md - Original application specification
-
docs/api.yaml - Original OpenAPI specification (now generated)
This project uses just as a command runner. The
justfile is the single source of truth for build logic — the same recipes run
locally and in CI.
just check # run fmt-check + clippy + tests (same as CI)
just fix # auto-fix formatting and clippy warnings
just setup-hooks # install pre-push git hook
just ci # watch the latest CI run for the current branch
just release # cut a release (tag + push + gh release)
just lint # clippy only (warnings are errors)
just test # tests only
just build # build debug binary
just run # start the server on port 3000
just test-api # build, start server, run hurl tests, stop server
just hurl-test # run all hurl API tests (requires running server)
just hurl entities # run a specific hurl test suite
just fmt # format code
just fmt-check # check formatting without changing files
just publish-dry-run # validate crate packagingReleases are automated via GitHub Actions. When a GitHub Release is published, the workflow validates the tag, runs checks, builds a static musl binary, publishes to crates.io, and uploads the binary tarball to the release.
-
Bump the version in
Cargo.tomland commit:# edit Cargo.toml git add Cargo.toml Cargo.lock && git commit -m "Bump version to X.Y.Z"
-
Cut the release:
just release
This runs checks, validates packaging, creates a signed
vX.Y.Ztag, pushes, and creates the GitHub Release. GitHub Actions handles the rest (build artifacts, publish to crates.io).
If you need to publish outside the automated workflow:
CARGO_REGISTRY_TOKEN=$(passage show cargo/registry-token) just publish| Location | Purpose |
|---|---|
passage (local) |
Encrypted token for manual publishing |
GitHub secret CARGO_REGISTRY_TOKEN |
Token used by CI release workflow |
To rotate the crates.io API token:
- Generate a new token at crates.io
passage edit cargo/registry-tokengh secret set CARGO_REGISTRY_TOKEN --body "$(passage show cargo/registry-token)"
This project is licensed under the MIT License.
Backend API implementation complete with in-memory storage. No persistence layer yet.