Skip to content

Fix quest assignment and post-based claim flow#30

Merged
MelonChicken merged 2 commits into
mainfrom
feat/quest-response-refactor
Jun 9, 2026
Merged

Fix quest assignment and post-based claim flow#30
MelonChicken merged 2 commits into
mainfrom
feat/quest-response-refactor

Conversation

@Driedoutjerky

Copy link
Copy Markdown
Owner

Summary

Updates the quest flow so that quest claiming is based on a specific completed post.

Previously, the quest claim logic checked all posts from the current user. However, after discussion of handling submission of posts and quest completion check, changes to code were made to follow the flow as below.

  1. Frontend submits post: POST /api/posts (For now when testing, have to send it manually.)
  2. Backend creates post, grants post reward, and returns the created post id
  3. Frontend sends claim request: POST /api/quests/:id/claim (For now when testing, have to send it manually.)
  4. Claim request includes the completed post_id
  5. Backend verifies that the specific post satisfies the quest
  6. Backend grants quest reward and marks the quest as claimed

Changes

  • Updated GET /api/quests/today to return user quest data joined with quest template data.
  • Added user_quest_id, status, completed_post_id, and completed_at to the today quests response.
  • Added logic to assign today’s quests to the current user if missing.
  • Updated POST /api/quests/:id/claim to accept post_id in the request body.
  • Updated claim logic to validate one specific post instead of checking all user posts.
  • Updated claim logic to:
    • verify the quest belongs to the logged-in user
    • verify the quest is not already claimed
    • verify the post belongs to the logged-in user
    • verify the post satisfies the quest requirement
    • set status = claimed
    • set completed_post_id
    • set completed_at
    • grant quest Will reward once

API behavior

Get today’s quests

GET /api/quests/today

Example Response

[
  {
    "user_quest_id": 9,
    "user_id": 5,
    "quest_id": 1,
    "assigned_date": "2026-06-09",
    "status": "assigned",
    "completed_post_id": null,
    "completed_at": null,
    "title": "Write about food",
    "description": "Write a memory post with the food tag.",
    "quest_type": "post_tag",
    "required_tag": "food",
    "required_word_count": 0,
    "required_image": 0,
    "reward_will": 10,
    "is_active": 1
  }
]

Claim quest

POST /api/quests/:user_quest_id/claim

Example Request Body

{
  "post_id": 8
}

Example Response

{
  "userQuest": {
    "user_quest_id": 9,
    "user_id": 5,
    "quest_id": 1,
    "assigned_date": "2026-06-09",
    "status": "claimed",
    "completed_post_id": 8,
    "completed_at": "2026-06-09",
    "title": "Write about food",
    "description": "Write a memory post with the food tag.",
    "quest_type": "post_tag",
    "required_tag": "food",
    "required_word_count": 0,
    "required_image": 0,
    "reward_will": 10,
    "is_active": 1
  },
  "user": {
    "user_id": 5,
    "nickname": "tester",
    "will_balance": 11
  },
  "reward_will": 10
}

Testing

Start server with...

npm install
npm start

Then, use Postman for further testing.
Register/login to get JWT token, and always keep that JWT token in the authorization header.

Expected Output

1. Get today's quests.

  • Returns 200 OK
  • Returned current user's assigned quest
  • Response included user_quest_id, status, and quest requirement fields.
GET http://localhost:5000/api/quests/today
스크린샷 2026-06-09 133505

2. Create a matching post

  • Returns 201 Created
  • Returns created post id. ("id":)
POST http://localhost:5000/api/posts

Request body

{
  "user_id": 5,
  "title": "Food memory",
  "content": "Today I ate something nice and wrote a small memory about it.",
  "tag": "food",
  "visibility": "public",
  "image_url": null,
  "created_at": "2026-06-09T00:00:00.000Z",
  "updated_at": "2026-06-09T00:00:00.000Z"
}
스크린샷 2026-06-09 133721

3. Claim quest using created post id

  • Returned 201 Created
  • Quest status became claimed
  • completed_post_id became the post_id (given by user)
  • User Will Balance increased
  • Response included reward_will
POST http://localhost:5000/api/quests/9/claim

Request body

{
  "post_id": 8
}
스크린샷 2026-06-09 134354

4. Try claiming the same quest again

  • Returns 409 Conflict
  • Response said the quest has already been claimed

Use the same request as 3.

스크린샷 2026-06-09 134425

5. Verify today's quest after claim

  • Returns 200 OK
  • Quest shows changed status of status and completed_post_id and completed_at
스크린샷 2026-06-09 134541

Expected Frontend Behavior

Note: For long-term option, it'd be best for backend claims matching quests automatically for a post, however for now, frontend would handle the "possibly-claimable-quest" and then send multiple requests of possible quest candidates.

Frontend follow this flow.

  1. Submit post through POST /api/posts
  2. Read returned post id from the response
  3. Find matching user_quest_id from GET /api/quests/today
  4. Frontend logic checks types of user quests and compare the quests with the post type/word-count etc. and approximate possible candidates of completable quests
function doesPostLikelySatisfyQuest(post, quest) {
  if (quest.status === "claimed") {
    return false;
  }

  if (quest.quest_type === "post_tag") {
    return post.tag === quest.required_tag;
  }

  if (quest.quest_type === "word_count") {
    return Number(post.word_count) >= Number(quest.required_word_count);
  }

  if (quest.quest_type === "image") {
    return Boolean(post.image_url);
  }

  if (quest.quest_type === "post_tag_image") {
    return post.tag === quest.required_tag && Boolean(post.image_url);
  }

  if (quest.quest_type === "post_tag_word_count") {
    return (
      post.tag === quest.required_tag &&
      Number(post.word_count) >= Number(quest.required_word_count)
    );
  }

  return false;
}
  1. Send quest claim request based on the candidates of quests.
const createdPost = await addPost(postData); // This sends the post.

const matchingQuests = quests.filter((quest) => // This checks what kind of quest the new post would likely be able to complete.
  doesPostLikelySatisfyQuest(createdPost, quest)
);

for (const quest of matchingQuests) { // Send requests to the possible candidates of quests.
  await claimQuest({
    userQuestId: quest.user_quest_id,
    postId: createdPost.id,
  });
}
  1. Receive response(s if many) and update the display of quest completion status + will credits status.

@Driedoutjerky Driedoutjerky self-assigned this Jun 9, 2026
@Driedoutjerky Driedoutjerky added enhancement New feature or request P1: Primary Primary Function to implement labels Jun 9, 2026
@MelonChicken MelonChicken force-pushed the feat/quest-response-refactor branch from 926e33c to 76922b9 Compare June 9, 2026 06:24

@MelonChicken MelonChicken left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the possible way to conduct quests.
LGTM and The test also worked in my local machine

@MelonChicken MelonChicken merged commit eaa2698 into main Jun 9, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request P1: Primary Primary Function to implement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants