Skip to Content

Daily Claim Limit (State Counter)

Demo Project

https://editor.momen.app/tool/Vbr0R9B92XZ/WEB?code=neVO5uQxwHMnX&ref=0562398

Introduction

  • Goal: Create a secure daily reward system that limits users to 3 claims per day.
  • Use Cases: Daily login rewards, free API rate limiting, daily lucky draws, or high-frequency business action auditing.
  • Core Logic: Use a claim_status table to track the “Single State” of a user’s progress. Backend Actionflow logic handles date verification and counter increments, while an On database changed trigger automates audit logging into a claim_log table.

Steps

This tutorial uses pre-styled layout blocks from the “Common UI Presets” template page to streamline the visual setup. These preset elements contain only basic styling and typography; they do not include any conditional logic, database bindings, or Actionflows. When building your own app, you can directly copy elements from this template page to skip manual styling and focus entirely on core frontend logic.

Data Storage

To implement a daily claim limit system, we need to establish a dedicated table in the database to map user data and its processing status.

Data Model

Configure the relational database to store user status and transactional history. Every table automatically includes system fields such as id, created_at, and updated_at; only custom fields are listed in detail below.

1. Table: claim_status

Used for state control; each account holds at most one corresponding record. The account_id field has a built-in unique constraint due to the 1:1 relationship with the account table.

Field NameTypeNote
idBigintPrimary Key (system default)
last_claim_dateDateUsed to verify if the request falls on a “new day”
daily_claim_countBigintIncrements sequentially (1‑3)
account_idBigintForeign key to account (1:1 relationship, automatically unique)

2. Table: claim_log An append‑only audit log table.

Field NameTypeNote
idBigintPrimary Key (system default)
claim_sequenceBigintLogs the index of the claim (1, 2, or 3)
account_idBigintForeign key to account (1:N relationship)

Logic & State Configuration

”Daily Claim” Actionflow Construction

This Actionflow handles the core validation rules: checking if a record exists, resetting the counter on a new day, and incrementing the count if under the limit.

  1. Actionflow variable: Add a global variable inside the Actionflow named status with the type Boolean to track the overall success of the request execution.
  2. Get ID: Add a custom code node named “Get ID” to retrieve the logged-in user’s account ID (current_account_id).
  3. Query data: Add a Query Record node named “Get Claim Status”.
    • Table: claim_status.
    • Filter: account_id Equal to Actionflow data/Get ID/current_account_id.
    • Limit: 1.
  4. Condition - Root Branching: Add a Branch Separation node named “Condition” to verify if the status record exists in the database.
    • Case Existing Status Record: Actionflow data/Get Claim Status/id Is not null. (Proceeds to Step 5)
    • Case No Records (Else): If the user has never claimed before (the record is null). (Proceeds to Step 9)
  5. Condition - Nested Date Check: Inside the existing record branch, add a nested Branch Separation node named “Condition”.
    • Case Already Claimed Today: Actionflow data/Get Claim Status/last_claim_date Equal to getCurrentDate. (Proceeds to Step 6)
    • Case Not Claimed Today (Else): If the last claim date belongs to a previous day. (Proceeds to Step 8)
  6. Update data (In Case Already Claimed Today): Add an Update Record node named “Update Daily Claim Count”.
    • Table: claim_status.
    • Parameters: daily_claim_count -> Arithmetic Operator: increment by 1.
    • Filter: account_id Equal to Actionflow data/Get ID/current_account_id AND daily_claim_count Less than 3.
  7. Set variable: Add a Set Variable node to determine the value of the status variable based on the execution result of the counter increment.
    • Case Updated Successfully: Actionflow data/Update Daily Claim Count/id Is not null -> Set to True.
    • Case Update Failed (Else): Set to False (this happens if the daily_claim_count is already 3 or more, violating the filter constraint).
  8. Update data (In Case Not Claimed Today): Since it is a brand new day, add an Update Record node named “Update Claim Status” to reset the counter tracking.
    • Table: claim_status.
    • Parameters: last_claim_date -> getCurrentDate, daily_claim_count -> Set directly to 1.
    • Filter: account_id Equal to Actionflow data/Get ID/current_account_id AND last_claim_date Not equal to getCurrentDate.
    • Set variable: Update the Actionflow variable status. If Update Claim Status/id Is not null, set to True, else False.
  9. Insert data (In Case No Records): For first-time users, add an Insert Record node named “Add Claim Status Record” to create the initial tracking state.
    • Table: claim_status.
    • Parameters: last_claim_date -> getCurrentDate, daily_claim_count -> 1, account_id -> Actionflow data/Get ID/current_account_id.
    • On Conflict: Do nothing. (The account_id field has a unique constraint due to its 1:1 relationship with the account table, ensuring this clause works as intended.)
    • Set variable: Update the Actionflow variable status. If Add Claim Status Record/id Is not null, set to True, else False.
  10. Actionflow output: Merge all conditional branches into the Flow End node and configure the output data binding to return Actionflow data/Variable/status.

