Create Requirement
Method
REST method is adopted.
HTTP Method
POST: Create requirement (file upload)
Naming Convention
To unify the naming of query parameters and nodes and improve readability, snake_case is used for URIs and JSON nodes in requests.
Request and Response
Headers
Meta information is set in HTTP headers, not in the response body.
Request Headers
AuthorizationContent-Type(multipart/form-data)AcceptAccept-language
Response Headers
Content-Type
Create Requirement
URI
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| organization_id | integer | Required | Organization ID |
| project_id | integer | Required | Project ID |
Request Body
The request body is multipart/form-data.
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | Required | Requirement name (unique within project) |
| file | file | Required | Requirement file |
Response
The response is JSON (HTTP status: 201 Created).
{
"id": "requirement-uuid",
"projectId": 1,
"name": "My Requirement",
"s3Key": "1/1/requirement/requirement-uuid",
"createdAt": 1234567890000,
"updatedAt": 1234567890000,
"deletedAt": null,
"createdBy": "user-cognito-sub",
"updatedBy": "user-cognito-sub",
"deletedBy": null
}
Response Fields
| Name | Type | Description |
|---|---|---|
| id | string | Requirement UUID |
| projectId | number | Project ID |
| name | string | Requirement name |
| s3Key | string | null | S3 object key |
| createdAt | number | Creation timestamp (epoch milliseconds) |
| updatedAt | number | Update timestamp (epoch milliseconds) |
| deletedAt | number | null | Deletion timestamp (epoch milliseconds); null if not deleted |
| createdBy | string | Creator user ID |
| updatedBy | string | Updater user ID |
| deletedBy | string | null | Deleter user ID; null if not deleted |
Authentication
Authentication is performed using JSON Web Tokens (JWT) issued by Amazon Cognito.
Error Handling
The status codes for error handling are as follows.
| Description | Status Code | Status Name |
|---|---|---|
| Invalid request (name not specified, file not attached, etc.) | 400 | Bad Request |
| Missing credentials | 401 | Unauthorized |
| Insufficient permissions | 403 | Forbidden |
| Project or organization not found | 404 | Not Found |
| Requirement name already exists within the project | 409 | Conflict |
| Internal server error | 500 | Internal Server Error |
Processing Flow
- Extract organization ID and project ID from path parameters
- Retrieve name and file from request body
- Verify the user has write access to the project
- Verify name is unique within the project
- Upload file to S3 under the
{organization_id}/{project_id}/requirement/prefix - Create requirement record (name, s3_key, etc.) in RDS
- Return the created requirement information
Detailed Flowchart
flowchart TD
Start([POST Request]) --> Route[Route Handler]
Route --> Auth[Auth & Parameter Extraction]
Auth --> Service[Service Layer]
Service --> AccessCheck[Access Check]
AccessCheck --> HasAccess{Write permission?}
HasAccess -->|No| Err404[404 Not Found]
HasAccess -->|Yes| Validate{name & file validation}
Validate -->|NG| Err400[400 Bad Request]
Validate -->|OK| UniqueCheck{name unique?}
UniqueCheck -->|NG| Err409[409 Conflict]
UniqueCheck -->|OK| UploadS3["Upload file to S3<br/>{organization_id}/{project_id}/requirement/{requirement_id}"]
UploadS3 --> S3OK{Successful?}
S3OK -->|NG| Err500[500 Internal Server Error]
S3OK -->|OK| CreateRDS[Create record in RDS<br/>name, s3_key, etc.]
CreateRDS --> Success[201 Created]