Salman Adnan

flask-todo-list

Flask TODO List

A to-do list you use in a web browser: each person signs in and sees only their own tasks, ticking them off without the page reloading. The story worth telling is the fix. Passwords used to be stored as plain readable words, so anyone reaching the database could read them. Now only a scrambled version is kept, and an old readable password no longer works.

Solo

Solo work by Salman Adnan.

Done and Gone: a task card gets ticked, flares, and leaves as dust; the small satisfaction of clearing a list, which is most of what the app is. Live and interactive: drag it to orbit, scroll or pinch to zoom. Open full screen
The real Flask TODO List app, showing a live-created account and tasks.
Live local run of the actual app.
2SQLAlchemy models, one-to-many
8flows verified by hand end to end

Overview

A small multi-user TODO list web app built with Flask, SQLAlchemy, and Flask-Login. Each user registers an account, logs in, and keeps their own private list of tasks, managed through an AJAX interface that falls back cleanly to plain form posts.

Key features

  • Register and log in with a name, email, and password. Passwords are hashed with scrypt via werkzeug.security.generate_password_hash before they touch the database; login verifies with check_password_hash rather than a raw string comparison.
  • A card-based task list where ticking a task marks it complete (strikethrough, faded row) without removing it, and a separate delete button removes it entirely, backed by distinct /toggle/<id> and /delete/<id> routes.
  • Add, complete/uncomplete, and delete all run over fetch() calls that patch the DOM directly with no full page reload, but each route still accepts a plain form POST and redirects if the request didn't come from the fetch-based JS.
  • Duplicate or empty tasks are rejected with a clear message on both the AJAX and no-JS paths, instead of a raw error or a silently bad row.
  • Each user only ever sees their own tasks: every task query is scoped by author_id to the logged-in user.

Verification

Everything was verified by hand and by script against a running instance: registering a user, confirming the stored password is a hash and not the raw string, logging in with the correct password, confirming a simulated legacy plaintext password now fails to log in, adding a duplicate/empty task, toggling a task complete and back, deleting a task, and logging out, all through direct HTTP requests. There's no automated test suite yet; that's listed plainly as a gap, not glossed over.

Tech stack

  • Python
  • Flask
  • SQLAlchemy
  • Flask-Login
  • SQLite
  • JavaScript (fetch/AJAX)

Book a call

Let's talk about what you're building.

Pick a slot below.