What Are the Trackers?

A suite of internal operational tools built on Cloudflare Workers + D1. There are two systems that share a single D1 database:

  1. Task Trackers โ€” three separate task-management dashboards (Sonan Group HQ, Harper's Preserve, Woodridge), each showing tasks, priorities, assignments, progress charts, and a timeline. All three call the same backend Worker API.
  2. Timesheet Tracker โ€” employee clock-in/clock-out, pay period management, tax settings, pay stubs, and admin controls for the SONAN TECH repair shops.

Repo & Folder

ItemValue
Local rootE:\Claude_Projects\sonan-trackers\
GitHubhttps://github.com/sonantechai/sonan-trackers
Cloudflare accountsonantechai (ID: a7bd7d4b54bb7cb5907f8ddd45c3e5d9)

Live URLs

SystemURLCloudflare Pages Project
Sonan Group Trackersonan-tracker.sonandigital.comsonan-tracker
Harper's Preserve Trackerhp-tracker.sonandigital.com (approx)harpers-preserve-tracker
Woodridge Trackerwr-tracker.sonandigital.com (approx)woodridge-tracker
Timesheet Trackersonantech-timesheet-tracker.sonandigital.comsonantech-timesheet
Task Tracker APIsonan-tracker-api.sonantechai.workers.devCloudflare Worker
Timesheet APIsonan-timesheet-api.sonantechai.workers.devCloudflare Worker

Tech Stack

LayerTechnology
FrontendPlain HTML / CSS / JavaScript โ€” static files served by Cloudflare Pages
BackendCloudflare Workers (edge JS) โ€” one worker per system
DatabaseCloudflare D1 (SQLite at the edge) โ€” both systems share one DB
Auth โ€” task trackersTwo-layer: hardcoded HTML password gate โ†’ localStorage SHA-256 app password
Auth โ€” timesheetAPI key header (X-API-Key) + server-side admin password hash in D1
EncryptionAES-256-GCM for sensitive timesheet data (pay rates, SSN) via ENCRYPT_KEY Worker secret

File Structure

sonan-trackers/
  sonan-tracker/
    Sonan/index.html          โ† Sonan Group task tracker frontend
    HP/index.html             โ† Harper's Preserve task tracker frontend
    WR/index.html             โ† Woodridge task tracker frontend
    worker.js                 โ† Task tracker backend Worker API
    wrangler.toml             โ† Worker config (sonan-tracker-api, sonan-tracker-db)
    sonan-timesheet/
      worker.js               โ† Timesheet backend Worker API
      wrangler.toml           โ† Worker config (sonan-timesheet-api, same D1 DB)
      html/
        index.html            โ† Timesheet frontend
  Timesheet-Tracker/          โ† Legacy/archived version (do not deploy)
  timesheet_migration.sql     โ† DB migration file used July 2026
  DEPLOYMENT-GUIDE.md        โ† How to deploy all components

Shared Database

Both workers bind to the same Cloudflare D1 database. They use separate table namespaces โ€” task tables are used by the task worker, timesheet tables by the timesheet worker.

PropertyValue
Database namesonan-tracker-db
Database IDd0e1e4d2-42be-4e0d-a521-534e7c4ebb99
Accountsonantechai

Key Tables

TableUsed byPurpose
tasksTask trackerSonan Group tasks
hp_tasksTask trackerHarper's Preserve tasks
wr_tasksTask trackerWoodridge tasks
employeesTimesheetEmployee records (AES-encrypted fields)
time_entriesTimesheetClock-in/out records, hours
pay_periodsTimesheetPay period summaries, deductions, advances
tax_settingsTimesheetKey/value config including admin_pw_hash
storesTimesheetStore locations
holidaysTimesheetFederal/custom holidays (id, holiday_date, name, type)
advancesTimesheetPay advances to employees
schedulesTimesheetEmployee shift schedules

How to Deploy

Frontend (Cloudflare Pages โ€” auto-deploy on push)

Each tracker frontend is a Cloudflare Pages project connected to sonantechai/sonan-trackers on GitHub. Push to main and Pages rebuilds automatically. No build command โ€” pure static HTML.

Pages ProjectRoot Directory in Repo
sonan-trackersonan-tracker/Sonan
harpers-preserve-trackersonan-tracker/HP
woodridge-trackersonan-tracker/WR
sonantech-timesheetsonan-tracker/sonan-timesheet/html

Backend Workers (manual deploy)

Workers are deployed via wrangler deploy from Windows terminal. They do NOT auto-deploy from GitHub.

# Task tracker API
cd "E:\Claude_Projects\sonan-trackers\sonan-tracker"
npx wrangler deploy

# Timesheet API
cd "E:\Claude_Projects\sonan-trackers\sonan-tracker\sonan-timesheet"
npx wrangler deploy

Worker Secrets

Set once via Wrangler CLI, stored in Cloudflare (not in wrangler.toml):

# Task tracker
npx wrangler secret put API_KEY        # value: Sonan2026

# Timesheet
cd sonan-timesheet
npx wrangler secret put API_KEY        # value: SonanTS2026
npx wrangler secret put ENCRYPT_KEY    # value: 64-char hex AES-256 key

Authentication โ€” How It Works

Task Trackers (Sonan, HP, WR)

Two-layer client-side protection:

  1. Layer 1 โ€” Hardcoded gate: An immediately-invoked function at page load checks a hardcoded password variable embedded in the HTML. This runs before anything else. Password: SONANGroup!. This gate persists across incognito/private browsing because it is in the HTML, not localStorage.
  2. Layer 2 โ€” Setup + app password: After passing layer 1, if localStorage.st_api_url is not set, the app shows a setup screen asking for API URL, API key, and a new app password. The app password is SHA-256 hashed and stored in localStorage.st_pw_hash. Subsequent loads show the lock screen requiring the app password.

Timesheet Tracker

Server-side auth via the Worker:

  • All requests to the timesheet Worker require header X-API-Key: SonanTS2026. Requests without it return 401 immediately โ€” the frontend will appear broken with no data if the API key is not configured.
  • Admin login: username admin, password checked by the Worker against admin_pw_hash in the tax_settings D1 table. Hash format: SHA-256("SONAN_TS_SALT_2026_" + plaintext_password).
  • If admin_pw_hash is not set or equals SETUP_REQUIRED, first login sets the password.

Common Mistakes to Avoid

MistakePrevention
Timesheet shows no employees / all API calls failFrontend must have API URL and API Key configured in Settings. X-API-Key header is required on every request.
Trying to reset task tracker password via localStorage in incognitoLayer 1 password (SONANGroup!) is hardcoded in HTML โ€” localStorage is irrelevant for it. It works the same in incognito.
Deploying worker changes by pushing to GitHubWorkers are NOT connected to GitHub. Must run npx wrangler deploy manually from Windows terminal.
Running wrangler from Claude sandboxSandbox cannot authenticate to Cloudflare (403 proxy). All wrangler commands run from user's Windows terminal.
Assuming both workers use separate databasesBoth the task worker and timesheet worker bind to the same D1 DB ID (d0e1e4d2). Schema changes affect both.
Using old malikadnanakram worker URLsAll workers are now in sonantechai account. Old malikadnanakram.workers.dev URLs no longer serve current data.