> ## Documentation Index
> Fetch the complete documentation index at: https://docs.solvice.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Resource Period Rules

> Configure daily, weekly, and monthly work limits for compliance and safety

# Resource Period Rules

Period rules enforce time-based constraints on resources over extended periods, ensuring compliance with labor laws, safety regulations, and operational policies. This guide covers daily, weekly, and monthly limits for work time, drive time, and service time.

## Period Rule Configuration

Define rules within each resource:

```json theme={null}
{
  "resources": [
    {
      "id": "driver-1",
      "name": "Driver 1",
      "periodRules": [
        {
          "type": "MAX_DRIVE_TIME",
          "period": "DAY",
          "value": 32400  // 9 hours max driving per day
        },
        {
          "type": "MAX_WORK_TIME",
          "period": "WEEK", 
          "value": 216000  // 60 hours max per week
        }
      ],
      "shifts": [
        {
          "id": "shift1",
          "from": "2024-03-15T08:00:00Z",
          "to": "2024-03-15T17:00:00Z"
        }
      ]
    }
  ],
  "jobs": [
    {
      "id": "job1",
      "name": "Example Job"
    }
  ]
}
```

## Rule Types

### Work Time Rules

Total time from shift start to end:

<Tabs>
  <Tab title="Daily Limit">
    ```json theme={null}
    {
      "type": "MAX_WORK_TIME",
      "period": "DAY",
      "value": 36000  // 10 hours
    }
    ```

    Includes breaks and waiting time
  </Tab>

  <Tab title="Weekly Limit">
    ```json theme={null}
    {
      "type": "MAX_WORK_TIME",
      "period": "WEEK",
      "value": 216000  // 60 hours
    }
    ```

    Rolling 7-day window
  </Tab>

  <Tab title="Monthly Limit">
    ```json theme={null}
    {
      "type": "MAX_WORK_TIME",
      "period": "MONTH",
      "value": 720000  // 200 hours
    }
    ```

    Rolling 30-day window
  </Tab>
</Tabs>

### Drive Time Rules

Actual time spent driving/traveling:

```json theme={null}
{
  "periodRules": [
    {
      "type": "MAX_DRIVE_TIME",
      "period": "DAY",
      "value": 32400  // 9 hours daily limit
    },
    {
      "type": "MAX_DRIVE_TIME", 
      "period": "WEEK",
      "value": 162000  // 45 hours weekly limit
    }
  ]
}
```

### Service Time Rules

Productive time at job locations:

<CodeGroup>
  ```json Maximum Service theme={null}
  {
    "type": "MAX_SERVICE_TIME",
    "period": "DAY",
    "value": 28800  // 8 hours max
  }
  ```

  ```json Minimum Service theme={null}
  {
    "type": "MIN_SERVICE_TIME",
    "period": "DAY",
    "value": 14400  // 4 hours minimum
  }
  ```
</CodeGroup>

<Info>
  **Service Time** = Time spent performing jobs (excludes travel and breaks)
</Info>

## Period Types

### DAY Period

Rolling 24-hour window from current time:

<Steps>
  <Step title="Calculation">
    Looks back 24 hours from job start time
  </Step>

  <Step title="Example">
    Job at 14:00 on Tuesday checks work from 14:00 Monday
  </Step>

  <Step title="Use Case">
    Daily driving limits, fatigue management
  </Step>
</Steps>

### WEEK Period

Rolling 7-day window:

<Steps>
  <Step title="Calculation">
    Looks back 168 hours (7 × 24) from job start
  </Step>

  <Step title="Example">
    Job on Friday checks total work since previous Friday
  </Step>

  <Step title="Use Case">
    Weekly hour limits, EU drivers' hours rules
  </Step>
</Steps>

### MONTH Period

Rolling 30-day window:

<Steps>
  <Step title="Calculation">
    Looks back 720 hours (30 × 24) from job start
  </Step>

  <Step title="Example">
    Job on March 15 checks work since February 13
  </Step>

  <Step title="Use Case">
    Monthly quotas, long-term fatigue management
  </Step>
</Steps>

## Legal Compliance Examples

### EU Drivers' Hours

```json theme={null}
{
  "resources": [{
    "id": "eu-driver",
    "name": "EU Driver",
    "periodRules": [
      // Daily driving limit
      {
        "type": "MAX_DRIVE_TIME",
        "period": "DAY",
        "value": 32400  // 9 hours (can be extended to 10 twice a week)
      },
      // Weekly driving limit
      {
        "type": "MAX_DRIVE_TIME",
        "period": "WEEK",
        "value": 201600  // 56 hours
      },
      // Bi-weekly driving limit (approximated with month)
      {
        "type": "MAX_DRIVE_TIME",
        "period": "MONTH",
        "value": 324000  // 90 hours per 2 weeks
      },
      // Daily rest requirement (inverse of work time)
      {
        "type": "MAX_WORK_TIME",
        "period": "DAY",
        "value": 46800  // 13 hours max work (11 hours rest)
      }
    ],
    "shifts": [
      {
        "id": "shift1",
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T17:00:00Z"
      }
    ]
  }],
  "jobs": [
    {
      "id": "job1",
      "name": "Example Job"
    }
  ]
}
```

