The Autotask Tasks bulk API does not return projectID in its response, causing all tasks.project_id to be NULL. This fixes it by: - Adding project_phases as a synced entity (Autotask endpoint: /Phases) - Migration 059: project_phases table with project_id, phase_number, estimated_hours, start/due dates, parent_phase_id, is_scheduled - EntityType.PROJECT_PHASES added to all sync maps and dependency graph (depends on PROJECTS, runs before TASKS in sync order) - buildProjectPhasesFilter: Phases endpoint requires a filter (id > 0) - mapProjectPhase: maps Autotask field names to DB columns - Post-sync backfill in syncEntity: after each project_phases sync, UPDATE tasks SET project_id = pp.project_id FROM project_phases pp JOIN projects p WHERE tasks.phase_id = pp.id Only backfills where the project exists in our DB (FK constraint on tasks.project_id; archived projects are skipped gracefully) Result: 2,455 of 4,966 tasks now have project_id populated. Tasks belonging to archived/completed projects have phase_id resolvable via project_phases even when project_id remains NULL. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
30 lines
1.5 KiB
SQL
30 lines
1.5 KiB
SQL
-- Migration 059: Create project_phases table
|
|
-- Project phases are groupings of tasks within an Autotask project.
|
|
-- Tasks reference phases via phase_id. Syncing phases allows us to resolve
|
|
-- tasks back to their parent project (tasks.phase_id → project_phases.id → project_phases.project_id).
|
|
-- Autotask endpoint: /Phases
|
|
|
|
CREATE TABLE IF NOT EXISTS project_phases (
|
|
id BIGINT PRIMARY KEY,
|
|
project_id BIGINT, -- no FK: phases may reference completed/archived projects not in our DB
|
|
parent_phase_id BIGINT,
|
|
title CHARACTER VARYING,
|
|
description TEXT,
|
|
phase_number CHARACTER VARYING,
|
|
estimated_hours NUMERIC,
|
|
start_date_time TIMESTAMP WITHOUT TIME ZONE,
|
|
due_date TIMESTAMP WITHOUT TIME ZONE,
|
|
create_date_time TIMESTAMP WITHOUT TIME ZONE,
|
|
last_activity_date_time TIMESTAMP WITHOUT TIME ZONE,
|
|
creator_resource_id BIGINT,
|
|
is_scheduled BOOLEAN DEFAULT FALSE,
|
|
external_id CHARACTER VARYING,
|
|
synced_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
is_deleted BOOLEAN DEFAULT FALSE,
|
|
deleted_at TIMESTAMP WITH TIME ZONE
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_project_phases_project_id ON project_phases (project_id);
|
|
CREATE INDEX IF NOT EXISTS idx_project_phases_is_deleted ON project_phases (is_deleted) WHERE is_deleted = FALSE;
|