Roadmapping
Modality's roadmapping feature helps you plan data platform development by automatically scheduling tasks based on dependencies, team capacity, and estimated effort.
Overview
Roadmapping in Modality provides:
- Automatic task generation from your data model
- Intelligent dependency suggestions based on entity relationships
- Capacity-based scheduling using team size and availability
- Visual timeline with Gantt chart representation
- Progress tracking with task statuses
- Manual overrides for custom scenarios
Core Concepts
Tasks
A task represents work to be done:
- Entity tasks: Build a data entity (table, view, model)
- Source tasks: Integrate a data source
- Report tasks: Build a dashboard or report
- Component tasks: Create cube, metric, API, stream, or reverse-ETL
- Data product tasks: Package a complete data product
Each task includes:
- Estimated hours: From estimation model or defaults
- Dependencies: Other tasks that must complete first
- Assignment: Who's working on it
- Status: not-started, in-progress, completed
- Dates: Calculated start and end dates
Dependencies
Tasks can depend on other tasks, creating a critical path:
Automatic dependencies are suggested based on:
- Entity relationships (
belongs-to,derived-from,contains) - Entities used in reports and metrics
- Logical model mappings
Manual dependencies can be added or overridden.
Team Capacity
Schedule calculated based on:
- Team size: Number of people available
- Hours per day: Available hours per person per day
days_required = CEIL(estimated_hours / (team_size * hours_per_day))Roadmap Configuration
Basic Setup
roadmap {
start_date = "2025-01-01"
team_size = 2
hours_per_day = 6
}Attributes
start_date: When the project begins (ISO date format)team_size: Number of people on the team (default: 2)hours_per_day: Available hours per person per day (default: 6)
Example configurations:
# Solo developer
roadmap {
start_date = "2025-01-15"
team_size = 1
hours_per_day = 8
}
# Small team, part-time
roadmap {
start_date = "2025-02-01"
team_size = 3
hours_per_day = 4
}
# Full team, dedicated
roadmap {
start_date = "2025-03-01"
team_size = 5
hours_per_day = 8
}Task Types
Entity Tasks
Tasks for building data entities.
task "Build Customer Entity" {
builds "Sales.Customer"
depends_on "Integrate CRM Source"
assignee = "alice"
status = "in-progress"
}Attributes:
builds: Reference to entity ("Domain.Entity")depends_on: Task dependencies (optional, auto-suggested)assignee: Person responsible (optional)status:"not-started"|"in-progress"|"completed"(default: "not-started")manual_hours: Override estimated hours (optional)notes: Task notes (optional)
Hour estimation: Pulled from entity_estimate or default (8 hours)
Auto-suggested dependencies:
- Entities referenced in
belongs-to - Entities referenced in
derived-from - Entities referenced in
contains
Source Tasks
Tasks for integrating data sources.
task "Integrate Production Database" {
builds "PostgreSQL_Production"
assignee = "bob"
status = "completed"
}Attributes:
builds: Reference to source ("SourceName")depends_on: Task dependencies (optional)assignee: Person responsible (optional)status: Task status (default: "not-started")manual_hours: Override estimated hours (optional)notes: Task notes (optional)
Hour estimation: Pulled from source_estimate or default (8 hours)
Auto-suggested dependencies: None (sources are typically first tasks)
Report Tasks
Tasks for building dashboards and reports.
task "Revenue Dashboard" {
builds "Sales Analytics.Revenue Dashboard"
depends_on "Build Customer Entity"
depends_on "Build Order Entity"
assignee = "charlie"
status = "not-started"
}Attributes:
builds: Reference to report ("ProductName.ReportName")depends_on: Task dependencies (optional, auto-suggested)assignee: Person responsible (optional)status: Task status (default: "not-started")manual_hours: Override estimated hours (optional)notes: Task notes (optional)
Hour estimation: Pulled from report_estimate or default (8 hours)
Auto-suggested dependencies:
- All entities referenced in report metrics (via
usesstatements)
Component Tasks
Tasks for specialized data product components.
task "Customer API Endpoint" {
builds "Customer 360.customer_api"
component_type = "api"
depends_on = "Build Customer Entity"
assignee = "diana"
status = "not-started"
}Component types:
report: BI dashboards (8 hours default)cube: OLAP cubes (16 hours default)metric: Standalone KPIs (4 hours default)reverse-etl: Data sync to operational systems (12 hours default)api: Programmatic access endpoints (10 hours default)stream: Real-time data streams (14 hours default)
Attributes:
builds: Reference to component ("ProductName.ComponentName")component_type: Component type (required)depends_on: Task dependencies (optional, auto-suggested)assignee: Person responsible (optional)status: Task status (default: "not-started")manual_hours: Override estimated hours (optional)notes: Task notes (optional)
Hour estimation: Default hours by component type
Auto-suggested dependencies:
- All entities referenced in the component
Data Product Tasks
Tasks for packaging complete data products.
task "Launch Sales Analytics" {
builds "Sales Analytics"
depends_on "Revenue Dashboard"
depends_on "Customer Insights Report"
assignee = "eve"
status = "not-started"
}Attributes:
builds: Reference to data product ("ProductName")depends_on: Task dependencies (required - typically all reports)assignee: Person responsible (optional)status: Task status (default: "not-started")manual_hours: Override estimated hours (optional)notes: Task notes (optional)
Hour estimation: Default (16 hours)
Auto-suggested dependencies: None (manually specify report dependencies)
Scheduling Algorithm
Date Calculation
For each task in order:
1. If task has dependencies:
start_date = MAX(end_date of all dependencies)
2. Else if not first task:
start_date = end_date of previous task
3. Else:
start_date = roadmap.start_date
4. Calculate duration:
days_required = CEIL(estimated_hours / (team_size * hours_per_day))
5. Calculate end date:
end_date = start_date + days_requiredExample Calculation
Given:
- Team size: 2 people
- Hours per day: 6 hours/person/day
- Capacity: 2 × 6 = 12 hours/day
Task 1: Build Customer (48 hours)
days_required = CEIL(48 / 12) = 4 days
start_date = 2025-01-01
end_date = 2025-01-05Task 2: Build Order (40 hours, depends on Customer)
days_required = CEIL(40 / 12) = 4 days
start_date = 2025-01-05 (Customer's end_date)
end_date = 2025-01-09Task 3: Revenue Dashboard (68 hours, depends on Customer + Order)
days_required = CEIL(68 / 12) = 6 days
start_date = 2025-01-09 (MAX of dependencies)
end_date = 2025-01-15Complete Example
# Configure roadmap
roadmap {
start_date = "2025-01-01"
team_size = 2
hours_per_day = 6
}
# Define entities with estimates
domain "Sales" {
entity "Customer" {
type = "entity"
description = "Customer master data"
}
entity "Order" {
type = "entity"
description = "Sales orders"
}
}
entity_estimate "Sales.Customer" {
data_quality = "medium"
data_volume = "large"
scd_type = "type-2"
business_rules_complexity = "moderate"
requires_resolution = false
derivation_count = 3
kpi_count = 2
testing_effort = 8
# Calculated: ~120 hours
}
entity_estimate "Sales.Order" {
data_quality = "high"
data_volume = "very-large"
scd_type = "type-1"
business_rules_complexity = "simple"
requires_resolution = false
derivation_count = 2
kpi_count = 1
testing_effort = 4
# Calculated: ~72 hours
}
# Define sources with estimates
source_estimate "PostgreSQL_Production" {
source_complexity = "simple"
data_volume = "large"
refresh_frequency = "hourly"
requires_auth = false
requires_transformation = false
# Calculated: ~10 hours
}
# Define data product
data_product "Sales Analytics" {
owner = "sales-team"
report "Revenue Dashboard" {
type = "dashboard"
uses "Sales.Customer"
uses "Sales.Order"
metric "Total Revenue" {
calculation = "SUM(Order.amount)"
uses "Sales.Order"
}
metric "Customer Count" {
calculation = "COUNT(DISTINCT Customer.id)"
uses "Sales.Customer"
}
}
}
report_estimate "Sales Analytics.Revenue Dashboard" {
report_complexity = "moderate"
visualization_count = 8
interactivity_level = "basic"
requires_custom_design = false
# Calculated: ~112 hours
}
# Define roadmap tasks
task "Setup Database Connection" {
builds "PostgreSQL_Production"
assignee = "alice"
status = "completed"
notes = "PostgreSQL read-only user configured"
# Hours: 10, Days: 1 (10/12), Start: 2025-01-01, End: 2025-01-02
}
task "Build Customer Entity" {
builds "Sales.Customer"
depends_on "Setup Database Connection"
assignee = "alice"
status = "in-progress"
# Hours: 120, Days: 10 (120/12), Start: 2025-01-02, End: 2025-01-12
}
task "Build Order Entity" {
builds "Sales.Order"
depends_on "Setup Database Connection"
assignee = "bob"
status = "not-started"
# Hours: 72, Days: 6 (72/12), Start: 2025-01-02, End: 2025-01-08
}
task "Create Revenue Dashboard" {
builds "Sales Analytics.Revenue Dashboard"
depends_on "Build Customer Entity" # auto-suggested
depends_on "Build Order Entity" # auto-suggested
assignee = "charlie"
status = "not-started"
notes = "Requires both Customer and Order entities"
# Hours: 112, Days: 10 (112/12), Start: 2025-01-12, End: 2025-01-22
}
task "Launch Sales Analytics" {
builds "Sales Analytics"
depends_on "Create Revenue Dashboard"
assignee = "alice"
status = "not-started"
# Hours: 16, Days: 2 (16/12), Start: 2025-01-22, End: 2025-01-24
}
# Total project duration: 2025-01-01 to 2025-01-24 (24 days)
# Critical path: Setup → Customer → Dashboard → LaunchDependency Management
Automatic Dependencies
Modality automatically suggests dependencies based on your data model:
For Entities:
domain "Sales" {
entity "Customer" {
type = "entity"
}
entity "Order" {
type = "entity"
contains entity.Customer # Relationship defined
}
}
# Auto-suggested dependency:
task "Build Order" {
builds "Sales.Order"
depends_on "Build Customer" # ← Automatically suggested
}For Reports:
report "Revenue Dashboard" {
metric "Total Revenue" {
uses "Sales.Order" # Entity reference
}
metric "Customer Count" {
uses "Sales.Customer" # Entity reference
}
}
# Auto-suggested dependencies:
task "Revenue Dashboard" {
builds "Sales Analytics.Revenue Dashboard"
depends_on "Build Order" # ← Auto from uses
depends_on "Build Customer" # ← Auto from uses
}Manual Dependencies
Override or add custom dependencies:
task "Build Customer 360" {
builds "Analytics.Customer360"
# Manual dependencies for specific reasons
depends_on "Build Customer"
depends_on "Build Order"
depends_on "Build Support Ticket"
depends_on "Setup Salesforce API"
notes = "Requires all customer touchpoint data"
}Complex Dependency Chains
Dependencies create critical paths:
# Foundation
task "Setup Infrastructure" {
builds "AWS_Account"
manual_hours = 40
}
# Data sources (parallel)
task "Integrate CRM" {
builds "Salesforce_API"
depends_on "Setup Infrastructure"
}
task "Integrate Database" {
builds "PostgreSQL_Production"
depends_on "Setup Infrastructure"
}
# Entities (parallel after sources)
task "Build Customer" {
builds "Sales.Customer"
depends_on "Integrate CRM"
depends_on "Integrate Database"
}
task "Build Product" {
builds "Sales.Product"
depends_on "Integrate Database"
}
task "Build Order" {
builds "Sales.Order"
depends_on "Integrate Database"
depends_on "Build Customer" # Logical dependency
depends_on "Build Product" # Logical dependency
}
# Reports (after all entities)
task "Customer Dashboard" {
builds "Sales Analytics.Customer Dashboard"
depends_on "Build Customer"
depends_on "Build Order"
}
task "Product Dashboard" {
builds "Sales Analytics.Product Dashboard"
depends_on "Build Product"
depends_on "Build Order"
}
# Final product (after all reports)
task "Launch Sales Analytics" {
builds "Sales Analytics"
depends_on "Customer Dashboard"
depends_on "Product Dashboard"
}Critical path: Setup → Integrate → Build Order → Dashboards → Launch
Task Status Tracking
Status Values
not-started: Task hasn't begun (default)in-progress: Task is actively being worked oncompleted: Task is finished
Updating Status
task "Build Customer" {
builds "Sales.Customer"
status = "in-progress" # Current status
assignee = "alice"
notes = """
Started: 2025-01-05
40% complete as of 2025-01-08
Blocked: Waiting for CRM API access
"""
}Progress Tracking
Use notes to track progress:
task "Revenue Dashboard" {
builds "Sales Analytics.Revenue Dashboard"
status = "in-progress"
notes = """
Week 1: Completed mockups and design
Week 2: Built 5 of 8 visualizations
Remaining: 3 charts, testing, documentation
Expected completion: 2025-01-22
"""
}Best Practices
1. Start with Foundational Tasks
Order tasks logically:
# ✅ Good order
task "Setup Infrastructure" { ... } # First
task "Integrate Sources" { ... } # Second
task "Build Core Entities" { ... } # Third
task "Build Derived Entities" { ... } # Fourth
task "Create Reports" { ... } # Fifth
task "Launch Product" { ... } # Last2. Be Realistic with Team Capacity
Don't overestimate availability:
# ✅ Realistic
roadmap {
team_size = 2
hours_per_day = 6 # Accounts for meetings, interruptions
}
# ❌ Unrealistic
roadmap {
team_size = 2
hours_per_day = 10 # Nobody can sustain this
}3. Use Manual Hours for Uncertainty
Override estimates when you have better information:
task "Migrate Legacy System" {
builds "Legacy.MainframeData"
manual_hours = 200 # Known to be complex
notes = "Previous migration took 3 weeks with similar scope"
}4. Document Blockers and Risks
Use notes to track issues:
task "Build Customer 360" {
builds "Analytics.Customer360"
status = "in-progress"
notes = """
BLOCKER: Waiting for legal approval on PII handling
RISK: CRM API rate limits may cause delays
RISK: Data quality worse than expected
"""
}5. Update as You Learn
Adjust estimates and dependencies:
task "Build Order Entity" {
builds "Sales.Order"
manual_hours = 120 # Originally 72
notes = """
Original estimate: 72 hours
Revised: 120 hours after discovering:
- Complex tax calculation logic
- Multi-currency support needed
- Promo code validation required
"""
}6. Parallel vs. Sequential Work
Structure tasks to maximize parallelism:
# ✅ Good - parallel work
task "Build Customer" {
builds "Sales.Customer"
assignee = "alice"
}
task "Build Product" {
builds "Sales.Product"
assignee = "bob" # Can work in parallel
}
# ❌ Bad - artificial sequencing
task "Build Customer" {
builds "Sales.Customer"
}
task "Build Product" {
builds "Sales.Product"
depends_on "Build Customer" # Unnecessary dependency
}7. Group Similar Work
Assign related tasks to same person:
task "Build Customer" {
builds "Sales.Customer"
assignee = "alice"
}
task "Build Order" {
builds "Sales.Order"
assignee = "alice" # Same domain, same person
}
task "Customer Dashboard" {
builds "Analytics.Customer Dashboard"
assignee = "bob" # Different specialty (BI)
}Roadmap Visualization
Modality displays roadmaps as Gantt charts showing:
- Task bars: Duration and scheduling
- Dependencies: Arrows between tasks
- Critical path: Longest path through dependencies
- Progress: Color-coded by status
- Assignments: Who's working on what
- Timeline: Day/week/month/quarter views
Timeline views:
- Day view: Detailed daily scheduling
- Week view: Weekly sprints
- Month view: Monthly milestones
- Quarter view: High-level quarterly planning
Summary
Roadmapping in Modality provides:
✅ Automatic scheduling based on estimates and capacity ✅ Intelligent dependencies from your data model ✅ Visual timeline with Gantt charts ✅ Progress tracking with statuses ✅ Flexible overrides for custom scenarios ✅ Team capacity planning with realistic timelines
By combining estimation, dependencies, and team capacity, Modality creates realistic project timelines that adapt as your understanding improves.
