Back to .md Directory

DevPulse πŸ“Š β€” Technical Requirement Document

> Your Personal Developer Analytics Platform

May 2, 2026
0 downloads
1 views
ai rag
View source

DevPulse πŸ“Š β€” Technical Requirement Document

Your Personal Developer Analytics Platform

Version: 1.0
Author: Hijra Engineering
Date: February 17, 2026
Status: Draft
Related Document: DevPulse β€” Product Requirement Document v1.0


1. System Architecture Overview

DevPulse follows the modern ELT (Extract-Load-Transform) architecture pattern. Raw data is extracted from GitHub APIs using a Java application, loaded directly into BigQuery's raw layer, then transformed in-place using dbt. Apache Airflow orchestrates the entire pipeline on a daily schedule, and Metabase connects directly to BigQuery's mart layer for visualization.

1.1 Architecture Layers

LayerTechnologyResponsibility
ExtractionJava 21 + OkHttp/RetrofitPull data from GitHub REST API v3 and GraphQL API v4
LoadingJava + BigQuery Client SDKWrite raw JSON/structured data into BigQuery raw dataset
StorageGoogle BigQueryData warehouse with raw, staging, and mart datasets
Transformationdbt Core (Python)SQL-based models to clean, join, aggregate data
OrchestrationApache Airflow 2.xSchedule, monitor, and manage pipeline execution
VisualizationMetabase (OSS)Interactive dashboards and ad-hoc querying
InfrastructureDocker ComposeLocal development environment for all services

1.2 Data Flow

  1. GitHub API emits events (commits, PRs, reviews, repos).
  2. Java extractor fetches data via REST/GraphQL with pagination and rate-limit handling.
  3. Raw JSON payloads are loaded into BigQuery raw dataset tables.
  4. dbt staging models clean, type-cast, and deduplicate raw data.
  5. dbt mart models join, aggregate, and produce analytical tables.
  6. Metabase queries mart tables to render dashboards.
  7. Airflow triggers steps 2–5 daily and monitors execution.

2. Technology Stack Specifications

2.1 Extraction Layer β€” Java Application

ComponentSpecification
RuntimeJava 21 (LTS)
Build ToolGradle 8.x with Kotlin DSL
HTTP ClientOkHttp 4.x / Retrofit 2.x
JSON ProcessingJackson 2.x (databind + Java time module)
BigQuery SDKgoogle-cloud-bigquery 2.x
ConfigurationEnvironment variables + .env file (dotenv-java)
LoggingSLF4J + Logback
TestingJUnit 5 + Mockito

The extractor is structured as a modular Java application with the following packages:

  • com.devpulse.extractor.client β€” GitHub API client classes with retry logic and rate limiting.
  • com.devpulse.extractor.model β€” Data transfer objects mapping GitHub API responses.
  • com.devpulse.extractor.loader β€” BigQuery writer components for each entity type.
  • com.devpulse.extractor.config β€” Configuration management and environment parsing.
  • com.devpulse.extractor.orchestrator β€” Main entry point coordinating extraction and loading.

2.2 Storage Layer β€” Google BigQuery

2.2.1 Dataset Structure

DatasetPurposeAccess Pattern
devpulse_rawRaw data exactly as received from GitHub APIWrite by extractor, read by dbt staging
devpulse_stagingCleaned, typed, deduplicated dataManaged by dbt, read by dbt mart
devpulse_martAnalytical models optimized for queriesManaged by dbt, read by Metabase

2.2.2 Raw Layer Tables

TableSourcePartitioningClustering
raw_commitsGET /repos/{owner}/{repo}/commitsingestion_time (DAY)repo_full_name
raw_pull_requestsGET /repos/{owner}/{repo}/pullsingestion_time (DAY)repo_full_name, state
raw_reviewsGET /repos/{owner}/{repo}/pulls/{id}/reviewsingestion_time (DAY)repo_full_name
raw_repositoriesGET /user/reposingestion_time (DAY)language
raw_languagesGET /repos/{owner}/{repo}/languagesingestion_time (DAY)repo_full_name

2.2.3 Staging Layer Models

ModelSourceKey Transformations
stg_commitsraw_commitsParse dates, extract file stats, deduplicate by SHA
stg_pull_requestsraw_pull_requestsCalculate duration, normalize status, deduplicate by PR number
stg_reviewsraw_reviewsMap review states, link to PRs, deduplicate by review ID
stg_repositoriesraw_repositoriesExtract owner, normalize names, latest snapshot only
stg_languagesraw_languagesPivot language bytes, calculate percentages

2.2.4 Mart Layer Models

ModelTypeDescription
dim_dateDimensionCalendar dimension with day-of-week, week, month, quarter, year attributes
dim_repositoryDimensionRepository attributes: name, primary language, created date, visibility
fct_commitsFactOne row per commit: timestamp, repo, files changed, lines added/removed
fct_pull_requestsFactOne row per PR: created, merged, review count, time-to-merge
fct_reviewsFactOne row per review: timestamp, PR, review state, reviewer
agg_daily_activityAggregateDaily rollup: commit count, PR count, lines changed, active repos
agg_weekly_activityAggregateWeekly rollup with same metrics plus weekly trends
agg_language_usageAggregateLanguage usage over time by bytes, commits, and repos
agg_hourly_heatmapAggregateCommit counts by hour-of-day and day-of-week for heatmap

2.3 Transformation Layer β€” dbt

ComponentSpecification
Versiondbt Core 1.8+
Adapterdbt-bigquery
ProfileBigQuery service account with dataset-level permissions
Materialization (staging)View (cost-efficient, always fresh)
Materialization (mart facts)Incremental (append new data, reduce processing)
Materialization (mart dimensions)Table (full refresh, small datasets)
Materialization (mart aggregates)Table (full refresh for correctness)
Testing Frameworkdbt built-in tests + custom tests

2.3.1 dbt Project Structure

devpulse-dbt/
β”œβ”€β”€ dbt_project.yml
β”œβ”€β”€ profiles.yml
β”œβ”€β”€ models/
β”‚   β”œβ”€β”€ staging/      (stg_*.sql)
β”‚   β”œβ”€β”€ mart/         (dim_*, fct_*, agg_*)
β”‚   └── sources.yml
β”œβ”€β”€ tests/
β”œβ”€β”€ macros/
└── seeds/

2.3.2 dbt Testing Strategy

Test TypeCoverageExample
uniquePrimary keys in all modelsunique on fct_commits.commit_sha
not_nullRequired fieldsnot_null on fct_commits.committed_at
accepted_valuesEnum fieldsaccepted_values on fct_pull_requests.state ['open','closed','merged']
relationshipsForeign keysfct_commits.repo_id references dim_repository.repo_id
Custom: recencyData freshnessAssert max(committed_at) is within last 48 hours
Source freshnessRaw table freshnesswarn_after: 24h, error_after: 48h on raw tables

2.4 Orchestration Layer β€” Apache Airflow

ComponentSpecification
VersionApache Airflow 2.9+
ExecutorLocalExecutor (single-node for personal project)
DatabasePostgreSQL 15 (Airflow metadata)
DeploymentDocker Compose with official Airflow image
ScheduleDaily at 02:00 UTC
Retry Policy3 retries with 5-minute exponential backoff
AlertingEmail on failure (configurable)

2.4.1 DAG Design

devpulse_daily_pipeline β€” Main DAG executing the full ELT cycle:

  1. extract_commits β€” Run Java extractor for commit data
  2. extract_pull_requests β€” Run Java extractor for PR data (parallel with commits)
  3. extract_reviews β€” Run Java extractor for review data (depends on PRs)
  4. extract_repositories β€” Run Java extractor for repo metadata (parallel)
  5. dbt_run_staging β€” Execute dbt staging models (depends on all extractions)
  6. dbt_run_mart β€” Execute dbt mart models (depends on staging)
  7. dbt_test β€” Run dbt tests (depends on mart)

2.5 Visualization Layer β€” Metabase

ComponentSpecification
VersionMetabase OSS (latest stable)
DeploymentDocker container in compose stack
Database ConnectionBigQuery service account (read-only to mart dataset)
Internal DBPostgreSQL 15 (Metabase metadata, shared with Airflow)

2.5.1 Dashboard Specifications

Dashboard 1: Productivity Overview

  • Commit trend line (daily/weekly/monthly toggle).
  • Coding activity heatmap (hour vs day-of-week).
  • Current streak and longest streak cards.
  • Daily average commits (30-day rolling).

Dashboard 2: Language Analytics

  • Language usage pie chart (by bytes).
  • Language trend over time (stacked area).
  • Top repositories per language.

Dashboard 3: Pull Request Analytics

  • PR open-to-merge time distribution.
  • Review turnaround time trend.
  • PR volume by repository.
  • Merge rate percentage.

