Skip to content

Commit d43a525

Browse files
committed
chore: clean up awards API impl to match definition
1 parent 2c16eac commit d43a525

7 files changed

Lines changed: 84 additions & 104 deletions

File tree

sticker-award/src/main/java/com/datadoghq/stickerlandia/stickeraward/StickerAwardResource.java

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@
22

33
import com.datadoghq.stickerlandia.stickeraward.beans.AssignStickerCommand;
44
import com.datadoghq.stickerlandia.stickeraward.beans.StickerAssignmentResponse;
5-
import com.datadoghq.stickerlandia.stickeraward.beans.StickerAssignmentResponseApiResponse;
65
import com.datadoghq.stickerlandia.stickeraward.beans.StickerDTO;
76
import com.datadoghq.stickerlandia.stickeraward.beans.StickerRemovalResponse;
8-
import com.datadoghq.stickerlandia.stickeraward.beans.StickerRemovalResponseApiResponse;
97
import com.datadoghq.stickerlandia.stickeraward.beans.UserStickersResponse;
10-
import com.datadoghq.stickerlandia.stickeraward.beans.UserStickersResponseApiResponse;
118
import com.datadoghq.stickerlandia.stickeraward.entity.Sticker;
129
import com.datadoghq.stickerlandia.stickeraward.entity.StickerAssignment;
1310
import com.datadoghq.stickerlandia.stickeraward.messaging.StickerEventPublisher;
@@ -45,7 +42,7 @@ public class StickerAwardResource {
4542
@GET
4643
@Produces("application/json")
4744
@Transactional
48-
public Response getUserStickers(@PathParam("userId") String userId) {
45+
public UserStickersResponse getUserStickers(@PathParam("userId") String userId) {
4946
List<StickerAssignment> assignments = StickerAssignment.findActiveByUserId(userId);
5047

5148
List<StickerDTO> stickerDTOs = assignments.stream()
@@ -65,12 +62,7 @@ public Response getUserStickers(@PathParam("userId") String userId) {
6562
response.setUserId(userId);
6663
response.setStickers(stickerDTOs);
6764

68-
UserStickersResponseApiResponse apiResponse = new UserStickersResponseApiResponse();
69-
apiResponse.setSuccess(true);
70-
apiResponse.setMessage("Successfully retrieved user stickers");
71-
apiResponse.setData(response);
72-
73-
return Response.ok(apiResponse).build();
65+
return response;
7466
}
7567

7668
@Operation(description = "Assign a new sticker to a user (access controlled based on caller identity)")
@@ -86,23 +78,13 @@ public Response assignStickerToUser(@PathParam("userId") String userId,
8678
Sticker sticker = Sticker.findById(stickerId);
8779

8880
if (sticker == null) {
89-
StickerAssignmentResponseApiResponse apiResponse = new StickerAssignmentResponseApiResponse();
90-
apiResponse.setSuccess(false);
91-
apiResponse.setMessage("Sticker not found: " + stickerId);
92-
return Response.status(Response.Status.BAD_REQUEST)
93-
.entity(apiResponse)
94-
.build();
81+
return Response.status(Response.Status.BAD_REQUEST).build();
9582
}
9683

9784
// Check if sticker is already assigned to the user and not removed
9885
StickerAssignment existingAssignment = StickerAssignment.findActiveByUserAndSticker(userId, stickerId);
9986
if (existingAssignment != null) {
100-
StickerAssignmentResponseApiResponse apiResponse = new StickerAssignmentResponseApiResponse();
101-
apiResponse.setSuccess(false);
102-
apiResponse.setMessage("User already has this sticker assigned");
103-
return Response.status(Response.Status.CONFLICT)
104-
.entity(apiResponse)
105-
.build();
87+
return Response.status(Response.Status.CONFLICT).build();
10688
}
10789

10890
// Create new assignment
@@ -125,13 +107,8 @@ public Response assignStickerToUser(@PathParam("userId") String userId,
125107
response.setStickerId(stickerId);
126108
response.setAssignedAt(Date.from(assignment.getAssignedAt()));
127109

128-
StickerAssignmentResponseApiResponse apiResponse = new StickerAssignmentResponseApiResponse();
129-
apiResponse.setSuccess(true);
130-
apiResponse.setMessage("Sticker assigned successfully");
131-
apiResponse.setData(response);
132-
133110
return Response.status(Response.Status.CREATED)
134-
.entity(apiResponse)
111+
.entity(response)
135112
.build();
136113
}
137114

@@ -146,12 +123,7 @@ public Response removeStickerFromUser(@PathParam("userId") String userId,
146123
StickerAssignment assignment = StickerAssignment.findActiveByUserAndSticker(userId, stickerId);
147124

148125
if (assignment == null) {
149-
StickerRemovalResponseApiResponse apiResponse = new StickerRemovalResponseApiResponse();
150-
apiResponse.setSuccess(false);
151-
apiResponse.setMessage("Active sticker assignment not found for user");
152-
return Response.status(Response.Status.NOT_FOUND)
153-
.entity(apiResponse)
154-
.build();
126+
return Response.status(Response.Status.NOT_FOUND).build();
155127
}
156128

157129
// Mark as removed
@@ -174,11 +146,6 @@ public Response removeStickerFromUser(@PathParam("userId") String userId,
174146
response.setStickerId(stickerId);
175147
response.setRemovedAt(Date.from(assignment.getRemovedAt()));
176148

177-
StickerRemovalResponseApiResponse apiResponse = new StickerRemovalResponseApiResponse();
178-
apiResponse.setSuccess(true);
179-
apiResponse.setMessage("Sticker removed successfully");
180-
apiResponse.setData(response);
181-
182-
return Response.ok(apiResponse).build();
149+
return Response.ok(response).build();
183150
}
184151
}

sticker-award/src/main/java/com/datadoghq/stickerlandia/stickeraward/entity/Sticker.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public class Sticker extends PanacheEntityBase {
2525
@Column(name = "image_url")
2626
private String imageUrl;
2727

28+
@Column(name = "sticker_quantity_remaining", nullable = false)
29+
private Integer stickerQuantityRemaining;
30+
2831
@Column(name = "created_at", nullable = false)
2932
private Instant createdAt;
3033

@@ -36,11 +39,12 @@ public Sticker() {
3639
}
3740

3841
// Constructor with fields
39-
public Sticker(String stickerId, String name, String description, String imageUrl) {
42+
public Sticker(String stickerId, String name, String description, String imageUrl, Integer stickerQuantityRemaining) {
4043
this.stickerId = stickerId;
4144
this.name = name;
4245
this.description = description;
4346
this.imageUrl = imageUrl;
47+
this.stickerQuantityRemaining = stickerQuantityRemaining;
4448
this.createdAt = Instant.now();
4549
}
4650

@@ -93,6 +97,29 @@ public void setUpdatedAt(Instant updatedAt) {
9397
this.updatedAt = updatedAt;
9498
}
9599

100+
public Integer getStickerQuantityRemaining() {
101+
return stickerQuantityRemaining;
102+
}
103+
104+
public void setStickerQuantityRemaining(Integer stickerQuantityRemaining) {
105+
this.stickerQuantityRemaining = stickerQuantityRemaining;
106+
}
107+
108+
// Helper methods for quantity management
109+
public boolean isAvailable() {
110+
return stickerQuantityRemaining == null || stickerQuantityRemaining == -1 || stickerQuantityRemaining > 0;
111+
}
112+
113+
public boolean hasUnlimitedQuantity() {
114+
return stickerQuantityRemaining == null || stickerQuantityRemaining == -1;
115+
}
116+
117+
public void decrementQuantity() {
118+
if (stickerQuantityRemaining != null && stickerQuantityRemaining > 0) {
119+
stickerQuantityRemaining--;
120+
}
121+
}
122+
96123
// Helper methods for finding stickers
97124
public static Sticker findById(String id) {
98125
return find("stickerId", id).firstResult();

sticker-award/src/main/resources/db/migration/V1.0.0__initial_schema.sql

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CREATE TABLE stickers (
66
name VARCHAR(100) NOT NULL,
77
description VARCHAR(500),
88
image_url VARCHAR(255),
9+
sticker_quantity_remaining INTEGER NOT NULL DEFAULT -1,
910
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
1011
updated_at TIMESTAMP
1112
);
@@ -27,12 +28,18 @@ CREATE INDEX idx_sticker_assignments_user_id ON sticker_assignments(user_id);
2728
CREATE INDEX idx_sticker_assignments_active ON sticker_assignments(user_id, removed_at)
2829
WHERE removed_at IS NULL;
2930

31+
-- Add comment to explain the quantity field
32+
COMMENT ON COLUMN stickers.sticker_quantity_remaining IS 'Quantity remaining (-1 for infinite)';
33+
3034
-- Initial seed data
31-
INSERT INTO stickers (sticker_id, name, description, image_url, created_at)
35+
INSERT INTO stickers (sticker_id, name, description, image_url, sticker_quantity_remaining, created_at)
3236
VALUES
33-
('sticker-001', 'Debugging Hero', 'Awarded for exceptional debugging skills', 'https://stickerlandia.example.com/images/debugging-hero.png', CURRENT_TIMESTAMP),
34-
('sticker-002', 'Code Review Champion', 'Awarded for thorough code reviews', 'https://stickerlandia.example.com/images/code-review-champion.png', CURRENT_TIMESTAMP),
35-
('sticker-003', 'Performance Optimizer', 'Awarded for significant performance improvements', 'https://stickerlandia.example.com/images/performance-optimizer.png', CURRENT_TIMESTAMP);
37+
('sticker-001', 'Debugging Hero', 'Awarded for exceptional debugging skills', 'https://stickerlandia.example.com/images/debugging-hero.png', 100, CURRENT_TIMESTAMP),
38+
('sticker-002', 'Code Review Champion', 'Awarded for thorough code reviews', 'https://stickerlandia.example.com/images/code-review-champion.png', 100, CURRENT_TIMESTAMP),
39+
('sticker-003', 'Performance Optimizer', 'Awarded for significant performance improvements', 'https://stickerlandia.example.com/images/performance-optimizer.png', -1, CURRENT_TIMESTAMP),
40+
('sticker-004', 'Early Bird', 'Awarded for being first to complete tasks', 'https://stickerlandia.example.com/images/early-bird.png', 50, CURRENT_TIMESTAMP),
41+
('sticker-005', 'Team Player', 'Awarded for excellent collaboration', 'https://stickerlandia.example.com/images/team-player.png', -1, CURRENT_TIMESTAMP),
42+
('sticker-006', 'Innovation Award', 'Awarded for creative solutions', 'https://stickerlandia.example.com/images/innovation-award.png', 25, CURRENT_TIMESTAMP);
3643

3744
-- Sample assignment
3845
INSERT INTO sticker_assignments (user_id, sticker_id, assigned_at, reason)

sticker-award/src/test/java/com/datadoghq/stickerlandia/stickeraward/StickerAwardResourceKafkaIT.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public class StickerAwardResourceKafkaIT {
3535
@Order(1)
3636
public void testCreateSticker() {
3737
// Create a test sticker in the database
38-
Sticker sticker = new Sticker(TEST_STICKER_ID, "Test Sticker", "A test sticker", "https://example.com/sticker.png");
38+
Sticker sticker = new Sticker(TEST_STICKER_ID, "Test Sticker", "A test sticker", "https://example.com/sticker.png", 100);
3939
sticker.persist();
4040
}
4141

@@ -55,9 +55,8 @@ public void testAssignStickerToUser() {
5555
.post("/api/award/v1/users/" + TEST_USER_ID + "/stickers")
5656
.then()
5757
.statusCode(Status.CREATED.getStatusCode())
58-
.body("success", is(true))
59-
.body("data.userId", is(TEST_USER_ID))
60-
.body("data.stickerId", is(TEST_STICKER_ID));
58+
.body("userId", is(TEST_USER_ID))
59+
.body("stickerId", is(TEST_STICKER_ID));
6160
}
6261

6362
@Test
@@ -69,10 +68,9 @@ public void testGetUserStickers() {
6968
.get("/api/award/v1/users/" + TEST_USER_ID + "/stickers")
7069
.then()
7170
.statusCode(Status.OK.getStatusCode())
72-
.body("success", is(true))
73-
.body("data.userId", is(TEST_USER_ID))
74-
.body("data.stickers.size()", is(1))
75-
.body("data.stickers[0].stickerId", is(TEST_STICKER_ID));
71+
.body("userId", is(TEST_USER_ID))
72+
.body("stickers.size()", is(1))
73+
.body("stickers[0].stickerId", is(TEST_STICKER_ID));
7674
}
7775

7876
@Test
@@ -84,18 +82,16 @@ public void testRemoveStickerFromUser() {
8482
.delete("/api/award/v1/users/" + TEST_USER_ID + "/stickers/" + TEST_STICKER_ID)
8583
.then()
8684
.statusCode(Status.OK.getStatusCode())
87-
.body("success", is(true))
88-
.body("data.userId", is(TEST_USER_ID))
89-
.body("data.stickerId", is(TEST_STICKER_ID));
85+
.body("userId", is(TEST_USER_ID))
86+
.body("stickerId", is(TEST_STICKER_ID));
9087

9188
// Verify the user no longer has the sticker
9289
given()
9390
.when()
9491
.get("/api/award/v1/users/" + TEST_USER_ID + "/stickers")
9592
.then()
9693
.statusCode(Status.OK.getStatusCode())
97-
.body("success", is(true))
98-
.body("data.userId", is(TEST_USER_ID))
99-
.body("data.stickers.size()", is(0));
94+
.body("userId", is(TEST_USER_ID))
95+
.body("stickers.size()", is(0));
10096
}
10197
}

sticker-award/src/test/java/com/datadoghq/stickerlandia/stickeraward/StickerAwardResourceTest.java

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,20 @@ void setupTestData() {
3333
// Make sure our test stickers exist
3434
Sticker sticker1 = Sticker.findById(EXISTING_STICKER_ID);
3535
if (sticker1 == null) {
36-
sticker1 = new Sticker(EXISTING_STICKER_ID, "Test Sticker", "For testing", "http://example.com/test.png");
36+
sticker1 = new Sticker(EXISTING_STICKER_ID, "Test Sticker", "For testing", "http://example.com/test.png", 100);
3737
sticker1.persist();
3838
}
3939

4040
// Create sticker-002 and sticker-003 for other tests
4141
Sticker sticker2 = Sticker.findById("sticker-002");
4242
if (sticker2 == null) {
43-
sticker2 = new Sticker("sticker-002", "Test Sticker 2", "For testing", "http://example.com/test2.png");
43+
sticker2 = new Sticker("sticker-002", "Test Sticker 2", "For testing", "http://example.com/test2.png", 100);
4444
sticker2.persist();
4545
}
4646

4747
Sticker sticker3 = Sticker.findById("sticker-003");
4848
if (sticker3 == null) {
49-
sticker3 = new Sticker("sticker-003", "Test Sticker 3", "For testing", "http://example.com/test3.png");
49+
sticker3 = new Sticker("sticker-003", "Test Sticker 3", "For testing", "http://example.com/test3.png", 100);
5050
sticker3.persist();
5151
}
5252

@@ -65,11 +65,9 @@ void testGetUserStickers() {
6565
.then()
6666
.statusCode(200)
6767
.contentType(ContentType.JSON)
68-
.body("success", is(true))
69-
.body("data", notNullValue())
70-
.body("data.userId", is(TEST_USER_ID))
71-
.body("data.stickers.size()", is(1))
72-
.body("data.stickers[0].stickerId", is(EXISTING_STICKER_ID));
68+
.body("userId", is(TEST_USER_ID))
69+
.body("stickers.size()", is(1))
70+
.body("stickers[0].stickerId", is(EXISTING_STICKER_ID));
7371
}
7472

7573
@Test
@@ -80,10 +78,8 @@ void testGetUserStickersForUserWithNoStickers() {
8078
.then()
8179
.statusCode(200)
8280
.contentType(ContentType.JSON)
83-
.body("success", is(true))
84-
.body("data", notNullValue())
85-
.body("data.userId", is(unknownUserId))
86-
.body("data.stickers.size()", is(0));
81+
.body("userId", is(unknownUserId))
82+
.body("stickers.size()", is(0));
8783
}
8884

8985
@Test
@@ -104,20 +100,18 @@ void testAssignStickerToUser() {
104100
.then()
105101
.statusCode(201)
106102
.contentType(ContentType.JSON)
107-
.body("success", is(true))
108-
.body("data", notNullValue())
109-
.body("data.userId", is(userId))
110-
.body("data.stickerId", is(stickerId))
111-
.body("data.assignedAt", notNullValue());
103+
.body("userId", is(userId))
104+
.body("stickerId", is(stickerId))
105+
.body("assignedAt", notNullValue());
112106

113107
// Verify the sticker is now assigned by getting user stickers
114108
given()
115109
.when().get("/api/award/v1/users/{userId}/stickers", userId)
116110
.then()
117111
.statusCode(200)
118112
.contentType(ContentType.JSON)
119-
.body("data.stickers.size()", is(1))
120-
.body("data.stickers[0].stickerId", is(stickerId));
113+
.body("stickers.size()", is(1))
114+
.body("stickers[0].stickerId", is(stickerId));
121115
}
122116

123117
@Test
@@ -135,10 +129,7 @@ void testAssignNonExistingStickerReturns400() {
135129
.body(command)
136130
.when().post("/api/award/v1/users/{userId}/stickers", userId)
137131
.then()
138-
.statusCode(400)
139-
.contentType(ContentType.JSON)
140-
.body("success", is(false))
141-
.body("message", notNullValue());
132+
.statusCode(400);
142133
}
143134

144135
@Test
@@ -166,10 +157,7 @@ void testAssignAlreadyAssignedStickerReturns409() {
166157
.body(command)
167158
.when().post("/api/award/v1/users/{userId}/stickers", userId)
168159
.then()
169-
.statusCode(409)
170-
.contentType(ContentType.JSON)
171-
.body("success", is(false))
172-
.body("message", notNullValue());
160+
.statusCode(409);
173161
}
174162

175163
@Test
@@ -197,19 +185,17 @@ void testRemoveStickerAssignment() {
197185
.then()
198186
.statusCode(200)
199187
.contentType(ContentType.JSON)
200-
.body("success", is(true))
201-
.body("data", notNullValue())
202-
.body("data.userId", is(userId))
203-
.body("data.stickerId", is(stickerId))
204-
.body("data.removedAt", notNullValue());
188+
.body("userId", is(userId))
189+
.body("stickerId", is(stickerId))
190+
.body("removedAt", notNullValue());
205191

206192
// Verify the sticker is no longer assigned
207193
given()
208194
.when().get("/api/award/v1/users/{userId}/stickers", userId)
209195
.then()
210196
.statusCode(200)
211197
.contentType(ContentType.JSON)
212-
.body("data.stickers.size()", is(0));
198+
.body("stickers.size()", is(0));
213199
}
214200

215201
@Test
@@ -220,9 +206,6 @@ void testRemoveNonExistingStickerAssignmentReturns404() {
220206
given()
221207
.when().delete("/api/award/v1/users/{userId}/stickers/{stickerId}", userId, stickerId)
222208
.then()
223-
.statusCode(404)
224-
.contentType(ContentType.JSON)
225-
.body("success", is(false))
226-
.body("message", notNullValue());
209+
.statusCode(404);
227210
}
228211
}

0 commit comments

Comments
 (0)