Files
TimeTracker/docs/PROJECT_ARCHIVING_GUIDE.md
Dries Peeters 6de86fca2b feat: Implement comprehensive project archiving system
Add enhanced project archiving functionality for better organization of
completed projects with metadata tracking and validation.

Key Features:
- Archive metadata tracking (timestamp, user, reason)
- Archive form with quick-select reason templates
- Bulk archiving with optional shared reason
- Archive information display on project details
- Prevent time tracking on archived projects
- Activity logging for archive/unarchive actions

Database Changes:
- Add migration 026_add_project_archiving_metadata.py
- New fields: archived_at, archived_by (FK), archived_reason
- Index on archived_at for faster filtering
- Cascade on user deletion (SET NULL)

Model Enhancements (app/models/project.py):
- Enhanced archive() method with user_id and reason parameters
- Enhanced unarchive() method to clear all metadata
- New properties: is_archived, archived_by_user
- Updated to_dict() to include archive metadata

Route Updates (app/routes/projects.py):
- Convert archive route to GET/POST (form-based)
- Add archive reason handling
- Enhanced bulk operations with reason support
- Activity logging for all archive operations

UI Improvements:
- New archive form template (app/templates/projects/archive.html)
- Quick-select buttons for common archive reasons
- Archive metadata display on project view page
- Bulk archive modal with reason input
- Updated project list filtering

Validation (app/routes/timer.py):
- Prevent timer start on archived projects
- Block manual entry creation on archived projects
- Block bulk entry creation on archived projects
- Clear error messages for users

Testing:
- 90+ comprehensive test cases
- Unit tests (tests/test_project_archiving.py)
- Model tests (tests/test_project_archiving_models.py)
- Smoke tests for complete workflows
- Edge case coverage

Documentation:
- User guide (docs/PROJECT_ARCHIVING_GUIDE.md)
- Implementation summary (PROJECT_ARCHIVING_IMPLEMENTATION_SUMMARY.md)
- API reference and examples
- Best practices and troubleshooting

Migration Notes:
- Backward compatible with existing archived projects
- Existing archives will have NULL metadata (can be added later)
- No data migration required
- Run: migrations/manage_migrations.py upgrade head

Breaking Changes: None
- All changes are additive and backward compatible

Related: Feat-Project-Archiving branch
2025-10-24 09:06:51 +02:00

15 KiB

Project Archiving Guide

Overview

The Project Archiving feature provides a comprehensive solution for organizing completed, cancelled, or inactive projects in TimeTracker. This guide explains how to use the archiving system effectively.

Table of Contents

  1. What is Project Archiving?
  2. When to Archive Projects
  3. Archiving a Single Project
  4. Bulk Archiving
  5. Viewing Archived Projects
  6. Unarchiving Projects
  7. Archive Metadata
  8. Restrictions on Archived Projects
  9. API Reference
  10. Best Practices

What is Project Archiving?

Project archiving allows you to hide completed or inactive projects from your active project lists while preserving all historical data. Archived projects:

  • Are removed from active project dropdowns
  • Cannot have new time entries added
  • Retain all existing time entries and data
  • Can be filtered and viewed separately
  • Can be unarchived if needed
  • Store metadata about when, why, and by whom they were archived

When to Archive Projects

Consider archiving a project when:

  • The project is completed
  • The client contract has ended
  • The project has been cancelled
  • Work is on indefinite hold
  • The maintenance period has ended
  • You want to declutter your active project list

Do NOT archive projects that:

  • Are temporarily paused (use "Inactive" status instead)
  • May need time tracking in the near future
  • Are awaiting client feedback
  • Have ongoing maintenance work

Archiving a Single Project

Step-by-Step Process

  1. Navigate to the Project

    • Go to Projects in the main navigation
    • Find the project you want to archive
    • Click View to open the project details
  2. Click Archive Button

    • On the project details page, click the Archive button (visible to administrators only)
    • You'll be taken to the archive confirmation page
  3. Provide Archive Reason (Optional but Recommended)

    • Enter a reason for archiving in the text field
    • This helps with future reference and organization
    • Use the Quick Select buttons for common reasons:
      • Project Completed
      • Contract Ended
      • Cancelled
      • On Hold
      • Maintenance Ended
    • Or type a custom reason
  4. Confirm Archive

    • Click Archive Project to confirm
    • The project will be archived immediately
    • You'll be redirected to the archived projects list

Example Archive Reasons

✓ "Project delivered on 2025-01-15. Client satisfied with results."
✓ "Annual contract ended. Client chose not to renew."
✓ "Project cancelled by client due to budget constraints."
✓ "Website maintenance complete. No further updates planned."
✓ "Internal tool - replaced with new system."

Bulk Archiving

When you need to archive multiple projects at once:

Using Bulk Archive

  1. Navigate to Projects List

    • Go to ProjectsList All Projects
  2. Select Projects

    • Check the boxes next to projects you want to archive
    • Or click Select All to select all visible projects
  3. Open Bulk Actions Menu

    • Click Bulk Actions (N) button (where N is the number selected)
    • Select Archive from the dropdown
  4. Enter Bulk Archive Reason

    • A modal will appear
    • Enter a reason that applies to all selected projects
    • Or use one of the quick select buttons
    • Click Archive to confirm
  5. Confirmation

    • All selected projects will be archived with the same reason
    • You'll see a success message with the count

Bulk Archive Tips

  • You can archive up to 100 projects at once
  • All selected projects will receive the same archive reason
  • The current user will be recorded as the archiver for all projects
  • Projects with active timers cannot be archived (stop timers first)

Viewing Archived Projects

Filter Archived Projects

  1. Navigate to Projects List

    • Go to Projects in the main navigation
  2. Apply Archive Filter

    • In the filter section, select Status: Archived
    • Click Filter
  3. View Archived Project List

    • All archived projects will be displayed
    • The list shows:
      • Project name and client
      • Archive status badge
      • Budget and billing information
      • Quick actions

Viewing Individual Archived Project

When viewing an archived project's details page, you'll see:

Archive Information Section:

  • Archived on: Date and time of archiving
  • Archived by: User who archived the project
  • Reason: Why the project was archived

All historical data remains accessible:

  • Time entries
  • Tasks
  • Project costs
  • Extra goods
  • Comments
  • Budget information

Unarchiving Projects

If you need to reactivate an archived project:

Unarchive Process

  1. Navigate to Archived Projects

    • Go to Projects with Status: Archived filter
  2. Open Project Details

    • Click View on the project you want to unarchive
  3. Click Unarchive Button

    • Click the Unarchive button (administrators only)
    • Confirm the action in the dialog
  4. Project Reactivated

    • The project status changes to Active
    • Archive metadata is cleared
    • The project appears in active lists again
    • Time tracking can resume

Note: Unarchiving a project:

  • Removes all archive metadata (reason, date, user)
  • Sets the project status to "active"
  • Makes the project available for time tracking
  • Preserves all historical data

Archive Metadata

Each archived project stores three pieces of metadata:

1. Archived At (Timestamp)

  • Type: Date and time
  • Timezone: UTC
  • Purpose: Track when the project was archived
  • Displayed: Yes (in project details)
  • Example: "2025-10-24 14:30:00"

2. Archived By (User)

  • Type: User reference
  • Purpose: Track who archived the project
  • Displayed: Yes (shows username or full name)
  • Note: If user is deleted, this field may show "Unknown"

3. Archived Reason (Text)

  • Type: Free text (optional)
  • Max Length: Unlimited
  • Purpose: Document why the project was archived
  • Displayed: Yes (in dedicated section)
  • Can include: Multi-line text, special characters, emojis

Viewing Metadata

Archive metadata is displayed on:

  • Project details page (Archive Information section)
  • API responses (to_dict() method)
  • Activity logs
  • Export reports

Restrictions on Archived Projects

What You CANNOT Do with Archived Projects

Time Tracking

  • Cannot start new timers
  • Cannot create manual time entries
  • Cannot create bulk time entries
  • Error message: "Cannot start timer for an archived project. Please unarchive the project first."

Project Dropdown

  • Archived projects don't appear in:
    • Timer start modal
    • Manual entry forms
    • Bulk entry forms
    • Quick timer buttons

What You CAN Do with Archived Projects

View Data

  • View project details
  • Access time entry history
  • See tasks and their status
  • Review project costs
  • Read comments

Generate Reports

  • Include in time reports
  • Generate invoices from historical data
  • Export time entries
  • View analytics

Admin Actions

  • Unarchive the project
  • Edit project details (after unarchiving)
  • Delete the project (if no time entries)
  • Change client assignment

API Reference

Archive a Project

# Python/Flask
project = Project.query.get(project_id)
project.archive(user_id=current_user.id, reason="Project completed")
db.session.commit()
// JavaScript/API
fetch('/projects/123/archive', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'X-CSRFToken': csrfToken
    },
    body: new URLSearchParams({
        'reason': 'Project completed successfully'
    })
});

Unarchive a Project

# Python/Flask
project = Project.query.get(project_id)
project.unarchive()
db.session.commit()
// JavaScript/API
fetch('/projects/123/unarchive', {
    method: 'POST',
    headers: {
        'X-CSRFToken': csrfToken
    }
});

Get Archive Status

# Check if project is archived
if project.is_archived:
    print(f"Archived on: {project.archived_at}")
    print(f"Archived by: {project.archived_by_user.username}")
    print(f"Reason: {project.archived_reason}")

Project to Dictionary

# Get project data including archive metadata
project_dict = project.to_dict()

# Access archive fields
is_archived = project_dict['is_archived']
archived_at = project_dict['archived_at']  # ISO format string or None
archived_by = project_dict['archived_by']  # User ID or None
archived_reason = project_dict['archived_reason']  # Text or None

Filter Archived Projects

# Get all archived projects
archived_projects = Project.query.filter_by(status='archived').all()

# Get projects archived by specific user
user_archived = Project.query.filter_by(
    status='archived',
    archived_by=user_id
).all()

# Get projects archived in date range
from datetime import datetime, timedelta
week_ago = datetime.utcnow() - timedelta(days=7)
recently_archived = Project.query.filter(
    Project.status == 'archived',
    Project.archived_at >= week_ago
).all()

Bulk Archive

POST /projects/bulk-status-change
Content-Type: application/x-www-form-urlencoded

project_ids[]=1&project_ids[]=2&project_ids[]=3&new_status=archived&archive_reason=Bulk+archive+reason

Best Practices

1. Always Provide Archive Reasons

Good Practice:

✓ Document WHY the project was archived
✓ Include relevant dates (completion, cancellation)
✓ Mention key outcomes or decisions
✓ Reference client communications if applicable

Example Good Reasons:

  • "Project completed on schedule. Final invoice sent and paid."
  • "Client contract ended Q4 2024. No renewal planned."
  • "Cancelled due to client budget cuts. 75% of work completed."

2. Review Before Archiving

Before archiving, verify:

  • All time entries are logged
  • Final invoice generated (if applicable)
  • All outstanding tasks are resolved or noted
  • Client deliverables are complete
  • No active timers are running
  • Team members are notified

3. Use Bulk Archive Strategically

Bulk archive is ideal for:

  • End-of-year cleanup
  • Multiple projects from same client (contract ended)
  • Maintenance projects after completion
  • Internal projects that are no longer needed

4. Regular Archive Audits

Periodically review archived projects:

  • Monthly: Review recently archived projects
  • Quarterly: Audit archive reasons for completeness
  • Yearly: Consider permanent deletion of very old projects (backup first!)

5. Archive vs. Inactive

Use the right status:

Archive when:

  • Project is completely finished
  • No future work expected
  • Want to hide from all lists

Inactive when:

  • Temporarily paused
  • Waiting for client
  • May resume in near future
  • Want to keep in lists but marked as not active

6. Unarchive Sparingly

Only unarchive if:

  • New work is required on the project
  • Contract is renewed
  • Client requests additional features
  • You need to add historical entries

Consider creating a new project instead if:

  • It's a new phase/version
  • Significant time has passed
  • Scope has changed dramatically

Troubleshooting

Cannot Start Timer on Archived Project

Problem: Error message when starting timer

Solution:

  1. Check if project is archived (Projects → Filter: Archived)
  2. Unarchive the project if work needs to continue
  3. Or create a new project for new work

Cannot Find Archived Project in Dropdown

Problem: Archived project doesn't appear in timer dropdown

Solution: This is expected behavior. Archived projects are hidden from active lists. To work on an archived project, unarchive it first.

Lost Archive Reason After Unarchive

Problem: Archive reason is gone after unarchiving

Solution: This is by design. Archive metadata is cleared when unarchiving. If you need to preserve the reason:

  1. Copy the archive reason before unarchiving
  2. Add it to project description or comments
  3. Or take a screenshot of the archive information

Bulk Archive Not Working

Problem: Some projects not archived in bulk operation

Solution:

  1. Check if you have admin permissions
  2. Ensure no projects have active timers
  3. Verify projects are selected (checkboxes checked)
  4. Check for error messages in the flash notifications

Migration from Old System

If you're upgrading from a version without archive metadata:

What Happens to Existing Archived Projects?

  • Existing archived projects retain their "archived" status
  • Archive metadata fields will be NULL:
    • archived_at: NULL
    • archived_by: NULL
    • archived_reason: NULL
  • Projects still function normally
  • You can add archive reasons by:
    1. Unarchiving the project
    2. Re-archiving with a reason

Manual Migration (Optional)

To add metadata to existing archived projects:

# Example migration script
from app import db
from app.models import Project
from datetime import datetime

# Get all archived projects without metadata
archived_projects = Project.query.filter(
    Project.status == 'archived',
    Project.archived_at.is_(None)
).all()

# Set archive timestamp to created_at or updated_at
for project in archived_projects:
    project.archived_at = project.updated_at or project.created_at
    project.archived_reason = "Migrated from old system"
    # Leave archived_by as NULL if you don't know who archived it

db.session.commit()

Database Schema

For developers and database administrators:

New Fields in projects Table

ALTER TABLE projects 
ADD COLUMN archived_at DATETIME NULL,
ADD COLUMN archived_by INTEGER NULL,
ADD COLUMN archived_reason TEXT NULL,
ADD FOREIGN KEY (archived_by) REFERENCES users(id) ON DELETE SET NULL,
ADD INDEX ix_projects_archived_at (archived_at);

Field Specifications

Field Type Nullable Index Default Foreign Key
archived_at DATETIME Yes Yes NULL -
archived_by INTEGER Yes No NULL users(id) ON DELETE SET NULL
archived_reason TEXT Yes No NULL -

Support and Feedback

If you encounter issues with project archiving:

  1. Check this documentation
  2. Review the Troubleshooting section
  3. Contact your system administrator
  4. Report bugs via GitHub Issues

Document Version: 1.0
Last Updated: October 24, 2025
TimeTracker Version: 2.0+