# Project Archive & Completion

**Date:** 2026-05-31  
**Status:** Draft  
**Spec:** 147  
**Tier:** All tiers  
**Depends on:** `projects-module`, `invoices-core`, `tasks-board-engine`, `time-management`, `foundation-auth-rbac`  
**Referenced by:** `projects-module`, `invoices-core`

---

## Overview

Spec 10 (`projects-module`) defines project CRUD and status but does not document what happens when a project is completed or archived: whether tasks stay accessible, whether time entries can still be added, what happens to unbilled time, and how the project list filters inactive projects. This spec defines the completion flow, archive state, and cascade behavior.

---

## Project Status Model

Two distinct end states are added to the `projects.status` column:

| Status | Description |
|--------|-------------|
| `active` | (existing) Normal working state |
| `completed` | Work done; project closed; invoicing may still proceed |
| `archived` | Hidden from default views; read-only; fully settled |

```sql
ALTER TABLE projects
  ADD COLUMN IF NOT EXISTS completed_at TIMESTAMPTZ,
  ADD COLUMN IF NOT EXISTS archived_at TIMESTAMPTZ;
```

---

## Complete a Project

**[Mark complete]** action on project detail → confirmation sheet:

```
┌──────────────────────────────────────────────────────────────┐
│  Complete: Website Redesign?                                 │
│                                                              │
│  Summary                                                     │
│  Tasks:     42 total · 38 done · 4 open                      │
│  Time:      127h logged · 4h unbilled                        │
│  Invoices:  ₪28,400 invoiced · ₪4,200 outstanding           │
│                                                              │
│  ⚠ 4 open tasks and 4h unbilled time                         │
│                                                              │
│  What to do with open tasks?                                 │
│  ● Leave open (can still close them later)                   │
│  ○ Mark all remaining tasks done                             │
│                                                              │
│  [Cancel]      [Complete project]                            │
└──────────────────────────────────────────────────────────────┘
```

On complete:
1. `projects.status → 'completed'`, `completed_at = now()`
2. Task disposition per user choice
3. New time entries: allowed (to finalize any remaining work)
4. Project activity: "Marked complete by {user}"
5. If unbilled time exists on hourly project: notification to OWNER — "₪{amount} unbilled on completed project"

---

## Completed Project State

`completed` projects:
- Visible in `/projects` list with "Completed" badge
- Default filter: `/projects` shows `active` and `completed` (not `archived`)
- Full detail view remains accessible (read + limited write)
- Time entries: can still be added (finalization window)
- Tasks: can still be closed
- Invoices: can still be created (final billing)

---

## Archive a Project

**[Archive]** action (only available on `completed` projects):

```
Archive Website Redesign?
Archived projects are hidden from default views and locked.
No new time entries or invoices after archiving.

Outstanding: ₪4,200 on INV-0038 (SENT)

[Cancel]    [Archive anyway]
```

On archive:
1. `projects.status → 'archived'`, `archived_at = now()`
2. Time entries locked: no new entries (existing entries read-only)
3. Tasks locked: no new tasks; existing read-only
4. Invoices: no new invoices linked to project; existing invoices continue their lifecycle normally

---

## Archived Project State

`archived` projects:
- Hidden from `/projects` default list (must toggle "Show archived" filter)
- Project detail page accessible via direct URL (read-only)
- Appears in search results with `[Archived]` badge
- Time and expenses linked to archived projects still appear in reports
- Invoices linked to archived projects continue to collect payment normally

```
┌──────────────────────────────────────────────────────────────┐
│  🗄 Archived                                                  │
│  Website Redesign                                            │
│  Archived 2025-12-15 · Completed 2025-12-10                  │
│                                                              │
│  [Unarchive]                                                 │
└──────────────────────────────────────────────────────────────┘
```

**[Unarchive]** → sets `status = 'completed'`, clears `archived_at`. Requires `projects:write`.

---

## Project List Filter Integration

`/projects` list gets an additional filter:

```
[Status ▾]  Active · Completed · Archived
```

Default: shows Active + Completed. Archived hidden unless explicitly selected.

---

## API

```
POST /api/projects/:id/complete
     → mark project complete
       body: { close_open_tasks?: boolean }
       Requires: projects:write

POST /api/projects/:id/archive
     → archive completed project
       Requires: projects:write

POST /api/projects/:id/unarchive
     → restore to completed
       Requires: projects:write

GET /api/projects/:id/completion-summary
    → summary before completing: open tasks, unbilled time, outstanding invoices
      Returns: { open_tasks, unbilled_hours, unbilled_amount, outstanding_invoice_amount }
      Requires: projects:read
```

---

## Architecture Decisions

| Decision | Choice | Reason |
|----------|--------|--------|
| Two separate states (completed / archived) | Not one "closed" state | `completed` allows continued invoicing and time finalization; `archived` is a hard lock for permanent storage — they serve different operational needs |
| Time entries allowed on completed | Not locked immediately | Agencies often complete a project then log final hours the same week; blocking on completion creates billing gaps |
| Invoices continue after archive | Not blocked | Outstanding invoices must still be collectible regardless of project state; freezing invoice lifecycle on archive would break AR |
| Unarchive always allowed | Not one-way | Accidental archives happen; one-way locks create helpdesk tickets |
