Employee Project Tracking

L3
ModelContextProtocolPostgresEmployees

Build project tracking system from scratch with tables for projects, assignments, milestones, and performance indexes.

Created by Lingxiao Du
2025-08-14
Schema DesignData MigrationData Integrity Enforcement

Model Ranking

Click on the dots to view the trajectory of each task run
Model
Run Results
Pass@4
Pass^4
Avg Time
Avg Turns
Input Tokens
Output Tokens
Total Tokens
DeepSeek
deepseek-chat
4
/4
287.8s
29.3
165,346
3,267
168,613
OpenAI
gpt-5-high
4
/4
639.2s
14.3
101,447
21,211
122,658
OpenAI
gpt-5-low
4
/4
182.1s
13.8
64,124
10,857
74,981
OpenAI
gpt-5-medium
4
/4
249.0s
14.3
93,772
11,092
104,864
OpenAI
gpt-5-mini-high
4
/4
137.6s
13.0
102,898
15,312
118,210
OpenAI
gpt-5-mini-medium
4
/4
90.4s
12.0
97,835
8,871
106,706
Grok
grok-4
4
/4
135.9s
19.0
150,783
4,639
155,422
Grok
grok-code-fast-1
4
/4
50.8s
29.0
238,789
3,837
242,625
OpenAI
o3
4
/4
101.8s
14.5
62,718
6,420
69,138
Qwen
qwen-3-coder-plus
4
/4
81.9s
31.3
272,726
3,090
275,816
Claude
claude-sonnet-4
3
/4
166.7s
28.8
209,723
5,064
214,787
Claude
claude-sonnet-4-high
3
/4
164.2s
29.3
299,977
4,861
304,838
Claude
claude-sonnet-4-low
3
/4
163.6s
27.0
262,882
4,637
267,519
MoonshotAI
kimi-k2-0905
2
/4
1390.0s
28.5
218,250
2,501
220,751
MoonshotAI
kimi-k2-0711
1
/4
192.9s
31.5
179,989
3,210
183,198
Claude
claude-opus-4-1
0
/1
--
450.6s
30.0
213,055
7,961
221,016
Gemini
gemini-2-5-flash
0
/4
44.4s
8.0
29,075
7,080
36,155
Gemini
gemini-2-5-pro
0
/4
76.2s
9.8
50,662
6,523
57,185
Z.ai
glm-4-5
0
/4
147.7s
33.3
178,162
4,476
182,637
OpenAI
gpt-4-1
0
/4
85.5s
45.8
246,566
1,614
248,180
OpenAI
gpt-4-1-mini
0
/4
53.8s
22.3
88,930
1,805
90,735
OpenAI
gpt-4-1-nano
0
/4
26.4s
15.3
44,269
939
45,208
OpenAI
gpt-5-mini-low
0
/4
71.3s
8.0
29,092
7,098
36,190
OpenAI
gpt-5-nano-high
0
/4
274.9s
15.5
88,712
55,376
144,088
OpenAI
gpt-5-nano-low
0
/4
115.2s
8.8
40,846
24,409
65,255
OpenAI
gpt-5-nano-medium
0
/4
250.0s
13.0
96,998
38,293
135,291
OpenAI
gpt-oss-120b
0
/4
10.6s
4.5
14,843
442
15,284
OpenAI
o4-mini
0
/4
74.5s
4.5
14,390
5,738
20,127
Qwen
qwen-3-max
0
/4
86.3s
32.5
215,267
2,240
217,507

Task State