Dashboard 4: Repository Focus

  • Commit distribution across repositories (treemap).
  • Repository activity timeline.
  • Lines of code changed per repository.

3. Infrastructure and Deployment

3.1 Local Development Environment

The entire stack runs locally via Docker Compose for development and personal use. This keeps costs at zero while providing a production-like environment.

3.1.1 Docker Compose Services

ServiceImagePortsPurpose
airflow-webserverapache/airflow:2.9-python3.118080Airflow UI
airflow-schedulerapache/airflow:2.9-python3.11β€”DAG scheduling
airflow-initapache/airflow:2.9-python3.11β€”DB initialization
postgrespostgres:155432Metadata DB for Airflow + Metabase
metabasemetabase/metabase:latest3000Dashboard UI

3.2 Configuration and Secrets

SecretPurposeStorage
GITHUB_TOKENGitHub API personal access token.env file (git-ignored)
GOOGLE_APPLICATION_CREDENTIALSBigQuery service account key path.env file + key.json (git-ignored)
GCP_PROJECT_IDGoogle Cloud project identifier.env file
AIRFLOWCOREFERNET_KEYAirflow encryption key for connectionsDocker Compose env
METABASEDB*Metabase internal database connectionDocker Compose env

4. GitHub API Integration Design

4.1 API Endpoints

EndpointMethodData Extracted
/user/reposGETRepository list with metadata
/repos/{owner}/{repo}/commitsGETCommit history with stats
/repos/{owner}/{repo}/pulls?state=allGETAll pull requests
/repos/{owner}/{repo}/pulls/{number}/reviewsGETPR reviews
/repos/{owner}/{repo}/languagesGETLanguage byte counts

4.2 Rate Limiting Strategy

  • Primary limit: 5,000 requests/hour for authenticated requests.
  • Conditional requests: Use If-Modified-Since and ETag headers to avoid consuming rate limits on unchanged data.
  • Backoff: Exponential backoff starting at 1 second, doubling up to 60 seconds on 429/503 responses.
  • Rate tracking: Read X-RateLimit-Remaining headers and pause proactively when approaching limits.

4.3 Incremental Extraction

To minimize API calls and processing time, the extractor tracks the latest extracted timestamp per entity type. On each run, it only fetches records newer than the last successful extraction. This state is persisted in a BigQuery metadata table (devpulse_raw._extraction_metadata).


5. Data Quality Framework

LayerQuality CheckImplementation
ExtractionAPI response validationJava DTOs with required field validation
RawSchema enforcementBigQuery schema definitions with REQUIRED fields
StagingDeduplicationdbt models using ROW_NUMBER() with partition by natural key
StagingType castingSAFE_CAST with null handling for malformed data
MartReferential integritydbt relationship tests between fact and dimension tables
MartFreshness checksCustom dbt tests asserting max timestamp within SLA
MartValue constraintsdbt accepted_values and custom range tests

6. Security Considerations

  • Principle of least privilege: BigQuery service account has only dataset-level read/write permissions, not project-level admin.
  • Secret management: All tokens, keys, and credentials stored in .env files excluded from version control via .gitignore.
  • GitHub token scope: Personal access token with minimum required scopes (repo:read, user:read).
  • Network isolation: Docker services communicate on an internal bridge network; only UI ports are exposed to host.
  • Data sensitivity: No PII beyond public GitHub profile data. Commit messages may contain sensitive info; treat warehouse access as confidential.

7. Monitoring and Observability

  • Airflow UI: DAG run history, task duration trends, failure logs, and Gantt charts.
  • dbt artifacts: Run results and test results JSON files tracked per execution.
  • BigQuery audit logs: Query costs, slot usage, and data access patterns.
  • Extraction logs: Java application logs with structured JSON format (request counts, errors, durations).
  • Metabase usage: Dashboard view counts and query performance metrics.

8. Repository Structure

devpulse/
β”œβ”€β”€ extractor/              # Java Gradle project
β”‚   β”œβ”€β”€ build.gradle.kts
β”‚   └── src/main/java/com/devpulse/
β”œβ”€β”€ dbt/                    # dbt project
β”‚   β”œβ”€β”€ models/staging/
β”‚   β”œβ”€β”€ models/mart/
β”‚   └── tests/
β”œβ”€β”€ airflow/                # Airflow DAGs and config
β”‚   β”œβ”€β”€ dags/
β”‚   └── plugins/
β”œβ”€β”€ metabase/               # Metabase config and exports
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ .env.example
└── README.md

Related Documents