The Save button already has type=submit which naturally triggers form submission. The additional click handler dispatching submit event caused handleTaskSubmit to run twice.
GoalsBreakDown
A web-based task management application focused on goal-oriented task tracking with a scroll-view interface.
Features
- Multi-user support with registration and authentication
- Goal management with activation/deactivation
- Task management with status tracking (todo/doing/pending/done)
- Focus rule: Only one "doing" task per goal
- Scroll-view task selector with drag-and-drop reordering
- Admin panel for user management
- Per-user goal limits
Quick Start
Prerequisites
- Python 3.10+
- uv package manager
Installation
# Clone the repository
git clone <repository-url>
cd GoalsBreakDown
# Create your local configuration from the example
cp config.example.py config.py
# Install dependencies with uv
uv sync
# Run the application
uv run python app.py
The application will start at http://127.0.0.1:5000
Default Admin Account
- Username:
admin - Password:
admin123
Important: Change the default admin password after first login.
Configuration
Local configuration is managed via config.py (not tracked in git). Use config.example.py as a template:
# Copy the example config and edit it
cp config.example.py config.py
Available settings in config.py:
| Setting | Description | Default |
|---|---|---|
DB_PATH |
SQLite database path | data/db.sqlite |
DEFAULT_ADMIN_USERNAME |
Default admin username | admin |
DEFAULT_ADMIN_PASSWORD |
Default admin password | admin123 |
DEFAULT_MAX_GOALS |
Max goals per new user | 5 |
SECRET_KEY |
Flask session secret (change in production!) | — |
DEBUG |
Debug mode | True |
HOST |
Server bind address | 0.0.0.0 |
PORT |
Server port | 5000 |
Production Deployment
- Copy
config.example.pytoconfig.py - Change
SECRET_KEYto a random secure string - Set
DEBUG = False - Change default admin credentials
- Use a production WSGI server (e.g., gunicorn):
uv run gunicorn -w 4 -b 0.0.0.0:5000 app:app
Note: The
-bflag is required because gunicorn is a separate WSGI server and does not read Flask'sconfig.py. The values inconfig.py(HOST,PORT) only apply to Flask's built-in dev server (app.run()).
Project Structure
GoalsBreakDown/
├── app.py # Flask application
├── config.example.py # Configuration template (tracked in git)
├── config.py # Local configuration (NOT tracked in git)
├── database.py # SQLite operations
├── auth.py # Authentication helpers
├── schema.py # Database schema & migration
├── templates/ # HTML templates
├── static/
│ ├── css/ # Stylesheets
│ └── js/ # JavaScript files
└── data/ # Database (auto-created, not tracked in git)
Tech Stack
- Backend: Python + Flask
- Database: SQLite
- Frontend: Vanilla JS + HTML/CSS
- Drag-and-Drop: SortableJS
- Markdown: marked.js
- Authentication: bcrypt + Flask sessions
- Environment: uv
Description
Languages
JavaScript
32.6%
Python
30%
CSS
19.9%
HTML
17.5%