# dapbyte/traceon-private architecture

> Architecture diagram of the GitHub repository dapbyte/traceon-private, 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/dapbyte/traceon-private
- Repository: https://github.com/dapbyte/traceon-private

## Overview

1. **High-level shape**
   - TraceOn is a **native PHP 8.3 MVC application** with a **MySQL 8+** database and a **vanilla JavaScript ES-module** frontend.
   - It is organized as a single monolith: backend routes, business logic, database access, and server-rendered views live in the same repo.

2. **Request entry and routing boundary**
   - All browser traffic enters through **`public/index.php`** behind **`public/.htaccess`**, which acts as the front controller.
   - URL dispatch is centralized in **`routes.php`** and handled by **`app/Core/Router.php`**.
   - Request/response handling is abstracted by **`app/Core/Request.php`** and **`app/Core/Response.php`**.

3. **Core application services**
   - **`app/Core/Database.php`** provides the PDO/MySQL connection layer.
   - **`app/Core/Session.php`** manages session state, with session files stored in the **`sessions/`** directory.
   - **`app/Core/CsrfManager.php`** is the anti-CSRF boundary for mutating requests.
   - **`app/Controllers/BaseController.php`** likely provides shared controller utilities such as rendering and auth checks.

4. **Domain controllers and responsibilities**
   - The main backend surface is split into focused controllers:
     - **AuthController**: login, register, logout
     - **WorkspaceController**: workspace lifecycle, invite/join flows
     - **MemberController**: workspace membership and roles
     - **CardController**: card management and card access control
     - **TodoController**: todo CRUD and status updates
     - **ActivityController**: activity feed, search/filter/pagination
     - **ProfileController**: user profile and avatar updates
     - **HealthController**: app health/status endpoint
   - These controllers are the orchestration layer between HTTP, models, helpers, and views.

5. **Persistence and data model**
   - Database access is encapsulated in **`app/Models/*`** classes rather than scattered SQL.
   - The schema is bootstrapped from **`migrations/0001_init.sql`** and extended by **`0002_add_priority.sql`**.
   - The domain tables called out in the README are:
     - `users`
     - `workspaces`
     - `workspace_members`
     - `cards`
     - `card_access`
     - `todos`
     - `activities`
     - `login_attempts`
   - That structure shows clear boundaries between identity, collaboration/workspace membership, task tracking, and audit logging.

6. **Cross-cutting helpers**
   - **`app/Helpers/ActivityLogger.php`** is the shared audit trail writer used when important domain changes happen.
   - **`app/Helpers/ProgressCalculator.php`** computes card/workspace progress from todo state.
   - **`app/Helpers/FileUploadHelper.php`** handles avatar upload validation/storage.
   - These helpers indicate that progress and auditing are not embedded in the UI; they are backend concerns shared across controllers.

7. **Security and access control**
   - The app uses **bcrypt** for password hashing, **prepared statements** via PDO, **CSRF tokens**, and **session regeneration after login**.
   - Authentication state is session-based, and access is further constrained by:
     - workspace roles: **Owner / Admin / Member**
     - card-level access control through **`card_access`**
   - The presence of **`login_attempts`** suggests brute-force tracking or rate-limiting logic around authentication.

8. **Server-rendered UI layer**
   - Views are organized under **`app/Views/layouts`**, **`pages`**, and **`partials`**.
   - There are separate layouts for authenticated vs. auth pages:
     - **`layouts/main.php`**
     - **`layouts/auth.php`**
   - Key pages include dashboard, login, register, profile, and workspace.
   - Shared UI fragments like sidebar, toast notifications, and confirmation modal are isolated as partials.

9. **Client-side interaction layer**
   - Frontend behavior is split into ES modules under **`public/js/modules`** and page-specific scripts under **`public/js/pages`**.
   - Modules like **api**, **card**, **todo**, **activity**, **sidebar**, **modal**, and **toast** suggest the UI makes incremental requests back to the PHP backend rather than doing a full SPA rewrite.
   - The frontend is therefore a thin interaction layer over server-rendered pages and JSON-style actions.

10. **File and asset handling**
   - Static assets are served from **`public/css`** and **`public/js`**.
   - User-uploaded avatars live under **`public/uploads/avatars`**, with a local `.htaccess` indicating explicit access control for that directory.
   - CSS is structured with tokens, base styles, component styles, and layout styles, which supports a componentized UI but not a separate design system service.

