Skip to content

Latest commit

 

History

History
161 lines (116 loc) · 6.29 KB

File metadata and controls

161 lines (116 loc) · 6.29 KB

1. Technical Specifications (Backend API)

Framework: itty-router (v5+) on Cloudflare Workers Runtime: WinterCG (Node.js compatibility disabled) Database: Cloudflare D1 (SQLite) Language: JavaScript (ES Modules) + JSDoc

1.1. Architecture Overview

The backend uses a localized "Fat-Free" architecture. It is a single Cloudflare Worker handling all API requests. The router delegates request handling to domain-specific modules. Modules leverage Dependency Injection (DI) principles, accepting valid D1Database bindings and Env configurations at runtime.

1.1.1. Directory Structure (Backend)

src/ ├── index.js // Entry point, Router definition ├── operations.js // Route handlers (entries, auth, FreshBooks) ├── middleware/ // Custom middleware (JWT auth) │ └── auth.js // JWT verification middleware └── modules/ ├── journal/ // Journal Entry logic (DAL + Service) │ ├── dal.js // Data Access Layer │ └── service.js // Business Logic └── freshbooks/ // FreshBooks API client ├── FreshBooksClient.js // API wrapper ├── service.js // Service layer └── index.js // Module exports

1.2. API Standards

  • Communication: JSON-only (Content-Type: application/json).
  • Errors: Standardized error envelope.
/* Error Response Format */
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Duration cannot be negative."
  }
}
  • Dates: ISO 8601 strings (YYYY-MM-DD for logical dates, ISO timestamps for created_at).

1.3. Authentication & Security

Implemented via FreshBooks OAuth 2.0 with JWT tokens (see ADR-006 for detailed design).

1.3.1. Auth Flow

  1. OAuth Login: User authenticates via FreshBooks OAuth 2.0 (/auth/login)
  2. JWT Token: Backend signs a short-lived JWT (15 min expiry) using @tsndr/cloudflare-worker-jwt
  3. Request Header: All protected API requests must include the token in the Authorization header
    • Standard: Authorization: Bearer <token>
  4. Token Storage: Access token kept in memory; HttpOnly refresh cookie (1 year) for token refresh
  5. Middleware: requireAuth middleware intercepts requests, verifies the JWT signature, checks expiry, and attaches the userId to the Request context

1.3.2. OAuth Integration

The API mounts OAuth handlers at:

  • /auth/login - Initiates FreshBooks OAuth flow
  • /auth/callback - Handles OAuth callback and issues JWT
  • /auth/refresh - Refreshes expired JWT using refresh cookie
  • /auth/logout - Clears authentication state

1.4. Modules & Data Models

1.4.1. A. Journal Module (modules/journal)

Handles the core "Write" and "Commit" loops.

D1 Schema (entries)

  • id (TEXT, PK): Nano ID or UUID.
  • user_id (TEXT, FK): Author.
  • client_id (TEXT): FreshBooks Client ID.
  • project_id (TEXT): FreshBooks Project ID (e.g., "CPC General").
  • service_id (TEXT): FreshBooks Service/Task ID (e.g., "DevOps").
  • billable (INTEGER): Boolean flag (0/1).
  • client_notes (TEXT): Public work log (Matches "Note" field).
  • private_notes (TEXT): Private/Internal context.
  • duration_minutes (INTEGER): Time spent.
  • date (TEXT): YYYY-MM-DD (Logical date of entry).
  • status (TEXT): 'DRAFT' | 'COMMITTED'.
  • synced_at (INTEGER): Timestamp of successful FreshBooks sync.

API Endpoints

  • GET /api/entries: List entries (query params: date, status, limit)
  • POST /api/entries: Create new entry
  • GET /api/entries/:id: Get single entry
  • PUT /api/entries/:id: Update entry (only if status is 'DRAFT')
  • PATCH /api/entries/:id: Update entry (alias for PUT)
  • DELETE /api/entries/:id: Delete entry (only if status is 'DRAFT')
  • POST /api/entries/sync: Bulk sync entries to FreshBooks
  • POST /api/entries/:id/retry-sync: Retry failed sync for single entry

1.4.2. B. FreshBooks Module (modules/freshbooks)

Abstracts the FreshBooks Accounting API.

Responsibilities

  • Reference Data: Retrieve Clients, Projects, and Services to populate frontend dropdowns
  • Time Entry Sync: POST time entries to FreshBooks for synced journal logs
  • User Info: Fetch authenticated user details (avatar, email, business)
  • Error Handling: Manage API rate limits and retry logic

API Endpoints

  • GET /api/freshbooks/user: Returns authenticated user info
  • GET /api/freshbooks/clients: Returns list of clients with projects
  • GET /api/freshbooks/projects: Returns list of projects
  • GET /api/freshbooks/services: Returns list of services/tasks
  • POST /api/entries/sync: Sync selected entries to FreshBooks

1.4.3. C. Preferences (/api/preferences)

User preferences for UI state persistence.

Responsibilities

  • Store user-specific preferences (favorite clients, last-used services, etc.)
  • Persist settings across sessions

API Endpoints

  • GET /api/preferences: Get user preferences
  • PUT /api/preferences: Update user preferences

1.4.4. D. Scrum Reporting (Frontend)

Client-side markdown generation for daily standup reports.

Responsibilities

  • Format synced entries as markdown grouped by client > project > service
  • Copy formatted markdown to clipboard for pasting into standup channels (Slack, Teams, etc.)
  • Separate private notes from client-facing content

Implementation

  • Frontend-only (no backend API)
  • Per-day copy button in entries UI
  • Markdown format: - Service: ticket (Client > Project)\n - Note line 1\n - Note line 2
  • Only includes SYNCED entries (excludes private_notes)

1.5. Middleware Chain

  1. CORS: Handle preflight and standard headers (implicit via Cloudflare Workers)
  2. withAuth: JWT validation middleware - verifies Authorization header and extracts userId
  3. Error Handler: Catch global exceptions and format as JSON (via itty-router error handling)

1.6. Implementation Notes

  • Dependency Injection: The Env object (containing DB, OAuth credentials, and JWT secret) is passed through the application
  • Validation: Manual validation with clear error messages for user input
  • OAuth Implementation: FreshBooks OAuth 2.0 with JWT token management (see ADR-006)
  • Token Management: @tsndr/cloudflare-worker-jwt for JWT signing/verification (WinterCG compatible)