Shiftly is built around a clean architecture pattern with a hard boundary between business logic and the React UI. The domain layer contains all salary calculation rules as pure, framework-agnostic functions — it has no knowledge of Redux, React hooks, or MUI components. Adapters translate domain output into view models. Hooks orchestrate data flow. Redux holds application state. The UI renders what it receives. This separation means the entire calculation engine can be tested in isolation, recalculated for any historical period, and evolved without touching presentation code.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/dmaman86/shiftly/llms.txt
Use this file to discover all available pages before exploring further.
Three-Level Aggregation Flow
Every salary calculation in Shiftly moves through three levels of aggregation, each computed independently:- Shift — A single continuous block of work (start time, end time, date). The shift layer segments it into rate-bearing components: regular hours, overtime brackets, Shabbat bonuses, and night premiums.
- Day — All shifts on a given date are combined into a day-level pay breakdown. The day’s classification (regular, partial special, full special/Shabbat) determines which rate multipliers apply.
- Month — Day-level breakdowns are accumulated into a monthly aggregate using reducers that support incremental add and subtract operations — no full recomputation is triggered when a single shift changes.
Architectural Layers
1. Domain
The domain layer is the heart of Shiftly. It is entirely framework-agnostic — no React, no Redux, no MUI imports. It contains:- Builders — Assemble domain structures (
ShiftMapBuilder,ShiftSegmentBuilder,DayPayMapBuilder,WorkDaysForMonthBuilder) without embedding business rules in construction logic. - Calculators — Pure functions that implement salary rules, organized by concern: regular hours (per shift and per day), extra and special segments with time-based bonuses, per-diem at shift/day/month granularity, and meal allowance eligibility and rate calculation.
- Reducers — Accumulate and roll back calculated values. Key reducers include the monthly pay map reducer, regular hours accumulator, fixed segment month reducer, meal allowance month reducer, and workday month reducer. These enable incremental recalculation when individual shifts are added, updated, or removed.
- Resolvers — Context-aware decision functions: the holiday resolver (Hebcal-based), shift segment resolver, timeline-based per-diem rate resolver, timeline-based meal allowance rate resolver, month resolver, and workday info resolver.
- Factories — Create specific calculator instances:
FixedSegmentFactoryandRegularFactory. - Pipelines — Composition entry points that wire domain components together:
buildCoreServices,buildResolvers,buildCalculators,buildShiftLayer,buildDayLayer,buildMonthLayer, andbuildPayMapPipeline(the top-level entry point used indomain.instance.ts). - Services — Domain-level utilities:
DateServicefor date manipulation and validation, andShiftServicefor shift-related business logic.
2. Adapters
Adapters convert domain objects into UI-friendly view models. This one-way mapping ensures the domain never imports from the presentation layer. Key adapter functions includedayToPayBreakdownVM and monthToPayBreakdownVM, which reshape raw domain pay maps into the structured objects that feature components consume directly.
3. Hooks
React hooks form the orchestration layer between the UI, domain, and Redux state. They coordinate data flow without embedding any salary calculation logic. Key hooks include:useDomain— Provides access to the singleton domain instance (builders, calculators, resolvers, services).useWorkDays— Manages the work days list and dispatches Redux actions for shift add/update/remove.useGlobalState— Reads from and writes toglobalSlice(configuration and monthly aggregate).usePageTracking— Fires analytics page-view events on route changes.
4. State Management (Redux)
Redux Toolkit manages two slices:globalSlice— Holds application-wide configuration (standard hours, hourly base rate, selected year/month) and the running monthly aggregate. This is the slice that grows as shifts are added throughout the month.workDaysSlice— Holds the list of work-day records rendered by the Daily and Monthly views.
5. UI Components
UI components are purely presentational. They render data passed to them via props or selectors, and dispatch actions or call domain hooks in response to user interaction. Thefeatures/ directory is organized by product area:
work-table— The shift input table rendered on the Daily page.salary-summary— Per-day and monthly salary breakdown panels.workday-timeline— Visual timeline for a selected workday.config— TheConfigPanelthat adapts between Daily mode (standard hours and rate) and Monthly mode (year/month selection with enforced rate).calculation-rules— The read-only rules reference page.
Project Directory Structure
Domain Instance Bootstrap
The domain is wired once at application startup insrc/app/domain/domain.instance.ts via the buildPayMapPipeline() factory. The resulting singleton is placed into a React context by DomainProvider and accessed anywhere in the tree via the useDomain hook — ensuring that all pages and features share the same initialized builder and resolver instances.
Provider Stack
The application shell wraps the component tree with a carefully ordered set of providers defined inAppProviders:
/he/ → RTL, /en/ → LTR) on initialization, and the MUI theme and Emotion CSS cache are both recreated whenever direction changes.
Routing
Routes are lazy-loaded using React’sSuspense and lazy. The URL structure is /:lang/(daily|monthly|calculation-rules). Any unmatched path under a language segment redirects to /:lang/daily. The root path / redirects to /he/daily.
Domain Architecture Reference
Builders
Domain structure builders:
ShiftMapBuilder, ShiftSegmentBuilder, DayPayMapBuilder, and WorkDaysForMonthBuilder. Responsible for assembling inputs before calculation.Calculators
Pure calculation functions for regular hours, overtime brackets, per-diem, meal allowance, and special-day rate segments. No side effects.
Reducers
Accumulation and rollback logic enabling incremental monthly recalculation. Supports add and subtract operations on pay maps without full recomputes.
Resolvers
Context-aware decision logic: holiday classification via Hebcal, time-based rate timeline resolution, shift segment classification, and workday info resolution.