Architecture overview for Forge Apps

Architecture overview and best practices for privacy-aware analytics

πŸ“¦

Working Example Available

The following code is available in our sample app available on GitHub.

πŸ”— View the full Forge Analytics Example on GitHub

The Problem: Traditional analytics are privacy nightmares

Most analytics implementations are extremely leaky when it comes to personally identifiable information (PII) and End User Data (EUD). Frontend analytics automatically transmit:

  • User IP addresses (tracks location, identifies companies)
  • Browser referrer URLs (reveals internal Jira/Confluence navigation)
  • Full page URLs (contains project names, issue keys, sensitive data)
  • Page titles (contains issue summaries and keys)
  • User agent strings (device fingerprinting)
  • Session cookies (cross-site tracking)
  • Form data (accidentally capturing sensitive information and end user data)
// ❌ DANGEROUS: Typical frontend analytics
gtag('event', 'search', {
  search_term: 'ACME Corp Salary Review'  // Customer data leak!
});
// Google now knows about ACME Corp's HR processes

The Solution: Complete Backend Control

By routing ALL analytics through your backend, you control exactly what information reaches your analytics provider. No accidents, no leaks, less chance of compliance violations.

Frontend Events β†’ Backend Resolver β†’ Queue β†’ Consumer β†’ Analytics Provider
                                   ↑
                      Backend Events

Architecture Overview

This implementation uses a queue-based, privacy-first architecture with six core components that work together to provide enterprise-ready analytics while maintaining Atlassian compliance.

Frontend Layer

Frontend Events Module (static/spa/src/analytics/events.js)

  • Purpose: Central registry for all UI interaction tracking
  • Key Functions: trackTodoItemsLoaded(), optional identify() and group()
  • Privacy Protection: Only sends event names via invoke() - no PII, no URLs, no browser data
  • Integration: React components import specific tracking functions for consistency

Backend Layer

Backend Events Module (src/analytics/events.js)

  • Purpose: Central definition of business events and main tracking logic
  • Key Functions: trackCreate(), trackUpdate(), trackDelete(), trackDeleteAll(), core track() function
  • Architecture Role: Processes both frontend-routed events and direct backend events through unified queue system

Resolver Bridge (src/analytics/resolvers.js)

  • Purpose: Privacy barrier between frontend and analytics provider
  • Key Functions: trackEvent() (main frontend bridge), optional identify() and group()
  • Privacy Filter: Receives minimal frontend data, adds backend context, forwards to queue

Queue Infrastructure

Queue Consumer (src/analytics/consumer.js)

  • Purpose: Asynchronous event processing with automatic retry
  • Architecture: Processes three event types: identify, group, track
  • Reliability: Handles provider outages without affecting user experience
  • Configuration: Defined in manifest.yml as analytics-consumer with analytics-queue

HTTP Dispatcher (src/analytics/dispatcher.js)

  • Purpose: Transport layer to analytics provider (Accoil)
  • Key Functions: handleTrackEvent(), handleIdentify(), handleGroup()
  • Provider Support: Built with common format that works across analytics providers
  • Debug Mode: Environment-controlled logging for development testing

Supporting Components

Utility Functions (src/analytics/utils.js)

  • Purpose: Consistent identity management and data extraction
  • Key Functions: userIdFromContext(), groupIdFromContext()
  • Cost Optimization: Configurable user identification strategy (individual vs instance-level)

Scheduled Analytics (src/analytics/schedule.js)

  • Purpose: Automated organizational data updates
  • Function: dailyGroupAnalytics() - updates license status, usage metrics
  • Trigger: Daily scheduled job configured in manifest.yml
  • Data: Instance-level traits, license information, activity metrics

Infrastructure Configuration

Manifest Declaration (manifest.yml)

  • Queue System: Consumer, queue, and function definitions
  • Scheduled Triggers: Daily analytics jobs
  • External Permissions: Backend-only analytics egress with inScopeEUD: false
  • Critical Setting: category: analytics and inScopeEUD: false protect "Runs on Atlassian" status

Data Flow Architecture

Frontend-Triggered Events

  1. User Interaction β†’ Component calls trackTodoItemsLoaded()
  2. Frontend Bridge β†’ invoke('track-event', {event: 'Todos Loaded'})
  3. Resolver Processing β†’ Backend receives event name + Forge context
  4. Queue Insertion β†’ Event bundled with identity/group data and queued
  5. Async Processing β†’ Consumer processes event when provider is available
  6. HTTP Delivery β†’ Dispatcher sends to analytics provider

Backend-Triggered Events

  1. Business Logic β†’ Todo created in resolver.define('create')
  2. Direct Tracking β†’ await trackCreate(context) called immediately
  3. Queue Processing β†’ Same queue/consumer/dispatcher flow as frontend events

Scheduled Events

  1. Daily Trigger β†’ Forge executes dailyGroupAnalytics()
  2. Data Collection β†’ Gathers license info, usage metrics, instance status
  3. Direct Dispatch β†’ Bypasses queue (already scheduled), sends directly to provider

Privacy Protection Guarantees

Risk CategoryFrontend AnalyticsThis Architecture
IP Addresses❌ User's real IP sentβœ… Only Forge server IP visible
URLs/Referrers❌ Internal URLs leakedβœ… Never transmitted to provider
Browser Data❌ Full user agent sentβœ… Server-controlled data only
Session Data❌ Cookies, localStorage exposedβœ… No client-side data access
Form Inputs❌ Accidentally captured PIIβœ… Only intentional business events
Navigation Patterns❌ Full browsing historyβœ… Meaningful business actions only

Key Architecture Principles

  1. Privacy by Design: No accidental PII transmission possible
  2. Provider Abstraction: Easy switching between analytics services
  3. Central Event Management: Single source of truth for all tracked events
  4. Queue-Based Reliability: Enterprise-grade event delivery
  5. Customer Control: Customers can disable analytics via Atlassian controls.
  6. Compliance First: Built to exceed Atlassian's privacy requirements

Bottom Line: This architecture doesn't just ensure complianceβ€”it provides competitive advantage through customer trust and enterprise readiness.


What’s Next