### US DOT Hours of Service

```json theme={null}
{
  "resources": [{
    "id": "us-driver",
    "name": "US Driver",
    "periodRules": [
      // 11-hour driving limit
      {
        "type": "MAX_DRIVE_TIME",
        "period": "DAY",
        "value": 39600  // 11 hours
      },
      // 14-hour on-duty limit
      {
        "type": "MAX_WORK_TIME",
        "period": "DAY",
        "value": 50400  // 14 hours
      },
      // 60-hour/7-day limit
      {
        "type": "MAX_WORK_TIME",
        "period": "WEEK",
        "value": 216000  // 60 hours
      },
      // 70-hour/8-day limit (approximated)
      {
        "type": "MAX_WORK_TIME",
        "period": "WEEK",
        "value": 252000,  // 70 hours
        "rollingDays": 8  // Custom period
      }
    ],
    "shifts": [
      {
        "id": "shift1",
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T17:00:00Z"
      }
    ]
  }],
  "jobs": [
    {
      "id": "job1",
      "name": "Example Job"
    }
  ]
}
```

## Soft vs Hard Enforcement

### Hard Limits (Default)

Jobs cannot be assigned if they would violate rules:

```json theme={null}
{
  "periodRules": [{
    "type": "MAX_DRIVE_TIME",
    "period": "DAY",
    "value": 32400,
    "hard": true  // Default
  }]
}
```

### Soft Limits

Allow violations with penalties:

```json theme={null}
{
  "periodRules": [{
    "type": "MAX_SERVICE_TIME",
    "period": "DAY",
    "value": 28800,
    "hard": false,
    "weight": 100  // Penalty per minute over limit
  }],
  "options": {
    "weights": {
      "periodRuleViolationWeight": 1.0
    }
  }
}
```

## Complex Scenarios

### Multi-Role Resources

Different rules for different activities:

```json theme={null}
{
  "resources": [{
    "id": "driver-installer",
    "name": "Driver Installer",
    "tags": [
      {"name": "driver", "hard": true},
      {"name": "installer", "hard": true}
    ],
    "periodRules": [
      // Driving limits
      {
        "type": "MAX_DRIVE_TIME",
        "period": "DAY",
        "value": 28800,  // 8 hours driving
        "tags": ["driver"]
      },
      // Installation limits
      {
        "type": "MAX_SERVICE_TIME",
        "period": "DAY",
        "value": 21600,  // 6 hours installing
        "tags": ["installer"]
      },
      // Overall work limit
      {
        "type": "MAX_WORK_TIME",
        "period": "DAY",
        "value": 36000  // 10 hours total
      }
    ],
    "shifts": [
      {
        "id": "shift1",
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T17:00:00Z"
      }
    ]
  }],
  "jobs": [
    {
      "id": "job1",
      "name": "Example Job"
    }
  ]
}
```

### Quota Management

Minimum service requirements:

```json theme={null}
{
  "resources": [{
    "id": "sales-rep",
    "name": "Sales Representative",
    "periodRules": [
      // Daily minimum visits
      {
        "type": "MIN_SERVICE_TIME",
        "period": "DAY",
        "value": 18000  // 5 hours customer time
      },
      // Weekly minimum
      {
        "type": "MIN_SERVICE_TIME",
        "period": "WEEK",
        "value": 108000  // 30 hours per week
      },
      // Don't overwork
      {
        "type": "MAX_WORK_TIME",
        "period": "DAY",
        "value": 36000  // 10 hours max
      }
    ],
    "shifts": [
      {
        "id": "shift1",
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T17:00:00Z"
      }
    ]
  }],
  "jobs": [
    {
      "id": "job1",
      "name": "Example Job"
    }
  ]
}
```

## Monitoring and Reporting

### Period Rule Status

Track rule compliance in solutions:

```json theme={null}
{
  "resourceStats": {
    "driver-1": {
      "periodRuleStatus": [
        {
          "rule": "MAX_DRIVE_TIME_DAY",
          "used": 28800,    // 8 hours used
          "limit": 32400,   // 9 hours allowed
          "remaining": 3600, // 1 hour remaining
          "utilization": 0.89
        },
        {
          "rule": "MAX_WORK_TIME_WEEK", 
          "used": 180000,   // 50 hours used
          "limit": 216000,  // 60 hours allowed
          "remaining": 36000, // 10 hours remaining
          "utilization": 0.83
        }
      ]
    }
  }
}
```

## Best Practices

<Steps>
  <Step title="Start Conservative">
    Set limits slightly below legal requirements for buffer
  </Step>

  <Step title="Consider Patterns">
    Account for typical work patterns and peak periods
  </Step>

  <Step title="Use Multiple Rules">
    Combine daily and weekly limits for comprehensive control
  </Step>

  <Step title="Monitor Utilization">
    Track how close resources get to limits
  </Step>

  <Step title="Plan Ahead">
    Consider future shifts when near limits
  </Step>
