feat: implement XER MCP Server with 9 schedule query tools
Implement complete MCP server for parsing Primavera P6 XER files and exposing schedule data through MCP tools. All 4 user stories complete. Tools implemented: - load_xer: Parse XER files into SQLite database - list_activities: Query activities with pagination and filtering - get_activity: Get activity details by ID - list_relationships: Query activity dependencies - get_predecessors/get_successors: Query activity relationships - get_project_summary: Project overview with counts - list_milestones: Query milestone activities - get_critical_path: Query driving path activities Features: - Tab-delimited XER format parsing with pluggable table handlers - In-memory SQLite database for fast queries - Pagination with 100-item default limit - Multi-project file support with project selection - ISO8601 date formatting - NO_FILE_LOADED error handling for all query tools Test coverage: 81 tests (contract, integration, unit)
This commit is contained in:
77
src/xer_mcp/db/schema.py
Normal file
77
src/xer_mcp/db/schema.py
Normal file
@@ -0,0 +1,77 @@
|
||||
"""SQLite database schema for XER MCP Server."""
|
||||
|
||||
SCHEMA_SQL = """
|
||||
-- Projects
|
||||
CREATE TABLE IF NOT EXISTS projects (
|
||||
proj_id TEXT PRIMARY KEY,
|
||||
proj_short_name TEXT NOT NULL,
|
||||
plan_start_date TEXT,
|
||||
plan_end_date TEXT,
|
||||
loaded_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
-- Activities
|
||||
CREATE TABLE IF NOT EXISTS activities (
|
||||
task_id TEXT PRIMARY KEY,
|
||||
proj_id TEXT NOT NULL,
|
||||
wbs_id TEXT,
|
||||
task_code TEXT NOT NULL,
|
||||
task_name TEXT NOT NULL,
|
||||
task_type TEXT NOT NULL,
|
||||
target_start_date TEXT,
|
||||
target_end_date TEXT,
|
||||
act_start_date TEXT,
|
||||
act_end_date TEXT,
|
||||
total_float_hr_cnt REAL,
|
||||
driving_path_flag INTEGER DEFAULT 0,
|
||||
status_code TEXT,
|
||||
FOREIGN KEY (proj_id) REFERENCES projects(proj_id)
|
||||
);
|
||||
|
||||
-- Relationships
|
||||
CREATE TABLE IF NOT EXISTS relationships (
|
||||
task_pred_id TEXT PRIMARY KEY,
|
||||
task_id TEXT NOT NULL,
|
||||
pred_task_id TEXT NOT NULL,
|
||||
pred_type TEXT NOT NULL,
|
||||
lag_hr_cnt REAL DEFAULT 0,
|
||||
FOREIGN KEY (task_id) REFERENCES activities(task_id),
|
||||
FOREIGN KEY (pred_task_id) REFERENCES activities(task_id)
|
||||
);
|
||||
|
||||
-- WBS (Work Breakdown Structure)
|
||||
CREATE TABLE IF NOT EXISTS wbs (
|
||||
wbs_id TEXT PRIMARY KEY,
|
||||
proj_id TEXT NOT NULL,
|
||||
parent_wbs_id TEXT,
|
||||
wbs_short_name TEXT NOT NULL,
|
||||
wbs_name TEXT,
|
||||
FOREIGN KEY (proj_id) REFERENCES projects(proj_id),
|
||||
FOREIGN KEY (parent_wbs_id) REFERENCES wbs(wbs_id)
|
||||
);
|
||||
|
||||
-- Calendars (internal use only)
|
||||
CREATE TABLE IF NOT EXISTS calendars (
|
||||
clndr_id TEXT PRIMARY KEY,
|
||||
clndr_name TEXT NOT NULL,
|
||||
day_hr_cnt REAL,
|
||||
week_hr_cnt REAL
|
||||
);
|
||||
|
||||
-- Indexes for performance
|
||||
CREATE INDEX IF NOT EXISTS idx_activities_proj ON activities(proj_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_activities_wbs ON activities(wbs_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_activities_type ON activities(task_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_activities_critical ON activities(driving_path_flag)
|
||||
WHERE driving_path_flag = 1;
|
||||
CREATE INDEX IF NOT EXISTS idx_activities_dates ON activities(target_start_date, target_end_date);
|
||||
CREATE INDEX IF NOT EXISTS idx_relationships_task ON relationships(task_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_relationships_pred ON relationships(pred_task_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_wbs_parent ON wbs(parent_wbs_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_wbs_proj ON wbs(proj_id);
|
||||
"""
|
||||
|
||||
|
||||
def get_schema() -> str:
|
||||
"""Return the complete SQLite schema."""
|
||||
return SCHEMA_SQL
|
||||
Reference in New Issue
Block a user