CRUD Service Patterns
Relevant source files
The following files were used as context for generating this wiki page:
The CRUD Service Patterns in this project define a standardized architecture for managing entities across the .NET backend and the TanStack Start frontend. This pattern ensures consistency in how data is created, retrieved, updated, and archived, utilizing a layered approach that separates API endpoints, business logic services, and data persistence.
The implementation focuses on modularity, where each domain (e.g., Customers, Users, Contracts) follows a similar structural blueprint. This includes server-side pagination, sorting, search capabilities, and a "soft-delete" mechanism referred to as archiving.
Backend Architecture
The backend follows a modular service-based pattern. Each module typically consists of an Endpoints class for routing and a Service class for business logic and database interactions.
Service Layer Logic
The CustomerService exemplifies the core CRUD operations. It utilizes an AppDbContext for data persistence and a CounterService for generating sequential, human-readable entity numbers.
- Read (GetAll): Implements filtering by search terms, sorting by specific fields, and pagination.
- Read (GetById): Retrieves a single record by its GUID.
- Create: Validates the request, increments a sequential counter, and persists the new entity.
- Update: Modifies existing entity fields while preserving immutable data like entity numbers.
- Archive/Unarchive: Updates an
IsArchivedboolean flag rather than performing physical deletion.
Sources: [packages/api/Modules/Customers/CustomerService.cs](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/packages/api/Modules/Customers/CustomerService.cs), [packages/api/Modules/Customers/CustomerEndpoints.cs](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/packages/api/Modules/Customers/CustomerEndpoints.cs)
API Endpoint Structure
Endpoints are mapped using a group-based approach. They leverage TypedResults for strongly-typed HTTP responses and incorporate validation filters.
The diagram shows the standard flow of an API request through the validation and service layers.
Sources: [packages/api/Modules/Customers/CustomerEndpoints.cs:11-75](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/packages/api/Modules/Customers/CustomerEndpoints.cs#L11-L75)
Frontend Implementation
The frontend utilizes TanStack Start and TanStack Form to interface with the backend services. It relies on Zod for schema validation and auto-generated TypeScript types from the OpenAPI specification.
Server Functions
Frontend "Server Functions" act as the bridge between the UI and the API. They wrap API calls and handle input validation using Zod schemas.
| Function | Method | Description |
|---|---|---|
fetchCustomers | GET | Retrieves paginated list with sorting/search. |
fetchCustomerById | GET | Retrieves a single customer or null if 404. |
createCustomerFn | POST | Submits new customer data. |
updateCustomerFn | POST | Updates existing customer via UUID and data object. |
archiveCustomerFn | POST | Triggers the archive patch endpoint. |
Sources: [packages/web/src/features/customers/customers.functions.ts:9-52](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/packages/web/src/features/customers/customers.functions.ts#L9-L52), [packages/web/CLAUDE.md:14-16](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/packages/web/CLAUDE.md#L14-L16)
Form Pattern
Forms are managed via @tanstack/react-form and validated using Zod adapters. A specific convention is followed to prevent UI drift: labels, inputs, and error messages are rendered using a standardized FieldError component.
Sources: [packages/web/CLAUDE.md:10-12](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/packages/web/CLAUDE.md#L10-L12), [REVIEW.md:65-88](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/REVIEW.md#L65-L88)
Data Patterns and Schemas
Common Data Fields
Entities across different modules share common attributes to support the CRUD patterns.
| Field | Type | Description |
|---|---|---|
Id | Guid / UUID | Primary unique identifier. |
Number | int / number | Sequential human-readable ID (e.g., 100001). |
IsArchived | bool / boolean | Flag for soft-deletion; defaults to false. |
Sources: [packages/web/src/api/schema.ts:635-646](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/packages/web/src/api/schema.ts#L635-L646), [packages/api/Modules/Customers/CustomerService.cs](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/packages/api/Modules/Customers/CustomerService.cs)
Sequencing and Counters
The project uses a dedicated Counters table to maintain sequential numbers for entities like Customers and Contracts. This avoids reliance on database-specific auto-incrementing identity columns for business-facing IDs.
This sequence illustrates how sequential numbers are safely generated during entity creation.
Sources: [packages/api/Modules/Customers/CustomerService.cs:46-48](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/packages/api/Modules/Customers/CustomerService.cs#L46-L48), [packages/api.tests/Customers/CustomerServiceTests.cs:175-182](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/packages/api.tests/Customers/CustomerServiceTests.cs#L175-L182)
Architecture Best Practices
Based on project reviews, several patterns were established to improve the CRUD implementation:
- Module Configuration: Move database and service registration into per-module extension methods (e.g.,
AddCustomerModule) to clean upProgram.cs. - DTO Usage: Decouple API contracts from database entities using Request/Response DTOs to avoid exposing internal schema details.
- Strict OpenAPI: Configure JSON serialization and schema transformers to ensure TypeScript types correctly reflect nullability and required fields.
Sources: [REVIEW.md:5-30](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/REVIEW.md#L5-L30), [REVIEW.md:52-56](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/REVIEW.md#L52-L56), [REVIEW.md:92-120](https://github.com/cmdras/tsz/blob/c1e50ac7a5129c520f1c656299da5323ceee70e3/REVIEW.md#L92-L120)
Conclusion
The CRUD Service Patterns in this repository provide a robust framework for entity management. By strictly separating concerns between the service logic, API definitions, and frontend forms, the architecture remains maintainable and scalable. The use of sequential counters for business IDs and a standardized soft-delete (archiving) mechanism are central to the system's data integrity and user experience.