Tasks module

Manages task-related operations.

📋 Tasks Module

🔧 Workflow

📄 GET Request (/project/{project_id}/create-task)

  • Renders the task creation form for a specific project.

  • Ensures the project exists before proceeding:

    project = request.dbsession.query(Project).get(project_id)
    if not project: return HTTPFound(...)

📝 POST Request (/project/{project_id}/create-task)

  • Creates a new task under the specified project.

  • Validates that all fields (name, description, due_date) are provided.

  • Stores the task with status assigned and 0% completion.

  • Logs task creation to ActivityLog.

if not task_name or not task_description or not due_date:
    return { ..., "error_ping": "All fields are required." }

new_task = Task(...)
request.dbsession.add(new_task)

🔍 GET Request (/task/{id})

  • Displays the task details.

  • Retrieves the task by ID.

  • Also fetches associated microtasks that are active=True.

  • Includes current date in context for UI display.


✏️ POST Request (/task/{id}/edit)

  • Edits task fields: title, description, and due date.

  • Fields must not be empty.

  • Each updated field is individually logged to ActivityLog:

    if task.task_title != name:
        ActivityLog(... action='task_edited_title', ...)

🗑️ POST Request (/task/{id}/delete)

  • Soft-deletes the task by setting task.active = False.

  • Logs task deletion to ActivityLog.

  • Redirects back to the parent project page.


🔒 Security Measures

✅ Session Enforcement

All routes are protected by @verify_session, ensuring only authenticated users can access or modify tasks.

✅ Admin-Only Routes

Task creation, editing, and deletion are restricted to users with "admin" permission via:

@view_config(..., permission="admin")

✅ Validations

📌 Project Existence

Checked before creating or displaying a task:

if not project:
    return HTTPFound(location=request.route_url('my_projects'))

🧱 Required Fields (Creation/Edit)

Both creation and edit routes require:

  • name

  • description

  • due_date

Empty or missing fields are rejected with an error:

if not name or not description or not due_date:
    return { ..., "error_ping": "All fields are required." }

🕒 Date Parsing

Due dates are parsed using:

datetime.strptime(due_date, '%Y-%m-%d')

Improper date formats would raise an exception (caught and handled).

📖 Change Detection (Edit)

Only modified fields are logged for auditing purposes:

if task.task_title != name: ...

🗂️ Soft Delete

Tasks are never permanently deleted:

if task.active:
    task.active = False

Prevents accidental loss and supports recovery/audit.


🧠 Design Rationale

  • Auditability: All state changes (create/edit/delete) are logged with details of who performed the action and what changed.

  • Integrity: Strict checks on required fields and relationships (e.g., valid project).

  • Security: Only authenticated, authorized users can manipulate task data.

  • User Experience: Users see relevant error messages and are redirected appropriately on success or failure.

  • All POST requests are protected against CSRF

Last updated