Project Overview — ShiftIt

What it is

ShiftIt is a shift planning and employee scheduling platform. Admins create events and shifts, define roles, assign or release shifts for employee self-claiming, and track worked hours with overtime balance management. It also supports building customer-facing event-booking forms that feed directly into the admin workflow.

Initial target: single-tenant deployments for one business. Long-term: multi-tenant SaaS plus licensed self-hosted deployments. Multi-tenancy is built into the schema and runtime today (RLS-enforced) — operators can run single-tenant without changes.

Consuming clients (current and planned):

  • Leptos PWA — primary web frontend (this repo, frontend/)

  • Tauri mobile app — iOS/Android, separate project, same REST API


Repository structure

Cargo workspace with two members and one excluded sub-crate:

Part Path Type Stack

Backend

backend/

Rust modular monolith REST API

Axum 0.8, sqlx 0.8, PostgreSQL 16 (RLS), Zitadel JWTs, utoipa, web-push, aws-sdk-s3

Frontend

frontend/

Rust → WASM SPA + PWA

Leptos 0.8 (CSR + nightly), Trunk, Tailwind v4, rust-ui components

License tool

deploy/license/

Standalone CLI (not in workspace)

ed25519-dalek signed .lic files


Architecture at a glance

Browser (Leptos PWA WASM)
  └── /api/v1 → nginx → anubis (PoW bot challenge) → Axum backend
                                                       ├── PostgreSQL (RLS-bound)
                                                       ├── RustFS (S3-compatible)
                                                       └── Zitadel (JWKS only — backend never issues tokens)

Key design decisions (see docs/superpowers/specs/2026-05-08-shiftit-design.md for the full rationale):

  1. Axum is a pure resource server. Validates Zitadel-issued JWTs; never issues tokens.

  2. Zitadel Organizations = ShiftIt Tenants. SSO federation, customer IdP integration (Entra/Keycloak/Authentik) is Zitadel’s job.

  3. PostgreSQL RLS enforces tenant isolation. app.tenant_id GUC set per transaction; <table>_isolation policies filter every read and write. Application code cannot leak across tenants — provably tested.

  4. Two roles in the DB: the connecting role (privileged, runs migrations) and shiftit_app (NOLOGIN, RLS-bound, used at runtime via SET ROLE per-connection).

  5. No unauthenticated endpoints. Even customer forms require a Zitadel JWT (customers are provisioned with role customer). The single RLS bypass is customer_forms_lookup_by_slug SECURITY DEFINER.

  6. time_tracking is feature-flagged per tenant. tenant_settings.time_tracking_enabled; routes return 404 when off.

  7. SaaS vs self-hosted is a compile-time --features saas flag. SaaS builds skip license validation entirely.


Auth tiers

Role Access

admin

Full tenant access

employee

Own assignments, shift claiming, notifications, overtime balance

customer

Assigned forms only — read form definition + submit


Status (as of 2026-05-10)

Area State

Backend

80 sqlx tests passing; every public route has #[utoipa::path]; OpenAPI doc has 39 paths / 36 schemas / 12 tags

Frontend

Nightly Rust + Tailwind v4 + rust-ui components. 3 surfaces: /admin/ (10 pages), /app/ (5 pages), /f/{slug} (customer form). wasm32 + fmt + clippy clean

Migrations

0001—​0007 applied (tenants/users, roles+locations, events+shifts, time_tracking, forms+documents, form_lookup_function, notifications)

Deployment

Distroless backend Dockerfile, nginx-alpine frontend Dockerfile, Compose stack with anubis + Zitadel + RustFS, ed25519 license tool, GitLab CI

The 9 original implementation plans (docs/superpowers/plans/01..09) are all complete plus a Phase 1 styling refactor and an MVP fill round on top.

Outstanding work is tracked in docs/follow-ups.md. Two P0 items (Zitadel OAuth wiring + slot-picker UI) block real users; the rest are P1/P2.


Where to go next

To…​ Read…​

Run the dev stack

CLAUDE.md (root) — run-the-dev-stack section

See the full endpoint surface

http://localhost:3010/api/docs/ (Swagger UI) once running, or docs/api-contracts-backend.md

Understand the data model

docs/data-models-backend.md

Understand the source layout

docs/source-tree-analysis.md

Understand backend internals

docs/architecture-backend.md

Understand frontend internals

docs/architecture-frontend.md

Understand how the two parts talk

docs/integration-architecture.md

See the catalog of UI components

docs/component-inventory-frontend.md

Deploy somewhere

docs/deployment-guide.md + docs/deployment/*.md

Pick up open work

docs/follow-ups.md

See the original design rationale

docs/superpowers/specs/2026-05-08-shiftit-design.md