Business Rules¶
Business rules define the invariants and constraints of the domain. They must be enforced regardless of which use case or API endpoint triggers them — typically in the domain layer, never only in controllers or validators.
BR-001: Task Title Is Required¶
Category: Invariant
Statement: A Task must always have a non-blank title.
Rationale: The title is the primary human-readable identifier of a task; without it a task cannot be meaningfully displayed or managed.
Applies to: Task
Violated when: title is null, empty, or contains only whitespace characters.
Error code: TASK_TITLE_REQUIRED — "Task title is required"
| Valid | Invalid |
|---|---|
"Fix login bug" |
"" (empty) |
"Update documentation" |
" " (blanks) |
null |
BR-002: Task Title Maximum Length¶
Category: Invariant
Statement: A Task title must not exceed 100 characters.
Rationale: Enforces a consistent UI layout and prevents accidental misuse of the title field as a description field.
Applies to: Task
Violated when: title.length() is greater than 100.
Error code: TASK_TITLE_TOO_LONG — "Task title must not exceed 100 characters"
| Valid | Invalid |
|---|---|
"Fix login bug" (13 chars) |
A title with 101 or more characters |
| A title with exactly 100 characters |
BR-003: Task Description Maximum Length¶
Category: Invariant
Statement: When present, a Task description must not exceed 500 characters.
Rationale: Keeps descriptions concise and prevents the API payload from growing unbounded.
Applies to: Task
Violated when: description is non-null and description.length() is greater than 500.
Error code: TASK_DESCRIPTION_TOO_LONG — "Task description must not exceed 500 characters"
| Valid | Invalid |
|---|---|
null (omitted) |
A description with 501 or more characters |
"" (empty string, treated as absent) |
|
| A description with exactly 500 characters |
BR-004: Task Status Must Be a Valid Enum Value¶
Category: Invariant
Statement: A Task status must always be one of TODO, IN_PROGRESS, or DONE.
Rationale: The status drives UI display and filtering; unknown values would break client rendering.
Applies to: Task
Violated when: status is null or not one of the three defined TaskStatus enum values.
Error code: TASK_STATUS_INVALID — "Task status must be one of: TODO, IN_PROGRESS, DONE"
| Valid | Invalid |
|---|---|
TODO |
null |
IN_PROGRESS |
"PENDING" |
DONE |
"" |
BR-005: Task ID Is Immutable After Creation¶
Category: Invariant
Statement: The id of a Task must not be changed after the Task has been persisted.
Rationale: The ID is the stable reference used by clients; mutating it would break all existing bookmarks and references.
Applies to: Task
Violated when: Code attempts to set or overwrite the id field of an already-persisted Task.
Error code: TASK_ID_IMMUTABLE — "Task ID cannot be changed"
| Valid | Invalid |
|---|---|
| ID assigned by persistence layer on insert | Overwriting id during an update operation |
BR-006: Task Due Date Is Optional¶
Category: Policy
Statement: A Task may be created or updated without specifying a dueDate; when provided,
the value must be a valid calendar date.
Rationale: Not all tasks have deadlines; forcing a due date would create unnecessary friction for the User.
Applies to: Task
Violated when: A dueDate value is provided that cannot be parsed as a valid ISO 8601
calendar date (e.g., "2026-13-01", "not-a-date").
Error code: TASK_DUE_DATE_INVALID — "Task due date must be a valid date (ISO 8601)"
| Valid | Invalid |
|---|---|
null (omitted) |
"2026-13-01" |
"2026-06-30" |
"not-a-date" |
"2026-12-31" |
"2026-02-30" |