# yasusudas/poptask architecture

> Architecture diagram of the GitHub repository yasusudas/poptask, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/yasusudas/poptask
- Repository: https://github.com/yasusudas/poptask

## Overview

1. **Overall shape**
   - PopTask is a **client-only, local-first PWA**. There is **no backend** or account system in this repo; all task/folder/settings data lives in the browser.
   - The app is built with **React 19 + TypeScript + Vite**, and ships as an installable offline-capable web app.

2. **Bootstrap and app shell**
   - `index.html` and `src/main.tsx` mount the React app into `src/App.tsx`.
   - `src/index.css` provides the global styling foundation, while `src/components/BottomNav.tsx`, `Sidebar.tsx`, and related shell components adapt the layout to mobile vs. larger screens.

3. **Persistent data layer**
   - Persistence is isolated in `src/db/db.ts` and `src/db/repositories.ts`.
   - The app uses **IndexedDB via Dexie** with three repositories: **TaskRepository**, **FolderRepository**, and **SettingsRepository**.
   - This layer is the boundary between UI and storage; all task mutations ultimately flow through it.

4. **Domain model and state**
   - Shared shapes live in `src/types.ts`.
   - The domain centers on **tasks**, **one-level folders**, and **settings**, with task status moving through **active / completed / trash** states.
   - The README indicates no sync or server-side reconciliation, so the browser database is the source of truth.

5. **Primary user interface**
   - `src/components/TaskForm.tsx`, `TaskCreateModal.tsx`, `TaskDetailSheet.tsx`, `ConfirmDialog.tsx`, and `ModalSheet.tsx` handle task editing and confirmation flows.
   - `HistoryLists.tsx` renders completed and deleted task history, while `FolderManageModal.tsx` and `FolderFilterBar.tsx` support folder organization.
   - `SearchBar.tsx` provides partial-match search with a short debounce, and `SettingsScreen.tsx` contains app-level preferences and maintenance actions.

6. **Responsive navigation model**
   - The app uses two navigation patterns depending on screen size: **bottom navigation + FAB** on mobile, and **sidebar + top-bar style layout** on tablet/desktop.
   - `src/hooks/useMediaQuery.ts` is the main responsiveness hook driving that switch.
   - This layout choice is an important architectural boundary because the same task data and screens are presented through different shell components.

7. **Balloon visualization and task urgency**
   - `src/components/BalloonField.tsx` is the visual centerpiece: tasks are rendered as balloons with string, motion, and interaction.
   - Pure helper modules in `src/lib/size.ts`, `src/lib/time.ts`, `src/lib/colors.ts`, and `src/lib/id.ts` compute balloon size, color, identifiers, and time-based presentation rules.
   - The README’s “smooth 7-second transition” on due-date changes implies the UI consumes these pure calculations as derived presentation state rather than storing them.

8. **Custom physics subsystem**
   - `src/physics/engine.ts` is a separate lightweight 2D physics engine used for **floating, collision, dragging, and repulsion**.
   - Keeping physics in its own module makes it reusable and testable, and prevents animation logic from leaking into the React component tree.
   - `src/physics/engine.test.ts` shows this subsystem is explicitly unit-tested.

9. **Notifications and lifecycle automation**
   - `src/lib/notifications.ts` handles best-effort reminder scheduling and display, including the staged thresholds described in the README.
   - Notifications are delivered through the **Service Worker** where supported, which matters because the app is also a PWA and can surface reminders outside the visible page.
   - Trash auto-deletion after 30 days and undo behavior are part of the app’s state transitions and are surfaced through toast/UI flows such as `src/components/Toast.tsx`.

10. **Backup and data portability**
   - `src/lib/backup.ts` supports **JSON export** and **full replace import** of local data.
   - This is a data-boundary feature rather than a UI-only one: it operates on the repositories’ persisted state and can replace the browser’s stored dataset.
   - `src/lib/backup.test.ts` suggests the backup format and import/export behavior are treated as important contract logic.

11. **PWA, offline, and update behavior**
   - The app uses **vite-plugin-pwa** with **Workbox generateSW** to pre-cache the application shell.
   - This enables **offline startup** and non-destructive update handling, so the app behaves like an installed local tool rather than a traditional server-backed site.
   - `public/manifest.webmanifest` provides install metadata for the PWA shell.