”Claim Log” Actionflow & Trigger

Automate the audit trail whenever the claim_status table is modified.

  1. Actionflow input: Create a new Actionflow named “Claim Log”. Add inputs: account_id (Bigint) and sequence (Bigint).
  2. Configure the Database Trigger: Enable the Database Trigger for this Actionflow to capture automated updates.
    • Trigger type: DB_TRIGGER.
    • Select DB Operation Type: INSERT_OR_UPDATE.
    • Select Table: claim_status.
    • Actionflow inputs mapping:
      • account_id -> Inserted or updated data/account_id.
      • sequence -> Inserted or updated data/daily_claim_count.
  3. Insert data: Add an Insert Record node named “Insert data” to persist the changes.
    • Table: claim_log.
    • Parameters: claim_sequence -> Actionflow data/Input/sequence, account_id -> Actionflow data/Input/account_id.

By using an On database changed trigger set to INSERT_OR_UPDATE, you ensure that every change to the claim_status table is logged.

UI Construction & Interaction

Configure the frontend to dynamically display the claim status and handle user interactions based on the backend logic.

Page: Daily Reward Claim

  1. Conditional View Setup: In the Component Tree, select the Conditional View component. Rename the default cases to reflect the business logic:

    • Case Under 3 Times: For users who can still claim rewards.
    • Case 3 Times Reached: For users who have hit their daily limit.
    • Initializing: The default state for logged-out users.
  2. Configure Active Button: Within Case Under 3 Times, select the Button / Primary component.

    • Button text: Click the Data Binding icon and select Condition.
      • Case No Records: If Logged in user -> claim_status -> daily_claim_count Is null, set the display data to 0.
      • Case Record Exists: Else, bind the data to Logged in user -> claim_status -> daily_claim_count.
      • Final String: Set the static text to Claim Daily Reward ({Condition}/3).
  3. Configure Button Interaction: Select the active button, go to the Interaction tab, and configure its behavior.

    • Action: Add an OnClick event and select the Daily Claim Actionflow. Enable the Loading animation toggle.
    • On success:
      • Show toast: Add a Show toast node. Click the Data Binding icon for the Message and select Condition.

        • Case Claim Successful: If Action result -> Daily Claim -> status Is true, set the message to Claim successful.
        • Case Claim Failed: Else, set the message to Claim failed.
      • Refresh login user data: Add a Refresh login user data node to ensure the frontend counter updates immediately after the database change.

  4. Configure Disabled Button: Within Case 3 Times Reached, select the Button / Disabled component to configure the UI when the daily limit is hit.

    • Button text: Click the Data Binding icon and select Condition (following the identical binding logic as the active button), or directly enter the static text: Claim Daily Reward (3/3).
  5. Configure Initializing View: Within Initializing, select the Text component to prompt unauthenticated users.

    • Text text: Directly enter the static text string: Please log in first.
  6. Configure Conditional View Logic: Select the master Conditional View and click Config in the right panel to define when each case is displayed.

    • Case Under 3 Times:
      • Add a condition: Global -> Is logged in Is true.
      • Add an And condition: Logged in user -> claim_status -> daily_claim_count Less than 3.
    • Case 3 Times Reached:
      • Add a condition: Global -> Is logged in Is true.
      • Add an And condition: Logged in user -> claim_status -> daily_claim_count Greater than or equal 3.
    • Initializing:
      • Add a condition: Global -> Is logged in Is false.

Verification

Step 1: Logged-out State

  1. Click the Preview icon in the top right.
  2. Expected Result: The page displays the text “Please log in first.”

Step 2: First Claim

  1. Use the Login simulation tool in the bottom bar. Click Create new and select the Logged-in user role.
  2. Click the button labeled Claim Daily Reward (0/3).
  3. Expected Result: A “Claim successful” toast appears, and the button label updates to Claim Daily Reward (1/3).

Step 3: Reaching the Limit

  1. Click the button two more times.
  2. Expected Result: After the third claim, the button label shows Claim Daily Reward (3/3) and becomes disabled (switching to the Case 3 Times Reached UI).

Step 4: Database Audit

  1. Navigate to the Data Source tab.
  2. Check the claim_status table: The daily_claim_count should be 3.
  3. Check the claim_log table: There should be three distinct records with claim_sequence values of 1, 2, and 3, all linked to the same account_id.
⚠️

If the counter does not update on the frontend, verify that the Refresh login user data node is correctly placed in the On success branch of the button’s OnClick interaction.

Last updated on