Skip to content

Commit 93450d7

Browse files
marc0derclaude
andcommitted
docs: add prompt for idempotent post and enhanced delete endpoints
Co-Authored-By: Claude <[email protected]>
1 parent b491a01 commit 93450d7

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Idempotent POST and Enhanced DELETE Endpoints
2+
3+
*The SDKMAN State API currently returns NO_CONTENT (204) for both successful POSTs and DELETEs, regardless of whether data was created/deleted or already existed. This implementation needs to be changed to provide proper idempotent POST behavior with CREATED (201) status and enhanced DELETE behavior with NOT_FOUND (404) status when attempting to delete non-existent entries, following REST API best practices for data mutation operations.*
4+
5+
## Requirements
6+
7+
- POST /versions should always succeed and return CREATED (201) status, even if the version already exists (idempotent behavior)
8+
- POST /versions should overwrite any existing version entry with the same unique key (candidate, version, vendor, platform)
9+
- DELETE /versions should return NO_CONTENT (204) when successfully deleting an existing version
10+
- DELETE /versions should return NOT_FOUND (404) when attempting to delete a non-existent version
11+
- All validation rules must remain intact for both endpoints
12+
- Authentication requirements must remain unchanged
13+
- Database operations should handle upsert behavior for POST operations
14+
15+
## Rules
16+
17+
- rules/kotlin.md
18+
- rules/kotest.md
19+
20+
## Domain
21+
22+
Core domain entities remain unchanged
23+
24+
## Testing Considerations
25+
26+
*All existing tests must pass with updated expectations for HTTP status codes. New tests should cover the enhanced behavior scenarios.*
27+
28+
*Test coverage should include:*
29+
- Idempotent POST behavior (multiple POSTs of same version should succeed with 201)
30+
- POST overwriting existing version data with different URL/visibility/checksums
31+
- DELETE returning 404 for non-existent versions
32+
- DELETE returning 204 for successful deletions
33+
- Edge cases around vendor presence/absence in unique keys
34+
- Concurrent operations and transaction handling
35+
36+
## Implementation Notes
37+
38+
*Prefer using database-level UPSERT mechanisms (PostgreSQL's ON CONFLICT clause) for efficient idempotent POST operations. The repository layer should be enhanced to support both create/update operations and return operation metadata to the API layer for appropriate status code determination.*
39+
40+
*Use Exposed ORM's insertIgnore or upsert capabilities where available, or raw SQL with ON CONFLICT clauses. Maintain separation of concerns between validation, business logic, and data access layers.*
41+
42+
## Specification by Example
43+
44+
### Idempotent POST Behavior
45+
46+
#### Vendored
47+
48+
```http
49+
POST /versions
50+
Authorization: Basic dGVzdHVzZXI6cGFzc3dvcmQxMjM=
51+
Content-Type: application/json
52+
53+
{
54+
"candidate": "java",
55+
"version": "17.0.1",
56+
"platform": "LINUX_X64",
57+
"url": "https://example.com/java-17.0.1.tar.gz",
58+
"visible": true,
59+
"vendor": "temurin"
60+
}
61+
62+
Response: 201 CREATED
63+
```
64+
65+
```http
66+
# Same POST request repeated
67+
POST /versions
68+
Authorization: Basic dGVzdHVzZXI6cGFzc3dvcmQxMjM=
69+
Content-Type: application/json
70+
71+
{
72+
"candidate": "java",
73+
"version": "17.0.1",
74+
"platform": "LINUX_X64",
75+
"url": "https://updated-url.com/java-17.0.1.tar.gz",
76+
"visible": false,
77+
"vendor": "temurin"
78+
}
79+
80+
Response: 201 CREATED (overwrites existing entry)
81+
```
82+
83+
#### Not vendored (null vendor in db)
84+
85+
```http
86+
POST /versions
87+
Authorization: Basic dGVzdHVzZXI6cGFzc3dvcmQxMjM=
88+
Content-Type: application/json
89+
90+
{
91+
"candidate": "scala",
92+
"version": "3.1.0",
93+
"platform": "UNIVERSAL",
94+
"url": "https://example.com/scala-3.1.0.tar.gz",
95+
"visible": true
96+
}
97+
98+
Response: 201 CREATED
99+
```
100+
101+
```http
102+
# Same POST request repeated
103+
POST /versions
104+
Authorization: Basic dGVzdHVzZXI6cGFzc3dvcmQxMjM=
105+
Content-Type: application/json
106+
107+
{
108+
"candidate": "scala",
109+
"version": "3.1.0",
110+
"platform": "UNIVERSAL",
111+
"url": "https://example.com/scala-3.1.0.tar.gz",
112+
"visible": true
113+
}
114+
115+
Response: 201 CREATED (overwrites existing entry)
116+
```
117+
118+
### Enhanced DELETE Behavior
119+
```http
120+
DELETE /versions
121+
Authorization: Basic dGVzdHVzZXI6cGFzc3dvcmQxMjM=
122+
Content-Type: application/json
123+
124+
{
125+
"candidate": "java",
126+
"version": "17.0.1",
127+
"vendor": "temurin",
128+
"platform": "LINUX_X64"
129+
}
130+
131+
Response: 204 NO_CONTENT (if version exists)
132+
Response: 404 NOT_FOUND (if version does not exist)
133+
```
134+
135+
### Cucumber Scenarios
136+
```gherkin
137+
Feature: Idempotent POST endpoint
138+
Scenario: POST creates new version with 201 status
139+
When I POST a version for java 17.0.1 on LINUX_X64 with temurin vendor
140+
Then the response status should be 201 CREATED
141+
And the version should be stored in the database
142+
143+
Scenario: POST overwrites existing version with 201 status
144+
Given a version exists for java 17.0.1 on LINUX_X64 with temurin vendor
145+
When I POST the same version with different URL
146+
Then the response status should be 201 CREATED
147+
And the version URL should be updated in the database
148+
149+
Feature: Enhanced DELETE endpoint
150+
Scenario: DELETE removes existing version with 204 status
151+
Given a version exists for java 17.0.1 on LINUX_X64 with temurin vendor
152+
When I DELETE the version
153+
Then the response status should be 204 NO_CONTENT
154+
And the version should not exist in the database
155+
156+
Scenario: DELETE non-existent version returns 404 status
157+
Given no version exists for java 17.0.1 on LINUX_X64 with temurin vendor
158+
When I DELETE the version
159+
Then the response status should be 404 NOT_FOUND
160+
```
161+
162+
## Extra Considerations
163+
164+
- Database constraints may prevent duplicate entries, requiring UPSERT or INSERT ON CONFLICT handling
165+
- Existing validation logic must be preserved for both endpoints
166+
- HTTP status code changes will affect API consumers and should be documented
167+
- Transaction handling for upsert operations to ensure data consistency
168+
169+
## Verification
170+
171+
- [ ] POST /versions returns 201 CREATED for new versions
172+
- [ ] POST /versions returns 201 CREATED for existing versions (idempotent)
173+
- [ ] POST /versions overwrites existing version data completely
174+
- [ ] DELETE /versions returns 204 NO_CONTENT when version exists and is deleted
175+
- [ ] DELETE /versions returns 404 NOT_FOUND when version does not exist
176+
- [ ] All existing validation rules still apply to both endpoints
177+
- [ ] Authentication requirements unchanged for both endpoints
178+
- [ ] Database operations handle concurrent requests safely
179+
- [ ] All existing tests updated to reflect new status code expectations
180+
- [ ] New tests cover idempotent POST and enhanced DELETE scenarios
181+
- [ ] Performance testing shows acceptable response times for upsert operations

0 commit comments

Comments
 (0)