</Steps>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Jobs Not Assigned Due to Period Rules">
    **Symptoms**: Unassigned jobs with "PERIOD\_RULE\_VIOLATION" reason

    **Check**:

    * Current period usage for resources
    * Rule values vs job requirements
    * Hard vs soft rule configuration

    **Solutions**:

    * Add more resources
    * Adjust shift patterns
    * Convert to soft rules if appropriate
  </Accordion>

  <Accordion title="Unexpected Rule Violations">
    **Symptoms**: Rules violated despite seeming availability

    **Check**:

    * Rolling window calculations
    * Previous days' work history
    * All active rules for resource

    **Solutions**:

    * Verify historical data
    * Check period window logic
    * Review rule combinations
  </Accordion>

  <Accordion title="Performance Impact">
    **Symptoms**: Slow solving with period rules

    **Check**:

    * Number of rules per resource
    * Historical data lookup time
    * Complex rule combinations

    **Solutions**:

    * Limit rules to necessary ones
    * Use appropriate period types
    * Consider caching historical data
  </Accordion>
</AccordionGroup>

## Configuration Examples

### Fatigue Management

```json theme={null}
{
  "periodRules": [
    // Prevent excessive daily work
    {
      "type": "MAX_WORK_TIME",
      "period": "DAY",
      "value": 43200  // 12 hours
    },
    // Ensure adequate weekly rest
    {
      "type": "MAX_WORK_TIME",
      "period": "WEEK", 
      "value": 216000  // 60 hours
    },
    // Prevent continuous long days
    {
      "type": "MAX_DRIVE_TIME",
      "period": "DAY",
      "value": 32400,  // 9 hours
      "consecutiveDayLimit": 2  // Only 2 long days in a row
    }
  ]
}
```

### Productivity Targets

```json theme={null}
{
  "periodRules": [
    // Minimum daily productivity
    {
      "type": "MIN_SERVICE_TIME",
      "period": "DAY",
      "value": 21600,  // 6 hours
      "hard": false,
      "weight": 50
    },
    // Weekly targets
    {
      "type": "MIN_SERVICE_TIME",
      "period": "WEEK",
      "value": 126000,  // 35 hours
      "hard": false,
      "weight": 100
    }
  ]
}
```

## Pooled Rules (`groupTag`)

A period rule normally caps each declaring resource individually. Setting `groupTag` on a rule promotes it into a **pool**: the rule's limits then apply *collectively* across every resource that declares an identical rule with the same `groupTag`.

This is useful when a sub-group of resources needs a shared ceiling rather than per-resource caps — for example, "no more than 10 'Install' jobs per week across all contractors combined", regardless of how the work is divided among them.

```json theme={null}
{
  "resources": [
    {
      "name": "contractor-A",
      "rules": [{
        "period": { "from": "2024-01-01T00:00:00Z", "to": "2024-01-07T23:59:59Z" },
        "jobTypeLimitations": { "Install": 10 },
        "groupTag": "contractor-install-pool"
      }],
      "shifts": [ /* ... */ ]
    },
    {
      "name": "contractor-B",
      "rules": [{
        "period": { "from": "2024-01-01T00:00:00Z", "to": "2024-01-07T23:59:59Z" },
        "jobTypeLimitations": { "Install": 10 },
        "groupTag": "contractor-install-pool"
      }],
      "shifts": [ /* ... */ ]
    }
  ]
}
```

Both contractors share a single 10-job pool. Acceptable assignments include 10/0, 5/5, 7/3 — anything whose sum stays at or below 10.

**Rules for pool membership:**

* `groupTag` is a free identifier you choose; it is *not* related to `Resource.tags`.
* Every resource that should share the pool declares an identical rule (same period and same field values) with the same `groupTag`.
* The first declaration encountered is canonical. Any later declaration that doesn't match the canonical period or fields is **excluded** from the pool and a warning is logged — that resource simply doesn't participate. The remaining matching resources still form the pool.
* A pool with one declaring resource behaves like a per-resource rule.
* A resource may belong to multiple pools by declaring multiple rules with different `groupTag` values.
* All rule fields (`min/maxWorkTime`, `min/maxServiceTime`, `min/maxDriveTime`, `min/maxJobComplexity`, `jobTypeLimitations`) apply collectively when pooled.

## Related Features

<CardGroup cols={2}>
  <Card title="Resource Management" icon="users" href="/guides/vrp/features/resource-management">
    Basic resource configuration
  </Card>

  <Card title="Break Management" icon="coffee" href="/guides/vrp/features/break-management">
    Daily break requirements
  </Card>

  <Card title="Advanced Constraints" icon="shield" href="/guides/vrp/features/advanced-constraints">
    Other resource constraints
  </Card>

  <Card title="Time Scheduling" icon="calendar" href="/guides/vrp/features/time-scheduling-advanced">
    Multi-day shift patterns
  </Card>
</CardGroup>