Enum "employees"."employee_gender" { "M" "F" } Table "employees"."department" { "id" bpchar(4) [pk, not null] "dept_name" varchar(40) [unique, not null] } Table "employees"."department_employee" { "employee_id" int8 [not null] "department_id" bpchar(4) [not null] "from_date" date [not null] "to_date" date [not null] Indexes { (employee_id, department_id) [type: btree, name: "idx_16982_primary"] department_id [type: btree, name: "idx_16982_dept_no"] } } Table "employees"."department_manager" { "employee_id" int8 [not null] "department_id" bpchar(4) [not null] "from_date" date [not null] "to_date" date [not null] Indexes { (employee_id, department_id) [type: btree, name: "idx_16985_primary"] department_id [type: btree, name: "idx_16985_dept_no"] } } Table "employees"."employee" { "id" int8 [pk, not null, increment] "birth_date" date [not null] "first_name" varchar(14) [not null] "last_name" varchar(16) [not null] "gender" employees.employee_gender [not null] "hire_date" date [not null] } Table "employees"."salary" { "employee_id" int8 [not null] "amount" int8 [not null] "from_date" date [not null] "to_date" date [not null] Indexes { (employee_id, from_date) [type: btree, name: "idx_16991_primary"] } } Table "employees"."title" { "employee_id" int8 [not null] "title" varchar(50) [not null] "from_date" date [not null] "to_date" date Indexes { (employee_id, title, from_date) [type: btree, name: "idx_16994_primary"] } } Ref "dept_emp_ibfk_1":"employees"."employee"."id" < "employees"."department_employee"."employee_id" [update: restrict, delete: cascade] Ref "dept_emp_ibfk_2":"employees"."department"."id" < "employees"."department_employee"."department_id" [update: restrict, delete: cascade] Ref "dept_manager_ibfk_1":"employees"."employee"."id" < "employees"."department_manager"."employee_id" [update: restrict, delete: cascade] Ref "dept_manager_ibfk_2":"employees"."department"."id" < "employees"."department_manager"."department_id" [update: restrict, delete: cascade] Ref "salaries_ibfk_1":"employees"."employee"."id" < "employees"."salary"."employee_id" [update: restrict, delete: cascade] Ref "titles_ibfk_1":"employees"."employee"."id" < "employees"."title"."employee_id" [update: restrict, delete: cascade]

Instruction

Create and manage a comprehensive employee project tracking system using database schema design and data manipulation operations. The IT team needs you to build the database structure from scratch and populate it with specific initial data to support project management workflows.