12. **Testing and repo boundaries**
   - Unit tests cover the pure logic layers: physics, size, time, and backup behavior.
   - `e2e/app.spec.ts` and Playwright configuration validate end-to-end behavior, including offline startup.
   - The architecture is intentionally split so that **UI, persistence, physics, and pure domain calculations** are distinct layers, making the system easier to diagram and reason about.

Main entry points: [`src/App.tsx`](https://github.com/yasusudas/poptask/blob/main/src/App.tsx) (App shell), [`src/db/repositories.ts`](https://github.com/yasusudas/poptask/blob/main/src/db/repositories.ts) (Repositories), [`src/components/BalloonField.tsx`](https://github.com/yasusudas/poptask/blob/main/src/components/BalloonField.tsx) (Balloon field), [`src/lib/backup.ts`](https://github.com/yasusudas/poptask/blob/main/src/lib/backup.ts) (Backup)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ui_shell["UI shell"]
  node_main(("Main<br/>entrypoint<br/>[main.tsx]"))
  node_app["App shell<br/>react app<br/>[App.tsx]"]
  node_bottom_nav["Bottom nav<br/>mobile nav<br/>[BottomNav.tsx]"]
  node_sidebar["Sidebar<br/>desktop nav<br/>[Sidebar.tsx]"]
  node_media_query["Media query<br/>responsive hook<br/>[useMediaQuery.ts]"]
  node_balloon_field["Balloon field<br/>task visualization<br/>[BalloonField.tsx]"]
  node_task_create["Create modal<br/>task create UI"]
  node_task_detail["Detail sheet<br/>task detail UI"]
  node_task_form["Task form<br/>task editor<br/>[TaskForm.tsx]"]
  node_history_lists["History lists<br/>history UI<br/>[HistoryLists.tsx]"]
  node_folder_manage["Folder modal<br/>folder UI"]
  node_settings["Settings<br/>preferences screen<br/>[SettingsScreen.tsx]"]
  node_search_bar["Search<br/>[SearchBar.tsx]"]
end

subgraph group_data_layer["Data layer"]
  node_db[("Dexie DB<br/>indexeddb schema<br/>[db.ts]")]
  node_repositories["Repositories<br/>data access<br/>[repositories.ts]"]
  node_types["Types<br/>domain model<br/>[types.ts]"]
end

subgraph group_logic_layer["Logic layer"]
  node_backup["Backup<br/>import/export<br/>[backup.ts]"]
  node_notifications["Notifications<br/>reminders<br/>[notifications.ts]"]
  node_physics["Physics engine<br/>simulation<br/>[engine.ts]"]
  node_size["Size rules<br/>presentation logic<br/>[size.ts]"]
  node_time["Time rules<br/>time logic<br/>[time.ts]"]
end

subgraph group_platform["Platform"]
  node_platform_config["Vite PWA<br/>build config<br/>[vite.config.ts]"]
  node_manifest["Manifest<br/>pwa metadata"]
end

node_main -->|"mounts"| node_app
node_app -->|"responsive"| node_media_query
node_app -->|"mobile shell"| node_bottom_nav
node_app -->|"desktop shell"| node_sidebar
node_app -->|"renders"| node_balloon_field
node_app -->|"creates"| node_task_create
node_app -->|"inspects"| node_task_detail
node_task_detail -->|"uses"| node_task_form
node_app -->|"history"| node_history_lists
node_app -->|"folders"| node_folder_manage
node_app -->|"preferences"| node_settings
node_app -->|"search"| node_search_bar
node_app -->|"persists via"| node_repositories
node_repositories -->|"stores in"| node_db
node_repositories -->|"shapes"| node_types
node_backup -->|"exports/imports"| node_repositories
node_notifications -->|"reads state"| node_repositories
node_balloon_field -->|"simulates"| node_physics
node_balloon_field -->|"derives size"| node_size
node_balloon_field -->|"derives time"| node_time
node_notifications -->|"thresholds"| node_time
node_backup -->|"serializes"| node_types
node_platform_config -->|"installs"| node_manifest
node_platform_config -->|"packages"| node_app

click node_main "https://github.com/yasusudas/poptask/blob/main/src/main.tsx"
click node_app "https://github.com/yasusudas/poptask/blob/main/src/App.tsx"
click node_bottom_nav "https://github.com/yasusudas/poptask/blob/main/src/components/BottomNav.tsx"
click node_sidebar "https://github.com/yasusudas/poptask/blob/main/src/components/Sidebar.tsx"
click node_media_query "https://github.com/yasusudas/poptask/blob/main/src/hooks/useMediaQuery.ts"
click node_balloon_field "https://github.com/yasusudas/poptask/blob/main/src/components/BalloonField.tsx"
click node_task_create "https://github.com/yasusudas/poptask/blob/main/src/components/TaskCreateModal.tsx"
click node_task_detail "https://github.com/yasusudas/poptask/blob/main/src/components/TaskDetailSheet.tsx"
click node_task_form "https://github.com/yasusudas/poptask/blob/main/src/components/TaskForm.tsx"
click node_history_lists "https://github.com/yasusudas/poptask/blob/main/src/components/HistoryLists.tsx"
click node_folder_manage "https://github.com/yasusudas/poptask/blob/main/src/components/FolderManageModal.tsx"
click node_settings "https://github.com/yasusudas/poptask/blob/main/src/components/SettingsScreen.tsx"
click node_search_bar "https://github.com/yasusudas/poptask/blob/main/src/components/SearchBar.tsx"
click node_db "https://github.com/yasusudas/poptask/blob/main/src/db/db.ts"
click node_repositories "https://github.com/yasusudas/poptask/blob/main/src/db/repositories.ts"
click node_types "https://github.com/yasusudas/poptask/blob/main/src/types.ts"
click node_backup "https://github.com/yasusudas/poptask/blob/main/src/lib/backup.ts"
click node_notifications "https://github.com/yasusudas/poptask/blob/main/src/lib/notifications.ts"
click node_physics "https://github.com/yasusudas/poptask/blob/main/src/physics/engine.ts"
click node_size "https://github.com/yasusudas/poptask/blob/main/src/lib/size.ts"
click node_time "https://github.com/yasusudas/poptask/blob/main/src/lib/time.ts"
click node_platform_config "https://github.com/yasusudas/poptask/blob/main/vite.config.ts"
click node_manifest "https://github.com/yasusudas/poptask/blob/main/public/manifest.webmanifest"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main,node_app,node_bottom_nav,node_sidebar,node_media_query,node_balloon_field,node_task_create,node_task_detail,node_task_form,node_history_lists,node_folder_manage,node_settings,node_search_bar toneBlue
class node_db,node_repositories,node_types toneAmber
class node_backup,node_notifications,node_physics,node_size,node_time toneMint
class node_platform_config,node_manifest toneRose
```

## Components

### UI shell

App entry, responsive navigation, and primary screens

- [Main](https://github.com/yasusudas/poptask/blob/main/src/main.tsx): entrypoint · Bootstraps React into the app · `src/main.tsx`
- [App shell](https://github.com/yasusudas/poptask/blob/main/src/App.tsx): react app · Top-level composition of screens and layout · `src/App.tsx`
- [Bottom nav](https://github.com/yasusudas/poptask/blob/main/src/components/BottomNav.tsx): mobile nav · Mobile navigation and primary actions · `src/components/BottomNav.tsx`
- [Sidebar](https://github.com/yasusudas/poptask/blob/main/src/components/Sidebar.tsx): desktop nav · Larger-screen navigation shell · `src/components/Sidebar.tsx`
- [Media query](https://github.com/yasusudas/poptask/blob/main/src/hooks/useMediaQuery.ts): responsive hook · Switches between mobile and desktop layouts · `src/hooks/useMediaQuery.ts`
- [Balloon field](https://github.com/yasusudas/poptask/blob/main/src/components/BalloonField.tsx): task visualization · Renders tasks as interactive balloons · `src/components/BalloonField.tsx`
- [Create modal](https://github.com/yasusudas/poptask/blob/main/src/components/TaskCreateModal.tsx): task create UI · Task creation flow · `src/components/TaskCreateModal.tsx`
- [Detail sheet](https://github.com/yasusudas/poptask/blob/main/src/components/TaskDetailSheet.tsx): task detail UI · Task inspection and edit surface · `src/components/TaskDetailSheet.tsx`
- [Task form](https://github.com/yasusudas/poptask/blob/main/src/components/TaskForm.tsx): task editor · Shared task editing form · `src/components/TaskForm.tsx`
- [History lists](https://github.com/yasusudas/poptask/blob/main/src/components/HistoryLists.tsx): history UI · Completed and trash task history · `src/components/HistoryLists.tsx`
- [Folder modal](https://github.com/yasusudas/poptask/blob/main/src/components/FolderManageModal.tsx): folder UI · Folder organization and management · `src/components/FolderManageModal.tsx`
- [Settings](https://github.com/yasusudas/poptask/blob/main/src/components/SettingsScreen.tsx): preferences screen · App preferences and maintenance actions · `src/components/SettingsScreen.tsx`
- [Search](https://github.com/yasusudas/poptask/blob/main/src/components/SearchBar.tsx): search UI · Debounced partial-match task search · `src/components/SearchBar.tsx`

### Data layer

IndexedDB persistence and domain shapes

- [Dexie DB](https://github.com/yasusudas/poptask/blob/main/src/db/db.ts): indexeddb schema · Browser database setup · `src/db/db.ts`
- [Repositories](https://github.com/yasusudas/poptask/blob/main/src/db/repositories.ts): data access · Task, folder, and settings persistence APIs · `src/db/repositories.ts`
- [Types](https://github.com/yasusudas/poptask/blob/main/src/types.ts): domain model · Shared task, folder, and settings shapes · `src/types.ts`

### Logic layer

Pure helpers, physics, backup, and notifications

- [Backup](https://github.com/yasusudas/poptask/blob/main/src/lib/backup.ts): import/export · JSON export and full-replace import · `src/lib/backup.ts`
- [Notifications](https://github.com/yasusudas/poptask/blob/main/src/lib/notifications.ts): reminders · Reminder scheduling and display rules · `src/lib/notifications.ts`
- [Physics engine](https://github.com/yasusudas/poptask/blob/main/src/physics/engine.ts): simulation · Floating, collision, drag, and repulsion · `src/physics/engine.ts`
- [Size rules](https://github.com/yasusudas/poptask/blob/main/src/lib/size.ts): presentation logic · Balloon sizing and urgency scaling · `src/lib/size.ts`
- [Time rules](https://github.com/yasusudas/poptask/blob/main/src/lib/time.ts): time logic · Due-date and temporal presentation helpers · `src/lib/time.ts`

### Platform

PWA bootstrap and install metadata

- [Vite PWA](https://github.com/yasusudas/poptask/blob/main/vite.config.ts): build config · PWA build and precache setup · `vite.config.ts`
- [Manifest](https://github.com/yasusudas/poptask/blob/main/public/manifest.webmanifest): pwa metadata · Install metadata for the web app · `public/manifest.webmanifest`

## Connections

- Main → App shell: mounts · React entry mounts the application shell
- App shell → Media query: responsive · Chooses shell layout by screen size
- App shell → Bottom nav: mobile shell · Mobile navigation and action layer
- App shell → Sidebar: desktop shell · Desktop navigation and layout layer
- App shell → Balloon field: renders · Primary task visualization
- App shell → Create modal: creates · Task creation flow
- App shell → Detail sheet: inspects · Task details and edits
- Detail sheet → Task form: uses · Shares the task editing form
- App shell → History lists: history · Completed and deleted task views
- App shell → Folder modal: folders · Folder organization UI
- App shell → Settings: preferences · Settings and maintenance screen
- App shell → Search: search · Task filtering and lookup
- App shell → Repositories: persists via · All mutations flow through repository APIs
- Repositories → Dexie DB: stores in · Dexie-backed IndexedDB storage
- Repositories → Types: shapes · Repository records follow shared domain types
- Backup → Repositories: exports/imports · Backup operates on persisted browser data
- Notifications → Repositories: reads state · Uses persisted tasks and settings for reminders
- Balloon field → Physics engine: simulates · Uses the custom 2D physics engine
- Balloon field → Size rules: derives size · Computes balloon scale from task state
- Balloon field → Time rules: derives time · Applies time-based presentation rules
- Notifications → Time rules: thresholds · Reminder timing uses temporal rules
- Backup → Types: serializes · Backup format is based on domain data
- Vite PWA → Manifest: installs · PWA build consumes app manifest
- Vite PWA → App shell: packages · Builds the client app for offline use