11. **Primary data flows**
   - **Authentication flow:** browser → AuthController → UserModel / LoginAttemptModel → Session → redirected authenticated views.
   - **Workspace/card/todo flow:** browser action → controller → model updates → progress recalculation → activity log entry → updated dashboard/workspace view.
   - **Activity flow:** controllers write events through ActivityLogger; ActivityController reads/filter/paginates them for display.
   - **Profile flow:** profile form submission → ProfileController → UserModel + FileUploadHelper → updated session-visible profile data.

12. **Operational/runtime boundaries**
   - The app is intended to run on a standard PHP server, with local development via **`php -S localhost:8000 -t public`**.
   - Composer is used for dependency management, but the architecture is otherwise framework-light and self-contained.
   - The meaningful external dependency is the MySQL database; everything else is file-based within the repo or browser-delivered assets.

Main entry points: [`app/Core/Router.php`](https://github.com/dapbyte/traceon-private/blob/main/app/Core/Router.php) (Router), [`public/js/main.js`](https://github.com/dapbyte/traceon-private/blob/main/public/js/main.js) (Browser modules), [`app/Views/layouts/main.php`](https://github.com/dapbyte/traceon-private/blob/main/app/Views/layouts/main.php) (Views), [`app/Controllers/AuthController.php`](https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/AuthController.php) (Auth)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_g1["Request layer"]
  node_n1["Front controller<br/>php entrypoint<br/>[index.php]"]
  node_n2["Rewrite rules<br/>apache routing<br/>[.htaccess]"]
  node_n3["Router<br/>[Router.php]"]
  node_n4["Request/Response<br/>http abstractions<br/>[Request.php]"]
end

subgraph group_g2["Domain backend"]
  node_n5[("Core services<br/>runtime services<br/>[Database.php]")]
  node_n6["Base controller<br/>controller base<br/>[BaseController.php]"]
  node_n7["Auth<br/>controller<br/>[AuthController.php]"]
  node_n8["Workspace<br/>controller"]
  node_n9["Members<br/>controller"]
  node_n10["Cards<br/>controller<br/>[CardController.php]"]
  node_n11["Todos<br/>controller<br/>[TodoController.php]"]
  node_n12["Activity<br/>controller"]
  node_n13["Profile<br/>controller"]
  node_n14["Health<br/>controller"]
  node_n15["Models<br/>[UserModel.php]"]
  node_n16["Audit helper<br/>[ActivityLogger.php]"]
  node_n17["Progress helper"]
  node_n18["Upload helper"]
end

subgraph group_g3["UI layer"]
  node_n19["Views<br/>server-rendered UI<br/>[main.php]"]
  node_n20["Browser modules<br/>js modules<br/>[main.js]"]
  node_n21["Assets<br/>[base.css]"]
end

subgraph group_g4["Persistence"]
  node_n22["Schema migrations<br/>sql migrations<br/>[0001_init.sql]"]
  node_n23[("MySQL data<br/>database")]
  node_n24["Session files<br/>runtime state"]
end

node_n2 -->|"rewrites to"| node_n1
node_n1 -->|"dispatches via"| node_n3
node_n3 -->|"creates"| node_n4
node_n3 -->|"routes to"| node_n7
node_n3 -->|"routes to"| node_n8
node_n3 -->|"routes to"| node_n9
node_n3 -->|"routes to"| node_n10
node_n3 -->|"routes to"| node_n11
node_n3 -->|"routes to"| node_n12
node_n3 -->|"routes to"| node_n13
node_n3 -->|"routes to"| node_n14
node_n7 -->|"uses"| node_n5
node_n8 -->|"uses"| node_n15
node_n9 -->|"uses"| node_n15
node_n10 -->|"uses"| node_n15
node_n11 -->|"uses"| node_n15
node_n12 -->|"reads/writes"| node_n16
node_n10 -->|"recalculates"| node_n17
node_n11 -->|"updates"| node_n17
node_n13 -->|"uploads via"| node_n18
node_n7 -->|"stores auth state"| node_n24
node_n5 -->|"connects to"| node_n23
node_n22 -->|"bootstraps"| node_n23
node_n15 -->|"queries"| node_n23
node_n19 -->|"drives"| node_n20
node_n20 -->|"calls"| node_n7
node_n20 -->|"calls"| node_n10
node_n20 -->|"calls"| node_n11
node_n20 -->|"calls"| node_n12
node_n21 -->|"styles"| node_n19
node_n21 -->|"supports"| node_n20
node_n6 -->|"renders"| node_n19
node_n7 -->|"renders"| node_n19
node_n8 -->|"renders"| node_n19
node_n13 -->|"renders"| node_n19

click node_n1 "https://github.com/dapbyte/traceon-private/blob/main/public/index.php"
click node_n2 "https://github.com/dapbyte/traceon-private/blob/main/public/.htaccess"
click node_n3 "https://github.com/dapbyte/traceon-private/blob/main/app/Core/Router.php"
click node_n4 "https://github.com/dapbyte/traceon-private/blob/main/app/Core/Request.php"
click node_n5 "https://github.com/dapbyte/traceon-private/blob/main/app/Core/Database.php"
click node_n6 "https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/BaseController.php"
click node_n7 "https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/AuthController.php"
click node_n8 "https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/WorkspaceController.php"
click node_n9 "https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/MemberController.php"
click node_n10 "https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/CardController.php"
click node_n11 "https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/TodoController.php"
click node_n12 "https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/ActivityController.php"
click node_n13 "https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/ProfileController.php"
click node_n14 "https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/HealthController.php"
click node_n15 "https://github.com/dapbyte/traceon-private/blob/main/app/Models/UserModel.php"
click node_n16 "https://github.com/dapbyte/traceon-private/blob/main/app/Helpers/ActivityLogger.php"
click node_n17 "https://github.com/dapbyte/traceon-private/blob/main/app/Helpers/ProgressCalculator.php"
click node_n18 "https://github.com/dapbyte/traceon-private/blob/main/app/Helpers/FileUploadHelper.php"
click node_n19 "https://github.com/dapbyte/traceon-private/blob/main/app/Views/layouts/main.php"
click node_n20 "https://github.com/dapbyte/traceon-private/blob/main/public/js/main.js"
click node_n21 "https://github.com/dapbyte/traceon-private/blob/main/public/css/base.css"
click node_n22 "https://github.com/dapbyte/traceon-private/blob/main/migrations/0001_init.sql"
click node_n24 "https://github.com/dapbyte/traceon-private/tree/main/sessions/sess_7bblu43bbdoe40hdtih724kefd"

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_n1,node_n2,node_n3,node_n4 toneBlue
class node_n5,node_n6,node_n7,node_n8,node_n9,node_n10,node_n11,node_n12,node_n13,node_n14,node_n15,node_n16,node_n17,node_n18 toneAmber
class node_n19,node_n20,node_n21 toneMint
class node_n22,node_n23,node_n24 toneRose
```

## Components

### Request layer

HTTP entrypoint, routing, and response handling

- [Front controller](https://github.com/dapbyte/traceon-private/blob/main/public/index.php): php entrypoint · Main HTTP entry through the public web root · `public/index.php`
- [Rewrite rules](https://github.com/dapbyte/traceon-private/blob/main/public/.htaccess): apache routing · Web server rewrite boundary into the front controller · `public/.htaccess`
- [Router](https://github.com/dapbyte/traceon-private/blob/main/app/Core/Router.php): http router · Maps routes to controller actions · `app/Core/Router.php`
- [Request/Response](https://github.com/dapbyte/traceon-private/blob/main/app/Core/Request.php): http abstractions · Request parsing and response emission · `app/Core/Request.php`

### Domain backend

Controllers, models, helpers, and shared config

- [Core services](https://github.com/dapbyte/traceon-private/blob/main/app/Core/Database.php): runtime services · Database, session, and CSRF boundaries · `app/Core/Database.php`
- [Base controller](https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/BaseController.php): controller base · Shared controller utilities for rendering and auth checks · `app/Controllers/BaseController.php`
- [Auth](https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/AuthController.php): controller · Login, registration, logout, and auth state · `app/Controllers/AuthController.php`
- [Workspace](https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/WorkspaceController.php): controller · Workspace lifecycle and invite/join flows · `app/Controllers/WorkspaceController.php`
- [Members](https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/MemberController.php): controller · Workspace membership and roles · `app/Controllers/MemberController.php`
- [Cards](https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/CardController.php): controller · Card management and access control · `app/Controllers/CardController.php`
- [Todos](https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/TodoController.php): controller · Todo CRUD and status updates · `app/Controllers/TodoController.php`
- [Activity](https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/ActivityController.php): controller · Activity feed, search, filter, and pagination · `app/Controllers/ActivityController.php`
- [Profile](https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/ProfileController.php): controller · Profile updates and avatar handling · `app/Controllers/ProfileController.php`
- [Health](https://github.com/dapbyte/traceon-private/blob/main/app/Controllers/HealthController.php): controller · App status endpoint · `app/Controllers/HealthController.php`
- [Models](https://github.com/dapbyte/traceon-private/blob/main/app/Models/UserModel.php): persistence models · Domain models for users, workspaces, cards, todos, membership, activity, and login attempts · `app/Models/UserModel.php`
- [Audit helper](https://github.com/dapbyte/traceon-private/blob/main/app/Helpers/ActivityLogger.php): helper · Shared activity/event logging · `app/Helpers/ActivityLogger.php`
- [Progress helper](https://github.com/dapbyte/traceon-private/blob/main/app/Helpers/ProgressCalculator.php): helper · Computes progress from todo state · `app/Helpers/ProgressCalculator.php`
- [Upload helper](https://github.com/dapbyte/traceon-private/blob/main/app/Helpers/FileUploadHelper.php): helper · Validates and stores avatar uploads · `app/Helpers/FileUploadHelper.php`

### UI layer

Server-rendered views and browser modules

- [Views](https://github.com/dapbyte/traceon-private/blob/main/app/Views/layouts/main.php): server-rendered UI · Layouts, pages, and shared partials · `app/Views/layouts/main.php`
- [Browser modules](https://github.com/dapbyte/traceon-private/blob/main/public/js/main.js): js modules · Incremental client-side interaction modules · `public/js/main.js`
- [Assets](https://github.com/dapbyte/traceon-private/blob/main/public/css/base.css): static assets · CSS, JavaScript, and uploaded avatars · `public/css/base.css`

### Persistence

Database schema and runtime state

- [Schema migrations](https://github.com/dapbyte/traceon-private/blob/main/migrations/0001_init.sql): sql migrations · Initial schema and later priority extension · `migrations/0001_init.sql`
- **MySQL data**: database · Persistent domain tables and login attempt tracking
- [Session files](https://github.com/dapbyte/traceon-private/tree/main/sessions/sess_7bblu43bbdoe40hdtih724kefd): runtime state · File-backed PHP session storage · `sessions/sess_7bblu43bbdoe40hdtih724kefd`

## Connections

- Rewrite rules → Front controller: rewrites to · Web requests are routed into the front controller
- Front controller → Router: dispatches via · Front controller hands off to centralized routing
- Router → Request/Response: creates · Routes operate on request and response objects
- Router → Auth: routes to · Authentication endpoints
- Router → Workspace: routes to · Workspace lifecycle endpoints
- Router → Members: routes to · Membership and role endpoints
- Router → Cards: routes to · Card endpoints
- Router → Todos: routes to · Todo endpoints
- Router → Activity: routes to · Activity endpoints
- Router → Profile: routes to · Profile endpoints
- Router → Health: routes to · Health endpoint
- Auth → Core services: uses · Authentication relies on DB, sessions, and CSRF
- Workspace → Models: uses · Workspace orchestration persists through models
- Members → Models: uses · Membership changes flow through models
- Cards → Models: uses · Card state and access control are model-backed
- Todos → Models: uses · Todo updates are persisted through models
- Activity → Audit helper: reads/writes · Activity feed is written by helpers and read by controller
- Cards → Progress helper: recalculates · Card progress is derived from todo state
- Todos → Progress helper: updates · Todo changes can trigger progress recomputation
- Profile → Upload helper: uploads via · Avatar updates pass through upload validation/storage
- Auth → Session files: stores auth state · Session-backed authentication state
- Core services → MySQL data: connects to · PDO/MySQL persistence boundary
- Schema migrations → MySQL data: bootstraps · Migrations define the database structure
- Models → MySQL data: queries · All domain models persist to the MySQL database
- Views → Browser modules: drives · Rendered pages are enhanced by browser modules
- Browser modules → Auth: calls · Client-side actions invoke backend auth flows
- Browser modules → Cards: calls · Client-side card interactions hit the card controller
- Browser modules → Todos: calls · Client-side todo interactions hit the todo controller
- Browser modules → Activity: calls · Activity UI uses backend activity endpoints
- Assets → Views: styles · CSS assets support the rendered views
- Assets → Browser modules: supports · JavaScript and static assets ship the client layer
- Base controller → Views: renders · Controllers share rendering into layouts and pages
- Auth → Views: renders · Auth views use the auth layout and pages
- Workspace → Views: renders · Workspace and dashboard views are server-rendered
- Profile → Views: renders · Profile view is server-rendered
