Mark task as completed
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Marking a task as completed looks simple in the user interface, but the underlying implementation should do more than flip a checkbox. A good design updates status consistently, records when completion happened, supports undo, and keeps the operation idempotent so repeated clicks do not corrupt data. This matters whether you are building a to-do app, a project tracker, or an internal workflow tool.
Model Completion as a State Change
At the data level, “completed” is usually one state in a task lifecycle. A minimal task model often includes:
- a status field such as
pending,in_progress, orcompleted - a completion timestamp
- the user who completed the task, if auditing matters
A typical SQL update looks like this:
The last condition makes the update idempotent. If the task is already completed, the statement does not keep changing data pointlessly.
Implement the API So It Is Safe to Repeat
A backend endpoint should be designed so that pressing the complete button twice does not create inconsistent side effects.
This example uses an idempotent PATCH route. The exact transport can vary, but the design principle should remain the same.
Update the UI Immediately, Then Reconcile
In interactive apps, optimistic UI usually gives the best experience. Mark the task complete in the interface right away, then confirm with the server response.
If the request fails, roll the UI state back and show an error. That keeps the application fast without hiding backend truth.
Support Undo and Auditability
Many systems need more than a one-way status flip. If users can click the wrong item, an undo path is valuable.
A robust implementation often stores:
- '
completed_at' - '
completed_by' - an activity log entry such as “Task marked completed by Priya at 14:05”
That makes the action understandable later, especially in shared team tools.
Consider Derived Workflows
Completion may trigger other rules. For example:
- update project progress percentages
- notify subscribers
- archive the task from the default view
- unlock the next step in a checklist
Keep those side effects separate from the raw status update when possible. The status change should remain simple and reliable, while downstream workflow logic can react to it.
Common Pitfalls
- Treating completion as only a front-end checkbox without storing a real task state.
- Making the endpoint non-idempotent so repeated clicks cause duplicate notifications or logs.
- Overwriting completion metadata every time the same action is retried.
- Hiding completed tasks immediately without giving users a way to undo mistakes.
- Mixing unrelated business rules directly into the basic status update path.
Summary
- Marking a task complete should be modeled as a deliberate state change.
- Store status and completion metadata, not just a visual checkmark.
- Make the backend operation idempotent.
- Use optimistic UI carefully and reconcile with server truth.
- Keep side effects such as notifications and progress updates separate from the core completion update.
Related reading
- MassTransit with RabbitMQ recovering the error queue
- MassTransit with RabbitMQ When is a message moved to the error queue
- Matching array entries in AWS Cloudwatch log metrics filter
- Matplotlib draw grid lines behind other graph elements
- Matrix arrangement issues in php
- matrix multiplication algorithm time complexity
- Max-Heapify A Binary Tree
- max-weight k-clique in a complete k-partite graph

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.