The central hub: developers, clients, and projects connect to all work tracking domains.
erDiagram
developers {
varchar id PK "DEV-xxxxxxxx"
varchar clockify_id UK
varchar name
varchar email
varchar github_username
float cost_rate "hourly"
float monthly_cost "NEW"
varchar status
}
clients {
varchar id PK "CLI-xxxxxxxx"
varchar clockify_id UK
varchar name
varchar billing_model "retainer | hourly"
float retainer_amount
varchar parent_client_id FK
varchar status
}
projects {
varchar id PK "PRJ-xxxxxxxx"
varchar clockify_id UK
varchar client_id FK
varchar name
float hourly_rate "HMR only"
varchar status
}
repo_mappings {
serial id PK "NEW"
varchar repo UK "org/repo-name"
varchar client_id FK
varchar project_id FK
}
clients ||--o{ projects : "has"
clients ||--o| clients : "parent rollup"
clients ||--o{ repo_mappings : "owns"
projects ||--o{ repo_mappings : "mapped"
Claude Code sessions with 30-minute activity buckets, full prompt/response history, and ticket extraction.
erDiagram
claude_sessions {
varchar id PK "session UUID"
varchar developer_id FK
varchar client_id FK
varchar project_id FK
varchar model
int input_tokens
int output_tokens
int cache_read_tokens
int cache_creation_tokens
float cost_usd
int duration_seconds
int api_requests
varchar cwd
timestamp session_start
timestamp session_end
}
session_activity {
serial id PK "NEW"
varchar session_id FK
timestamp bucket_start "30-min"
timestamp bucket_end
int input_tokens
int output_tokens
int api_requests
int user_prompts
float cost_usd
text summary
}
session_prompts {
serial id PK "NEW"
varchar session_id FK
timestamp timestamp
text prompt_text
boolean has_image
varchar ticket_keys
}
session_responses {
serial id PK "NEW"
varchar session_id FK
int prompt_id FK
timestamp timestamp
text response_text
varchar model
int input_tokens
int output_tokens
text tool_calls "JSON"
}
session_tickets {
serial id PK "NEW"
varchar session_id FK
varchar ticket_key "CON-76"
timestamp first_mentioned_at
}
claude_sessions ||--o{ session_activity : "bucketed into"
claude_sessions ||--o{ session_prompts : "contains"
claude_sessions ||--o{ session_responses : "contains"
claude_sessions ||--o{ session_tickets : "mentions"
session_prompts ||--|| session_responses : "paired with"
Unified time entries from Clockify (historical) and Claude sessions (current). GitHub commits and PRs linked to developers.
erDiagram
time_entries {
varchar id PK
varchar clockify_id UK "nullable"
varchar developer_id FK
varchar project_id FK
varchar client_id FK "NEW"
varchar description
timestamp start_time
timestamp end_time
int duration_seconds
boolean billable
date local_date
varchar source "NEW: clockify | claude_session"
varchar session_id FK "NEW: nullable"
}
commits {
varchar id PK "CMT-xxxxxxxx"
varchar sha UK
varchar repo
varchar message
varchar developer_id FK
varchar github_author_login
timestamp authored_at
}
pull_requests {
varchar id PK "PR-repo-number"
int github_id UK
varchar repo
varchar title
varchar state
varchar developer_id FK
int additions
int deletions
timestamp opened_at
timestamp merged_at
}
claude_sessions ||--o| time_entries : "generates"
developers ||--o{ time_entries : "logs"
developers ||--o{ commits : "authors"
developers ||--o{ pull_requests : "opens"
Jira issues synced with status transition history. Assignee upgraded to FK for developer joins.
erDiagram
jira_issues {
varchar id PK
varchar key UK "CON-76"
varchar project_key "CON CC HD"
varchar summary
text description
varchar status
varchar status_category
varchar issue_type
varchar assignee_id FK "NEW"
float story_points
varchar parent_key "epic"
}
jira_transitions {
varchar id PK
varchar issue_id FK
varchar issue_key
varchar from_status
varchar to_status
varchar author
timestamp transitioned_at
}
jira_issues ||--o{ jira_transitions : "status history"
developers ||--o{ jira_issues : "assigned to"
Bank transactions from Plaid with business/personal scope. Accounts table maps IDs to labels.
erDiagram
transactions {
varchar id PK
date date
varchar description
float amount
varchar category
varchar type "income | expense"
varchar client_id FK "nullable"
varchar project_id FK "nullable"
varchar account_id FK "NEW"
varchar entity
varchar scope "NEW: business | personal"
boolean allocated
}
accounts {
varchar id PK "NEW: CHK-5809"
varchar plaid_account_id
varchar label "Business Checking"
varchar institution "Bank of America"
varchar scope "business | personal"
varchar account_type "checking | savings | credit"
}
plaid_items {
varchar id PK
varchar item_id UK
varchar access_token
varchar institution_name
varchar cursor
varchar status
}
plaid_items ||--o{ transactions : "sources"
accounts ||--o{ transactions : "categorizes"
clients ||--o{ transactions : "income from"
Developers, clients, and projects form the organizational backbone. Developers are the central hub — all work tracking connects through them. Clients are the billing hub.
| Table | Rows (est.) | Status |
|---|---|---|
| developers | ~10 | Existing Modified |
| clients | ~5 | Existing |
| projects | ~15 | Existing |
Claude Code session data captured via the host-level token-watcher daemon (polls Docker volumes every 30s). Per-session totals, 30-minute activity buckets, full prompt/response history, and extracted Jira ticket references.
| Table | Growth | Status |
|---|---|---|
| claude_sessions | ~20/day | Existing |
| session_activity | ~100/day | New |
| session_prompts | ~200/day | New |
| session_responses | ~400/day | New |
| session_tickets | ~30/day | New |
Time entries unify historical Clockify data and new session-derived hours via the source field. Commits and PRs sync from GitHub. Repo mappings link repos to clients for the productivity triangle.
| Table | Growth | Status |
|---|---|---|
| time_entries | ~5/day | Existing Modified |
| commits | ~20/day | Existing |
| pull_requests | ~3/day | Existing |
| repo_mappings | static | New |
Jira issues and transitions synced from Atlassian. Assignee field upgraded to FK for direct developer joins. Ticket keys cross-referenced with session_tickets for AI-work correlation.
| Table | Growth | Status |
|---|---|---|
| jira_issues | ~5/week | Existing Modified |
| jira_transitions | ~20/week | Existing |
Bank transactions from Plaid (Bank of America). New accounts table maps account IDs to labels and scope (business vs. personal). Transactions link to clients for revenue tracking.
| Table | Growth | Status |
|---|---|---|
| transactions | ~50/month | Existing Modified |
| accounts | static | New |
| plaid_items | static | Existing |
claude_sessions (upsert)session_activity, session_prompts, session_responses, session_ticketstime_entries (source=claude_session)time_entries (source=clockify), developers, clients, projectscommits, pull_requestsjira_issues, jira_transitionstransactionsCorrelate time + tokens + commits per developer per client per day. Joins time_entries, claude_sessions, and commits (via repo_mappings) on developer_id and client_id, grouped by date.
From a session ID, drill into 30-min activity buckets, individual prompts/responses, tools used, and tickets referenced. Joins claude_sessions → session_activity → session_prompts/session_responses.
Revenue (retainer amount or hours × rate) minus cost (developer monthly_cost × % of hours on client). Joins clients → time_entries → developers with transactions for income verification.
Daily overlay of Claude tokens, hours, and commits. session_activity provides 30-min granularity, time_entries provides work blocks, commits provides output markers.
| Convention | Format | Example |
|---|---|---|
| Developer IDs | DEV-{clockify_id[:8]} | DEV-654bca18 |
| Client IDs | CLI-{clockify_id[:8]} | CLI-6739d279 |
| Project IDs | PRJ-{clockify_id[:8]} | PRJ-6995a6bd |
| Commit IDs | CMT-{sha[:8]} | CMT-a5bd90e |
| PR IDs | PR-{repo_slug}-{number} | PR-contactos-v2-42 |
| Session IDs | UUID from Claude Code | 5cb7214b-... |
| Table names | snake_case, plural | claude_sessions |
| Column names | snake_case | developer_id |
| Timestamps | UTC, stored as timestamptz | 2026-04-07T14:30:00Z |
| Soft FKs | varchar, no DB constraint | Existing tables |
| Hard FKs | varchar with constraint | New tables |