Your Tasks:

  1. Create the project tracking tables — build three new tables in the employees schema:

    Table 1: employee_projects

    • project_id (integer, primary key, auto-increment)
    • project_name (varchar(100), not null)
    • start_date (date, not null)
    • end_date (date)
    • budget (decimal(10,2))
    • status (varchar(20), default 'active')

    Table 2: project_assignments

    • assignment_id (integer, primary key, auto-increment)
    • employee_id (bigint, not null)
    • project_id (integer, not null)
    • role (varchar(50), not null)
    • allocation_percentage (integer, check constraint: between 1 and 100)
    • assigned_date (date, not null)

    Table 3: project_milestones

    • milestone_id (integer, primary key, auto-increment)
    • project_id (integer, not null)
    • milestone_name (varchar(100), not null)
    • due_date (date, not null)
    • completed (boolean, default false)
  2. Add foreign key relationships:

    • project_assignments.employee_idemployees.employee.id
    • project_assignments.project_idemployees.employee_projects.project_id
    • project_milestones.project_idemployees.employee_projects.project_id
  3. Create performance indexes:

    • Index named idx_projects_status on employee_projects.status
    • Composite index named idx_assignments_emp_proj on project_assignments(employee_id, project_id)
    • Index named idx_milestones_due_date on project_milestones.due_date
  4. Insert exactly this initial data:

    Into employee_projects:

    • Project 1: name='Database Modernization', start_date='2024-01-15', end_date='2024-06-30', budget=250000.00, status='active'
    • Project 2: name='Employee Portal Upgrade', start_date='2024-02-01', end_date='2024-05-15', budget=180000.00, status='active'
    • Project 3: name='HR Analytics Dashboard', start_date='2023-11-01', end_date='2024-01-31', budget=120000.00, status='active'

    Into project_assignments (assign ALL current employees):

    • All employees from Development department → Project 1 ('Database Modernization'), role='Developer', allocation=80%
    • All employees from Human Resources department → Project 2 ('Employee Portal Upgrade'), role='Business Analyst', allocation=60%
    • All employees from Marketing department → Project 3 ('HR Analytics Dashboard'), role='Marketing Specialist', allocation=40%
    • All employees from Finance department → Project 1 ('Database Modernization'), role='Financial Analyst', allocation=30%
    • All employees from Sales department → Project 2 ('Employee Portal Upgrade'), role='Sales Representative', allocation=50%
    • All employees from Research department → Project 3 ('HR Analytics Dashboard'), role='Research Analyst', allocation=70%
    • All employees from Production department → Project 1 ('Database Modernization'), role='Production Coordinator', allocation=45%
    • All employees from Quality Management department → Project 2 ('Employee Portal Upgrade'), role='QA Specialist', allocation=85%
    • All employees from Customer Service department → Project 3 ('HR Analytics Dashboard'), role='Customer Success', allocation=35%
    • All employees should have assigned_date='2024-01-01'

    Into project_milestones:

    • Project 1: 'Design Phase Complete' due '2024-03-01', 'Implementation Complete' due '2024-05-15'
    • Project 2: 'UI/UX Approval' due '2024-03-15', 'Beta Testing' due '2024-04-30'
    • Project 3: 'Data Collection' due '2023-12-15', 'Dashboard Launch' due '2024-01-25'
  5. Perform these exact data updates:

    • Update Project 3 ('HR Analytics Dashboard') status to 'completed'
    • Increase budget by 15% for all projects with status 'active'
    • Mark the milestone 'Data Collection' as completed (set completed = true)
  6. Add new column to employee_projects:

    • Add priority column (varchar(10)) with check constraint allowing only 'low', 'medium', 'high'
    • Update all existing projects: set priority='high' for 'Database Modernization', priority='medium' for others


Verify

*.py
Python
"""
Verification script for PostgreSQL Task 5: Database Schema and Data Operations
"""

import os
import sys
import psycopg2
from decimal import Decimal

def rows_match(actual_row, expected_row):
    """
    Compare two rows with appropriate tolerance.
    For Decimal types: allows 0.1 tolerance
    For date types: convert to string for comparison
    For other types: requires exact match
    """
    if len(actual_row) != len(expected_row):
        return False
    
    for actual, expected in zip(actual_row, expected_row):
        if isinstance(actual, Decimal) and isinstance(expected, (Decimal, float, int)):
            if abs(float(actual) - float(expected)) > 0.1:
                return False
        elif hasattr(actual, 'strftime'):  # datetime.date or datetime.datetime
            if str(actual) != str(expected):
                return False
        elif actual != expected:
            return False
    
    return True

def get_connection_params() -> dict:
    """Get database connection parameters."""
    return {
        "host": os.getenv("POSTGRES_HOST", "localhost"),
        "port": int(os.getenv("POSTGRES_PORT", 5432)),
        "database": os.getenv("POSTGRES_DATABASE"),
        "user": os.getenv("POSTGRES_USERNAME"),
        "password": os.getenv("POSTGRES_PASSWORD")
    }

def verify_table_structures(conn) -> bool:
    """Verify that all three tables were created with correct structure."""
    with conn.cursor() as cur:
        # Check if tables exist
        cur.execute("""
            SELECT table_name FROM information_schema.tables 
            WHERE table_schema = 'employees' 
            AND table_name IN ('employee_projects', 'project_assignments', 'project_milestones')
            ORDER BY table_name
        """)
        tables = [row[0] for row in cur.fetchall()]
        
        if len(tables) != 3:
            print(f"❌ Expected 3 tables, found {len(tables)}: {tables}")
            return False
            
        # Check foreign key constraints exist
        cur.execute("""
            SELECT COUNT(*) FROM information_schema.table_constraints 
            WHERE table_schema = 'employees' 
            AND constraint_type = 'FOREIGN KEY'
            AND table_name IN ('project_assignments', 'project_milestones')
        """)
        fkey_count = cur.fetchone()[0]
        
        if fkey_count != 3:
            print(f"❌ Expected 3 foreign key constraints, found {fkey_count}")
            return False
            
        # Check if priority column exists (added in step 6)
        cur.execute("""
            SELECT COUNT(*) FROM information_schema.columns 
            WHERE table_schema = 'employees' AND table_name = 'employee_projects'
            AND column_name = 'priority'
        """)
        priority_exists = cur.fetchone()[0]
        
        if priority_exists == 0:
            print("❌ Priority column was not added to employee_projects table")
            return False
            
        print("✅ Table structures are correct")
        return True

