Skip to content

Architecture Overview

Monorepo Structure

flowchart LR
    subgraph apps["apps/"]
        desktop["desktop/<br/>Tauri + Vite + React"]
        web["web/<br/>Next.js 14 App Router"]
        homepage["homepage/<br/>Next.js 14 Marketing"]
    end

    subgraph packages["packages/"]
        shared["shared/<br/>Types & Utilities"]
        api_client["api-client/<br/>Axios Client"]
    end

    subgraph infrastructure["infrastructure/"]
        lib["lib/<br/>CDK Stack"]
        lambda["lambda/<br/>7 Lambda Functions"]
        scripts_infra["scripts/<br/>Build Scripts"]
    end

    subgraph scripts["scripts/"]
        deploy["deploy.sh"]
    end

    desktop --> shared & api_client
    web --> shared & api_client
    api_client --> shared

Apps

App Framework Deployment Purpose
desktop Tauri + Vite + React 18 Tauri package Offline-first task tracker with IndexedDB (Dexie.js), Zustand state, bi-directional sync
web Next.js 14 (App Router) Cloudflare Pages Admin portal for managing tasks, time, customers, billing, integrations
homepage Next.js 14 Cloudflare Pages Marketing site with contact form for Bytes and Books

Packages

Package Purpose
shared TypeScript types and utility functions shared across all apps (zero dependencies)
api-client Axios-based HTTP client wrapping all API endpoints

Infrastructure

Directory Purpose
lib/task-time-stack.ts Single CDK stack defining all AWS resources
lambda/ 7 Lambda function directories, each independently bundled
scripts/build-lambdas.cjs esbuild script that bundles each Lambda directory

Deployment Topology

flowchart TB
    subgraph cloudflare["Cloudflare Pages"]
        web_cf["Web Portal<br/>(task-and-time-portal)"]
        homepage_cf["Homepage<br/>(bytes-and-books-homepage)"]
        docs_cf["Documentation<br/>(task-time-docs)"]
    end

    subgraph aws["AWS (us-east-1)"]
        apigw["API Gateway<br/>(REST)"]
        cognito["Cognito User Pool<br/>(task-time-users)"]
        lambdas["7 Lambda Functions<br/>(Node.js 20.x, 512-1024MB)"]
        dynamo["10 DynamoDB Tables<br/>(PAY_PER_REQUEST)"]
        ses["SES"]
        eventbridge["EventBridge"]
    end

    subgraph tauri["Tauri"]
        desktop_app["Desktop App<br/>(macOS / Windows / Linux)"]
    end

    subgraph external["External Services"]
        xero["Xero Accounting"]
        slack["Slack"]
        claude["Claude AI (Haiku)"]
        sentry["Sentry<br/>(4 projects)"]
    end

    web_cf & desktop_app -->|HTTPS + JWT| apigw
    apigw --> cognito
    apigw --> lambdas
    lambdas --> dynamo & ses
    eventbridge --> lambdas
    lambdas --> xero & slack & claude
    web_cf & homepage_cf & desktop_app & lambdas --> sentry

Build Pipeline

flowchart LR
    A["pnpm test"] --> B["pnpm build<br/>(all packages)"]
    B --> C["pnpm build:lambdas"]
    C --> D["Sentry Releases<br/>(4 projects)"]
    D --> E["Upload Source Maps"]
    E --> F["Deploy Web<br/>(Cloudflare Pages)"]
    E --> G["Deploy Homepage<br/>(Cloudflare Pages)"]
    E --> H["CDK Deploy<br/>(AWS)"]
    E --> I["Package Desktop<br/>(Tauri)"]
    F & G & H & I --> J["Finalize Sentry"]

The full pipeline runs via pnpm deploy:all which executes scripts/deploy.sh. Individual components can be deployed independently:

  • Web: pnpm build:web && cd apps/web && pnpm deploy
  • Homepage: pnpm build:homepage && cd apps/homepage && pnpm deploy
  • Infrastructure: pnpm build:lambdas && cd infrastructure && pnpm cdk deploy
  • Desktop: pnpm package:desktop
  • Docs: pnpm docs:deploy

Lambda Functions

All Lambdas run Node.js 20.x with 512MB memory (except slack-integration at 1024MB), 30-second timeout, and Sentry error tracking.

Lambda Trigger Tables (Write) Tables (Read) External
task-sync API Gateway tasks Cognito
time-entry-sync API Gateway time-entries, time-bills, pillars tasks, customers, customer-users, xero-tokens Xero
customer-sync API Gateway customers, customer-users, pillars, customer-focus, time-bills, time-entries, tasks Cognito, SES
status-check EventBridge tasks
active-timer-sync API Gateway active-timers
xero-sync API Gateway xero-tokens Xero
slack-integration API Gateway (Slack) tasks, slack-channel-mappings customers, pillars Slack, Claude AI, Cognito

Key Patterns

  • Enrichment: Time entries and bills support ?enrich=true to include related task, customer, user, and pillar names
  • TimeBill auto-generation: Created when timer stops; groups by (pillar, customer, day); rounds up to nearest 15 minutes
  • Xero sync: Non-blocking; approved bills → Xero time entries; rate hierarchy: pillar > customer > project
  • Slack task creation: Slash command or message action → Claude Haiku title → modal → task (status: intake)
  • Status auto-transitions: EventBridge-triggered Lambda checks exploded/blocked tasks and transitions when conditions met