Contracts & Tasks
Relevant source files
The following files were used as context for generating this wiki page:
- packages/api/Modules/Contracts/Contract.cs
- packages/api/Modules/Contracts/ContractEndpoints.cs
- packages/api/Modules/Contracts/ContractService.cs
- packages/api/Modules/Contracts/ContractTask.cs
- packages/api/Modules/Contracts/ContractContracts.cs
- packages/web/src/features/contracts/contracts.server.ts
- packages/web/src/features/contracts/contracts.functions.ts
- packages/api/Migrations/AppDb/20260515084245_AddContractsAndCounters.Designer.cs
The Contracts & Tasks module facilitates the management of professional agreements between customers and consultants. It serves as a central registry for tracking contract durations, financial terms (day rates), and the specific breakdown of assignments through tasks. This module integrates with the Customers and Users modules to associate legal entities and personnel with specific project scopes.
Contracts are identified by unique, sequentially generated numbers and include metadata such as subjects, start dates, and optional end dates. Each contract contains one or more tasks, which represent the billable components of the agreement.
Sources: packages/api/Modules/Contracts/Contract.cs, packages/api/Modules/Contracts/ContractService.cs:81-86, CHANGELOG.md:16
Data Architecture
The system uses a relational model where a Contract acts as a parent entity for multiple ContractTask records. Contracts maintain foreign key relationships with Customer (the client) and User (acting as the Consultant).
Entity Relationships
The diagram illustrates the ownership of tasks by contracts and the external references to customers and consultants.
Sources: packages/api/Modules/Contracts/Contract.cs:7-19, packages/api/Modules/Contracts/ContractTask.cs:5-12, packages/api/Migrations/AppDb/20260515084245_AddContractsAndCounters.Designer.cs:175-197
Data Model Details
| Entity | Field | Type | Description |
|---|---|---|---|
| Contract | Number | int | Unique sequential identifier generated via CounterService. |
CustomerId | Guid | Reference to the associated Customer entity. | |
ConsultantId | Guid | Reference to the User (Consultant) assigned to the contract. | |
Subject | string | Brief description of the contract purpose. | |
IsArchived | bool | Soft-deletion flag; defaults to false. | |
| ContractTask | Name | string | The title of the specific task. |
DayRate | decimal | The financial rate assigned to the task. | |
Order | int | Display order within the contract's task list. |
Sources: packages/api/Modules/Contracts/Contract.cs, packages/api/Modules/Contracts/ContractTask.cs, packages/api/Modules/Contracts/ContractContracts.cs:23-45
Business Logic & Validation
The ContractService enforces strict business rules during the creation and modification of contracts. These rules ensure data integrity and organizational constraints.
- Consultant Eligibility: A consultant must be an active user and cannot hold the
ClientManagerrole. - Customer Validity: Contracts can only be created for non-archived customers.
- Temporal Logic: The
StartDatemust be chronologically before or equal to theEndDate(if provided). - Task Requirement: Every contract must contain at least one task.
- Task Integrity: During updates, the service verifies that any provided Task IDs actually belong to the contract being modified.
Sources: packages/api/Modules/Contracts/ContractService.cs:166-184, packages/api/Modules/Contracts/ContractService.cs:119-122
Creation Flow
The creation process ensures all relational constraints and business rules are met before persisting data.
Sources: packages/api/Modules/Contracts/ContractService.cs:79-102
API Endpoints
The module exposes a RESTful API under the /api/contracts prefix. It supports standard CRUD operations with specific actions for archiving.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/contracts | Retrieves a paged list of contracts with search and sort filters. |
GET | /api/contracts/{id} | Retrieves a single contract including its tasks. |
POST | /api/contracts | Creates a new contract and associated tasks. |
PUT | /api/contracts/{id} | Updates an existing contract and manages task synchronization. |
PATCH | /api/contracts/{id}/archive | Soft-deletes a contract. |
PATCH | /api/contracts/{id}/unarchive | Restores an archived contract. |
Sources: packages/api/Modules/Contracts/ContractEndpoints.cs:14-100
Task Synchronization Logic
When updating a contract, the system performs a differential update on the tasks. Existing tasks not included in the update request are marked as IsArchived. New tasks (those without an ID) are added, and existing tasks are updated in place.
Sources: packages/api/Modules/Contracts/ContractService.cs:124-150
Frontend Integration
The web application interacts with the API through TanStack Start server functions. The UI provides a specialized form for managing the complex relationship between a contract and its dynamic list of tasks.
Client-Side State Management
The contracts.functions.ts file acts as the bridge, transforming UI input (like Zod-validated forms) into the request formats expected by the C# backend.
The sequence shows the transformation and communication flow from the user interface to the database.
Sources: packages/web/src/features/contracts/contracts.functions.ts:14-30, packages/web/src/routes/_authed/admin/contracts/-components/form.tsx:32-42
Summary
The Contracts & Tasks module provides a robust framework for managing consultancy agreements. By utilizing a shared counter service for numbering and enforcing strict role-based validation for consultants, it ensures consistency across the platform. The architecture supports complex task management within a single contract context, allowing for detailed financial and operational tracking.
Sources: packages/api/Modules/Contracts/ContractService.cs, packages/api/Common/Counters/CounterService.cs