# Task Management App — Design Spec

Date: 2026-07-05
Status: Approved

## Purpose

A mobile-first to-do / task assignment app for one **Lead** and their **subordinates**.
The lead assigns dated tasks to subordinates; subordinates see only their own open
tasks and mark them complete; the lead sees everything, plus a Completed view and a
daily report. Built for non-technical users on mobile — the UI must be simple, large,
and intuitive.

## Stack

- Python 3 (compatible with 3.9), Flask (app-factory + blueprints)
- **File-based JSON storage** (no database, no encryption) under `storage/`
- Authlib for Google OAuth, Flask-Login for sessions
- Jinja2 templates + vanilla HTML/CSS/JS, mobile-first responsive
- Entry point: `main.py`. No automated test suite (per user).

## Directory structure

```
task-management/
├── main.py                # entry point (runs the Flask app)
├── requirements.txt
├── .env.example
├── README.md              # setup + how to generate Google OAuth creds
├── backend/
│   ├── __init__.py        # create_app() app factory
│   ├── config.py          # env-driven config
│   ├── storage.py         # JSON read/write, in-process lock, id generation
│   ├── auth.py            # Google OAuth login/callback/logout (+ opt-in dev-login)
│   ├── admin.py           # subordinate management
│   ├── tasks.py           # task CRUD + mark complete/reopen
│   └── reports.py         # daily report
├── frontend/
│   ├── templates/         # Jinja2 templates (base + admin/ + sub/)
│   └── static/{css,js}
└── storage/
    ├── users.json
    └── tasks.json
```

Flask's `create_app()` sets `template_folder` and `static_folder` to the `frontend/`
directory.

## Authentication & roles

Single "Sign in with Google" button. On the OAuth callback, resolve the email:

- `email == ADMIN_EMAIL` (env) → **admin** (the Lead). Auto-created on first login.
- email present in the subordinates records → **subordinate**.
- otherwise → **Access denied** screen.

**Dev-login (opt-in):** when `ALLOW_DEV_LOGIN=true`, an extra local login route lets a
user sign in as the admin or any subordinate without Google — used only to verify flows
during development. Default OFF; production uses pure Google OAuth.

### Environment variables (`.env`, example committed as `.env.example`)

- `SECRET_KEY` — Flask session signing key
- `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` — from Google Cloud Console
- `ADMIN_EMAIL` — the single whitelisted lead Gmail
- `BASE_URL` — used to build the OAuth redirect URI (default `http://localhost:5000`)
- `ALLOW_DEV_LOGIN` — `true`/`false` (default false)

## Data model (JSON)

`storage/users.json` — list of user objects:
```
{ "id": int, "email": str, "name": str, "role": "admin"|"subordinate",
  "active": bool, "created_at": ISO8601 }
```

`storage/tasks.json` — list of task objects:
```
{ "id": int, "title": str, "description": str, "due_date": "YYYY-MM-DD",
  "status": "open"|"completed", "assignee_id": int, "created_by": int,
  "created_at": ISO8601, "completed_at": ISO8601|null }
```

The storage layer serializes all reads/writes through a threading lock and writes
atomically (write temp file, then replace) to avoid corruption. IDs are monotonically
increasing integers (max existing id + 1).

## Permissions

- **Admin / Lead:** full task CRUD; view all open tasks grouped by subordinate;
  Completed view; manage subordinates (add by name + email, deactivate); daily report;
  reopen a completed task.
- **Subordinate:** view only their own open tasks; open a task's detail; mark complete;
  read-only list of their own completed tasks. No create/edit/delete/reassign. All
  admin routes reject non-admins.

## Task lifecycle

`open → completed`. A subordinate taps **Complete**, which sets `completed_at` and
status `completed`. **Overdue** = status open AND `due_date` before today — shown as a
red badge but still counts as open. Completing removes a task from the main open lists
and surfaces it in the Completed view. The admin can **reopen** (status back to open,
`completed_at` cleared). Single assignee per task.

## Pages (mobile-first)

**Admin**
- All Open Tasks — grouped by subordinate, overdue badges
- Create Task — title, description, assignee dropdown, due date
- Task detail — edit / delete / reopen
- Completed — completed tasks
- Subordinates — add (name + email) / deactivate
- Reports — pick a date → per-subordinate breakdown

**Subordinate**
- My Tasks — own open tasks, overdue badges
- Task detail — Complete button
- My Completed — read-only

Navigation: a simple bottom nav bar with large touch targets, role-appropriate items.

## Daily report

Admin picks a date **D**. For each subordinate, the report shows:

- **Assigned** — tasks with `due_date == D`
- **Completed** — those tasks now in `completed` status
- **Spilled over** — those still open (Assigned − Completed)

Rendered on-screen as name + the three lists with counts. Keyed off due date; can later
switch to a date range or key off assignment date.

## Out of scope for v1

Notifications (email/push), multiple assignees per task, multi-team/multi-lead,
encryption, automated tests.
