This document provides an overview of the CRUD API endpoints built for the JobTracker application using ASP.NET Core Controllers.
http://localhost:5138
The API includes OpenAPI/Swagger documentation available at:
http://localhost:5138/openapi/v1.json
Endpoints:
GET /api/users- Get all active usersGET /api/users/{id}- Get user by IDPOST /api/users- Create new userPUT /api/users/{id}- Update userDELETE /api/users/{id}- Archive user (soft delete)GET /api/users/archived- Get archived usersPOST /api/users/{id}/restore- Restore archived user
DTOs:
UserDto- Full user representationCreateUserDto- User creation payloadUpdateUserDto- User update payload (partial)
Endpoints:
GET /api/companies- Get all active companiesGET /api/companies/{id}- Get company by IDPOST /api/companies- Create new companyPUT /api/companies/{id}- Update companyDELETE /api/companies/{id}- Archive company (soft delete)POST /api/companies/{id}/external-ids- Add external ID to companyGET /api/companies/archived- Get archived companiesPOST /api/companies/{id}/restore- Restore archived companyGET /api/companies/{id}/job-postings- Get job postings for company
DTOs:
CompanyDto- Full company representationCreateCompanyDto- Company creation payloadUpdateCompanyDto- Company update payload (partial)AddExternalIdDto- External ID addition payload
Endpoints:
GET /api/jobpostings- Get all active job postingsGET /api/jobpostings/{id}- Get job posting by IDPOST /api/jobpostings- Create new job postingPUT /api/jobpostings/{id}- Update job postingDELETE /api/jobpostings/{id}- Archive job posting (soft delete)POST /api/jobpostings/{id}/external-ids- Add external ID to job postingPOST /api/jobpostings/{id}/salary-range- Set salary range for job postingPOST /api/jobpostings/{id}/language-requirements- Add language requirementGET /api/jobpostings/archived- Get archived job postingsPOST /api/jobpostings/{id}/restore- Restore archived job postingGET /api/jobpostings/search- Search job postings with filters
DTOs:
JobPostingDto- Full job posting representationCreateJobPostingDto- Job posting creation payloadUpdateJobPostingDto- Job posting update payload (partial)AddExternalIdDto- External ID addition payloadSetSalaryRangeDto- Salary range setting payloadAddLanguageRequirementDto- Language requirement addition payload
Endpoints:
GET /api/jobapplications- Get all active job applications (with optional filters: userId, jobPostingId, status)GET /api/jobapplications/{id}- Get job application by IDPOST /api/jobapplications- Create new job applicationPUT /api/jobapplications/{id}- Update job applicationDELETE /api/jobapplications/{id}- Archive job application (soft delete)PUT /api/jobapplications/{id}/status- Update application statusPOST /api/jobapplications/{id}/notes- Add note to applicationPUT /api/jobapplications/{id}/followup- Schedule follow-upPOST /api/jobapplications/{id}/followup- Record follow-upGET /api/jobapplications/archived- Get archived job applicationsPOST /api/jobapplications/{id}/restore- Restore archived job applicationGET /api/jobapplications/stats- Get application statistics (with optional userId filter)
DTOs:
JobApplicationDto- Full job application representationCreateJobApplicationDto- Job application creation payloadUpdateJobApplicationDto- Job application update payload (partial)UpdateApplicationStatusDto- Status update payloadAddApplicationNoteDto- Note addition payloadScheduleFollowUpDto- Follow-up scheduling payloadRecordFollowUpDto- Follow-up recording payload
Application Status Values:
0- Applied1- InReview2- PhoneScreening3- TechnicalInterview4- OnSiteInterview5- FinalInterview6- Offered7- Accepted8- Rejected9- Withdrawn
All entities support soft deletion through the ArchivedAt property:
- DELETE operations set
ArchivedAttimestamp instead of removing records - GET operations exclude archived records by default
- Restore endpoints allow unarchiving records
The API properly handles domain value objects:
ExternalId- System/Value pairs for external referencesSalaryRange- Min/Max salary with currency and periodLanguageRequirement- Language code with proficiency level
- Companies can have multiple JobPostings
- JobPostings belong to a Company
- Proper validation ensures referential integrity
- 404 responses for non-existent or archived resources
- 400 responses for invalid requests or validation errors
- Proper HTTP status codes for all operations
- Company existence validation for job posting operations
- Value object creation validation (ExternalId, SalaryRange, LanguageRequirement)
- Required field validation through DTOs
POST /api/users
Content-Type: application/json
{
"displayName": "John Doe",
"type": 0,
"active": true
}POST /api/companies
Content-Type: application/json
{
"name": "Tech Corp",
"description": "A technology company",
"location": "San Francisco",
"employeeCount": 150,
"externalIds": [
{
"system": "LinkedIn",
"value": "tech-corp"
}
]
}POST /api/jobapplications
Content-Type: application/json
{
"userId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"jobPostingId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": 0,
"notes": "Applied through LinkedIn",
"applicationSource": "LinkedIn",
"expectedSalaryMin": 80000,
"expectedSalaryMax": 100000,
"salaryCurrency": "USD"
}PUT /api/jobapplications/{id}/status
Content-Type: application/json
{
"status": 3
}POST /api/jobapplications/{id}/notes
Content-Type: application/json
{
"note": "Had a great phone interview, waiting for next steps"
}GET /api/jobpostings/search?title=developer&location=remote&contractType=0GET /api/jobapplications?userId=3fa85f64-5717-4562-b3fc-2c963f66afa6&status=1GET /api/jobapplications/stats?userId=3fa85f64-5717-4562-b3fc-2c963f66afa6- Controllers handle HTTP concerns only
- Business logic resides in domain entities
- DTOs provide clean API contracts
- Mapping extensions handle entity/DTO conversions
- In-memory database for development
- Async operations throughout
- Proper navigation property loading
- Configuration through Fluent API
- Controller-based routing
- Model binding and validation
- OpenAPI/Swagger integration
- Dependency injection for DbContext