def verify_indexes(conn) -> bool:
    """Verify that required indexes were created."""
    with conn.cursor() as cur:
        # Check for specific indexes
        cur.execute("""
            SELECT COUNT(*) 
            FROM pg_indexes 
            WHERE schemaname = 'employees' 
            AND indexname IN ('idx_projects_status', 'idx_assignments_emp_proj', 'idx_milestones_due_date')
        """)
        index_count = cur.fetchone()[0]
        
        if index_count != 3:
            print(f"❌ Expected 3 required indexes, got {index_count}")
            return False
                
        print("✅ All required indexes are present")
        return True

def verify_project_data(conn) -> bool:
    """Verify that project data was inserted and updated correctly."""
    with conn.cursor() as cur:
        # Check project data after updates
        cur.execute("""
            SELECT project_name, start_date, end_date, budget, status, priority
            FROM employees.employee_projects
            ORDER BY project_name
        """)
        projects = cur.fetchall()
        
        if len(projects) != 3:
            print(f"❌ Expected 3 projects, found {len(projects)}")
            return False
            
        # Expected final state after all updates
        expected = {
            'Database Modernization': ('2024-01-15', '2024-06-30', 287500.00, 'active', 'high'),
            'Employee Portal Upgrade': ('2024-02-01', '2024-05-15', 207000.00, 'active', 'medium'),
            'HR Analytics Dashboard': ('2023-11-01', '2024-01-31', 120000.00, 'completed', 'medium')
        }
        
        for project in projects:
            name = project[0]
            if name not in expected:
                print(f"❌ Unexpected project: {name}")
                return False
                
            exp = expected[name]
            # Use rows_match for comparison
            expected_row = (name,) + exp
            if not rows_match(project, expected_row):
                print(f"❌ Project {name} data mismatch: expected {expected_row}, got {project}")
                return False
                
        print("✅ Project data is correct")
        return True

