[Canonical page](<https://docs.dhtmlx.com/planning-engine/modeling/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# Modeling a plan

Planning Engine works from a description of work: what needs doing, what depends on it, when work can happen, and who's assigned. How you model those things decides what the engine can schedule and which improvements it can suggest.

These pages follow a small delivery project. Ann implements a feature and writes its guide; Ben reviews the result. They work different hours, and at first Ann has more work booked on Monday afternoon than she can do.

## Tasks, milestones, and summaries

A **task** has a working duration and dates. The duration is how much working time the task takes. The start and finish are its span on the timeline, and that span can also include nights, weekends, breaks, and leveling pauses.

For example, take a calendar with four working hours each morning and four each afternoon. An eight-hour task that starts Monday at 13:00 finishes Tuesday at 12:00. That's eight working hours spread across a 23-hour span.

A **milestone** marks a single moment, like "Ready to release." It has zero duration and books no resource load. You can connect milestones to tasks with dependencies, the same way you connect tasks to each other.

A **summary** groups child tasks. It normally spans from the earliest child start to the latest child finish, so it's a good fit for phases or deliverables. Its duration comes from that span. It isn't the sum of the children's durations, since two children can run at the same time.

Summaries take part in scheduling, too. A dependency on a summary can affect its descendants, and the engine can move a whole group together. You can give a summary manual dates and it'll keep them. But those dates don't stop its children from running outside them.

**API:** `TaskData` - [Rust](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/task-data.md>) · [WASM](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/task-data.md>) · [JS](<https://docs.dhtmlx.com/planning-engine/js/api/types/task-data.md>) · [.NET](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/task-data.md>) · [Java](<https://docs.dhtmlx.com/planning-engine/java/api/data/task-data.md>)

## Dependencies and date constraints

A dependency describes how two pieces of work relate. The engine supports four relationships:

| Relationship | Meaning | Example |
|---|---|---|
| Finish-to-start | The successor can't start before the predecessor finishes. | Review follows implementation. |
| Start-to-start | The successor can't start before the predecessor starts. | Documentation can begin when implementation begins. |
| Finish-to-finish | The successor can't finish before the predecessor finishes. | Final verification must finish after the work it verifies. |
| Start-to-finish | The successor can't finish before the predecessor starts. | An existing service continues until its replacement starts. |

A **lag** adds working time to the relationship. A negative lag lets the tasks overlap. Lag is a fixed amount of working time. It's not a percentage of the task's duration, and it doesn't count elapsed time over a weekend.

A **date constraint** sets a requirement that doesn't depend on another task: start no earlier than Tuesday, finish no later than Friday, or start at an exact moment. The engine also supports early and late scheduling preferences.

Constraints only affect scheduling when you enable them. Once they're on, hard constraints win over conflicting dependencies, and the engine reports the conflict. So "must finish on Friday" doesn't guarantee that all the predecessor work actually fits before Friday. There's no soft deadline in the model, meaning one that warns you without limiting where the task goes.

**API:** `LinkData` - [Rust](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/link-data.md>) · [WASM](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/link-data.md>) · [JS](<https://docs.dhtmlx.com/planning-engine/js/api/types/link-data.md>) · [.NET](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/link-data.md>) · [Java](<https://docs.dhtmlx.com/planning-engine/java/api/data/link-data.md>)

## Calendars and working time

A calendar describes working weekdays, daily hours, breaks, and exceptions for specific dates. You can use calendars for holidays, short days, or overnight shifts. The default calendar works Monday through Friday, 08:00-12:00 and 13:00-17:00.

By default, each assignment follows its resource's calendar. If you give the task its own calendar, work is limited to the time both calendars share. A resource without a calendar follows the task's calendar. A task without a calendar uses the global calendar as its reference.

When you assign several people with different calendars, each of them works the task's full duration on their own effective calendar. The task spans all their placements and finishes when the last person finishes. So adding someone with limited availability can make the span longer. The engine doesn't split a fixed amount of effort between people.

In this demo, each person has their own working week. Change someone's working days or give them a day off, and their tasks reshape around the new calendar:

![A Gantt chart above a row of working-week calendars, one per person; each task bar follows the calendar of the person assigned to it](<https://docs.dhtmlx.com/planning-engine/assets/resource-calendars.webp>)

Your application can switch to task-only calendars instead, optionally inherited from a parent task. In that mode, resource calendars don't affect placement. You can also turn calendars off completely and get a flat 24/7 timeline.

Pick units that match the work you're modeling. Hours and minutes count working minutes. An engine **day** counts one working date, however long it is. It's not a shortcut for eight hours. The examples here use hours so you can see morning and afternoon work clearly.

The engine uses local dates with minute precision. It doesn't convert time zones or handle daylight saving time. If your application deals with several time zones, agree on a common calendar convention before you schedule.

**API:** `CalendarData` - [Rust](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/calendar-data.md>) · [WASM](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/calendar-data.md>) · [JS](<https://docs.dhtmlx.com/planning-engine/js/api/types/calendar-data.md>) · [.NET](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/calendar-data.md>) · [Java](<https://docs.dhtmlx.com/planning-engine/java/api/data/calendar-data.md>)

## Resources, capacity, and assignments

A **resource** is someone or something with limited capacity. An **assignment** books part of that capacity for a task.

Capacity and assignment load use the same scale. A person with capacity 1 can take one assignment at 1, or two assignments at 0.5 each at the same time. You can model a team as capacity 8, where an assignment of 2 uses a quarter of the team.

An assignment's value is a utilization rate, not a number of effort hours. If you change an assignment from 1 to 0.5, the booked load drops, but the task's duration doesn't double. Adding a second person doesn't cut the duration in half, either. Your application supplies the duration the task needs.

Resource changes can still shift dates through calendars. Move a task from Ann's full-day calendar to Ben's afternoon-only calendar, and the same working duration takes more calendar days to fit.

**API:** `ResourceData` - [Rust](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/resource-data.md>) · [WASM](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#resourcedata>) · [JS](<https://docs.dhtmlx.com/planning-engine/js/api/types/common.md#resourcedata>) · [.NET](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/resource-data.md>) · [Java](<https://docs.dhtmlx.com/planning-engine/java/api/data/resource-data.md>)

### Assigning only part of a task

An assignment can cover just a slice of the task's working duration. On an eight-hour task, you might book one person for the first four working hours and someone else for the last four.

Slices follow working time, so they skip calendar breaks and task pauses. They're cut off at the task's end and move along with its work. A slice changes resource load. It doesn't change the task's required duration or its dependencies. An assigned resource's calendar still counts for task placement, even when that resource's slice books no work.

Here, Build has four parts: one person hands off the design on day 1, two developers build from day 2, and a tester joins at half capacity from day 6. The task's dates stay put. Only the load under it moves:

![A Gantt chart where the Build task shows four assignment slices underneath it, one per person, and an overload strip flags where a half-time slice collides with other work](<https://docs.dhtmlx.com/planning-engine/assets/assignment-parts.webp>)

**API:** `AssignmentData` - [Rust](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/assignment-data.md>) · [WASM](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/assignment-data.md>) · [JS](<https://docs.dhtmlx.com/planning-engine/js/api/types/assignment-data.md>) · [.NET](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/assignment-data.md>) · [Java](<https://docs.dhtmlx.com/planning-engine/java/api/data/assignment-data.md>)

## Fixed, completed, and unscheduled work

These states do different jobs:

| State | Scheduling effect | Resource effect |
|---|---|---|
| Manually scheduled/fixed | Dates stay fixed; other tasks can depend on them. | Assignments still consume capacity. |
| Completed, with progress-aware scheduling enabled | Completed tasks stay fixed, including within moving groups. | Their booked work remains represented. |
| Unscheduled | Task and descendants are excluded from the active schedule. | Their assignments are inactive and book no load. |

Unscheduled work stays in the plan data, so you can bring it back later. A fixed task, on the other hand, stays in the active plan.

Partial progress isn't tracked as separate remaining work. A task marked 50% complete can still move as a whole. The engine doesn't keep the finished half in place or move only the unfinished part after a status date.

## Build the example plan

The delivery project has two people:

| Person | Working calendar | Skills | Capacity |
|---|---|---|---|
| Ann | Mon-Fri, 08:00-12:00 and 13:00-17:00 | Implementation, documentation | 1 |
| Ben | Mon-Fri, 13:00-17:00 | Documentation, review | 1 |

Every assignment books the person's full capacity. None of the tasks has its own calendar, so the assigned people's calendars decide the working time.

| Task | Duration | Dependencies | Initial assignment |
|---|---|---|---|
| Design | 4 hours | Starts Monday at 08:00 | Ann |
| Implement | 8 hours | After Design | Ann |
| Write guide | 4 hours | After Design | Ann |
| Review | 4 hours | After Implement | Ben |
| Ready to release | Milestone | After Review and Write guide | None |


All tasks sit under one delivery summary. Use forward scheduling, close gaps you can avoid, and check load by the hour. No task is fixed or completed, and there are no hard date constraints.

The dependencies let Implement and Write guide start at the same time. Both are assigned to Ann, though, and that's the resource problem the next pages work through.

**API:** `ProjectData` - [Rust](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/project-data.md>) · [WASM](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/project-data.md>) · [JS](<https://docs.dhtmlx.com/planning-engine/js/api/types/project-data.md>) · [.NET](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/project-data.md>) · [Java](<https://docs.dhtmlx.com/planning-engine/java/api/data/project-data.md>)

## Modeling boundaries

The engine handles dates, working calendars, resource rates, and assignment choices. It doesn't calculate task duration from effort and staffing, track actual or remaining work, or change resource capacity over date ranges. Calendars use literal date exceptions, not recurring holiday rules or inherited base calendars.

Keep these limits in mind when you move an existing planning model to the engine. If you need effort calculations or recurring calendars, handle them in your application and send the engine the resulting durations and calendars.

Continue with [Scheduling work](<https://docs.dhtmlx.com/planning-engine/scheduling.md>). For a broader feature comparison, see [MS Project parity](<https://docs.dhtmlx.com/planning-engine/ms-project-parity.md>).