def verify_assignment_data(conn) -> bool:
    """Verify that all current employees were assigned to projects by department."""
    with conn.cursor() as cur:
        # Check total assignment count matches current employee count
        cur.execute("""
            SELECT COUNT(*) FROM employees.project_assignments
        """)
        assignment_count = cur.fetchone()[0]
        
        cur.execute("""
            SELECT COUNT(DISTINCT de.employee_id) 
            FROM employees.department_employee de
            WHERE de.to_date = '9999-01-01'
        """)
        current_employee_count = cur.fetchone()[0]
        
        if assignment_count != current_employee_count:
            print(f"❌ Expected {current_employee_count} assignments, found {assignment_count}")
            return False
            
        # Check department-project mapping
        cur.execute("""
            SELECT d.dept_name, pa.project_id, pa.role, pa.allocation_percentage, COUNT(*)
            FROM employees.project_assignments pa
            JOIN employees.department_employee de ON pa.employee_id = de.employee_id AND de.to_date = '9999-01-01'
            JOIN employees.department d ON de.department_id = d.id
            JOIN employees.employee_projects ep ON pa.project_id = ep.project_id
            GROUP BY d.dept_name, pa.project_id, pa.role, pa.allocation_percentage
            ORDER BY d.dept_name
        """)
        dept_assignments = cur.fetchall()
        
        # Expected department-project mappings
        expected_mappings = {
            'Development': (1, 'Developer', 80),
            'Human Resources': (2, 'Business Analyst', 60),
            'Marketing': (3, 'Marketing Specialist', 40),
            'Finance': (1, 'Financial Analyst', 30),
            'Sales': (2, 'Sales Representative', 50),
            'Research': (3, 'Research Analyst', 70),
            'Production': (1, 'Production Coordinator', 45),
            'Quality Management': (2, 'QA Specialist', 85),
            'Customer Service': (3, 'Customer Success', 35)
        }
        
        dept_found = {}
        for assignment in dept_assignments:
            dept_name, project_id, role, allocation, _ = assignment  # Ignore count
            if dept_name in dept_found:
                print(f"❌ Department {dept_name} has multiple assignments")
                return False
            dept_found[dept_name] = (project_id, role, allocation)
            
        for dept, expected in expected_mappings.items():
            if dept not in dept_found:
                print(f"❌ Department {dept} has no assignments")
                return False
            if dept_found[dept] != expected:
                print(f"❌ Department {dept} assignment mismatch: expected {expected}, got {dept_found[dept]}")
                return False
                
        # Check that all assignments have correct assigned_date
        cur.execute("""
            SELECT COUNT(*) FROM employees.project_assignments 
            WHERE assigned_date != '2024-01-01'
        """)
        wrong_date_count = cur.fetchone()[0]
        
        if wrong_date_count > 0:
            print(f"❌ {wrong_date_count} assignments have incorrect assigned_date")
            return False
                
        print("✅ Assignment data is correct")
        return True

def verify_milestone_data(conn) -> bool:
    """Verify that milestone data was inserted and updated correctly."""
    with conn.cursor() as cur:
        cur.execute("""
            SELECT project_id, milestone_name, due_date, completed
            FROM employees.project_milestones
            ORDER BY project_id, milestone_name
        """)
        milestones = cur.fetchall()
        
        if len(milestones) != 6:
            print(f"❌ Expected 6 milestones, found {len(milestones)}")
            return False
            
        # Expected milestones
        expected_milestones = {
            (1, 'Design Phase Complete'): ('2024-03-01', False),
            (1, 'Implementation Complete'): ('2024-05-15', False),
            (2, 'UI/UX Approval'): ('2024-03-15', False),
            (2, 'Beta Testing'): ('2024-04-30', False),
            (3, 'Data Collection'): ('2023-12-15', True),  # Should be completed
            (3, 'Dashboard Launch'): ('2024-01-25', False)
        }
        
        for milestone in milestones:
            project_id, name, due_date, completed = milestone
            key = (project_id, name)
            
            if key not in expected_milestones:
                print(f"❌ Unexpected milestone: {key}")
                return False
                
            expected_due, expected_completed = expected_milestones[key]
            if str(due_date) != expected_due or completed != expected_completed:
                print(f"❌ Milestone {name} mismatch: expected ({expected_due}, {expected_completed}), got ({due_date}, {completed})")
                return False
                
        print("✅ Milestone data is correct")
        return True

def main():
    """Main verification function."""
    print("=" * 50)

    # Get connection parameters
    conn_params = get_connection_params()

    if not conn_params["database"]:
        print("❌ No database specified")
        sys.exit(1)

    try:
        # Connect to database
        conn = psycopg2.connect(**conn_params)

        # Verify all components
        success = (
            verify_table_structures(conn) and 
            verify_indexes(conn) and
            verify_project_data(conn) and
            verify_assignment_data(conn) and
            verify_milestone_data(conn)
        )

        conn.close()

        if success:
            print("\n🎉 Task verification: PASS")
            sys.exit(0)
        else:
            print("\n❌ Task verification: FAIL")
            sys.exit(1)

    except psycopg2.Error as e:
        print(f"❌ Database error: {e}")
        sys.exit(1)
    except Exception as e:
        print(f"❌ Verification error: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()