{
"meta": {
"agent": "planner",
"task_id": "355",
"title": "MT-11: Add owner column to entities + scope all DB queries",
"created_at": "2026-04-08T22:10:00Z"
},
"inputs": [
{
"name": "GitHub Issue #355",
"type": "context",
"ref": "https://github.com/AgentSDE/agent-core/issues/355",
"notes": "Multi-tenant data isolation — add owner column and scope queries"
},
{
"name": "AGENTS.md",
"type": "context",
"ref": "AGENTS.md",
"notes": "Codebase conventions and testing patterns"
}
],
"outputs": [
{
"name": "plan.md",
"type": "plan",
"format": "md",
"content": "Implementation plan for owner column + scoped queries"
}
],
"files": [
{
"path": "src/database/entities/task.entity.ts",
"action": "modify",
"reason": "Add owner column, update unique constraint"
},
{
"path": "src/database/entities/job.entity.ts",
"action": "modify",
"reason": "Add owner column"
},
{
"path": "src/database/entities/webhook-delivery.entity.ts",
"action": "modify",
"reason": "Add owner column"
},
{
"path": "src/task-state/task-state.service.ts",
"action": "modify",
"reason": "Inject TenantConfigService, scope all find/create by owner"
},
{
"path": "src/task-state/task-state.module.ts",
"action": "modify",
"reason": "Import TenantModule"
},
{
"path": "src/queue/sqlite-job-queue.ts",
"action": "modify",
"reason": "Inject TenantConfigService, scope job creation and polling by owner"
},
{
"path": "src/queue/queue.module.ts",
"action": "modify",
"reason": "Import TenantModule"
},
{
"path": "src/webhook/webhook.controller.ts",
"action": "modify",
"reason": "Set owner on delivery creation"
},
{
"path": "src/webhook/webhook.module.ts",
"action": "modify",
"reason": "Import TenantModule"
},
{
"path": "src/task-state/task-state.service.spec.ts",
"action": "modify",
"reason": "Add owner to fixtures, mock TenantConfigService"
},
{
"path": "src/queue/sqlite-job-queue.spec.ts",
"action": "modify",
"reason": "Add owner to fixtures, mock TenantConfigService"
}
],
"steps": [
{
"id": "S1",
"summary": "Add owner column to TaskEntity, JobEntity, and WebhookDeliveryEntity with default 'AgentSDE'. Update TaskEntity unique constraint to ['owner', 'issue', 'repo'].",
"acceptance": [
"All three entities have @Column({ default: 'AgentSDE' }) owner: string",
"TaskEntity unique constraint is ['owner', 'issue', 'repo']",
"tsc --noEmit passes"
],
"depends_on": []
},
{
"id": "S2",
"summary": "Scope TaskStateService — inject TenantConfigService, add owner to all find/create queries. Import TenantModule in task-state.module.ts.",
"acceptance": [
"findByIssueAndRepo includes owner in where clause",
"findByStatus/findByStatuses/findAll include owner filter",
"createTask sets owner from TenantConfigService.getConfig().org",
"TenantModule imported in TaskStateModule"
],
"depends_on": [
"S1"
]
},
{
"id": "S3",
"summary": "Scope SqliteJobQueue — inject TenantConfigService, add owner to enqueue, processNext (including subquery), and onModuleInit. Import TenantModule in queue.module.ts.",
"acceptance": [
"enqueue() sets owner on created job",
"processNext() QueryBuilder filters by owner in both outer and inner query",
"onModuleInit() stale-job recovery filters by owner",
"TenantModule imported in QueueModule"
],
"depends_on": [
"S1"
]
},
{
"id": "S4",
"summary": "Scope WebhookController — inject TenantConfigService, set owner on WebhookDeliveryEntity creation. Import TenantModule in webhook.module.ts.",
"acceptance": [
"deliveryRepo.create() includes owner from TenantConfigService",
"TenantModule imported in WebhookModule"
],
"depends_on": [
"S1"
]
},
{
"id": "S5",
"summary": "Update unit tests — add owner to entity fixtures, mock TenantConfigService, verify scoped queries.",
"acceptance": [
"npm run test passes",
"npm run lint passes",
"Tests verify owner is included in queries"
],
"depends_on": [
"S2",
"S3",
"S4"
]
}
],
"risks": [
{
"risk": "Dependency on #348 (TenantModule) — TenantConfigService must exist",
"mitigation": "Target rc/multi-tenant branch; #348 merges first"
},
{
"risk": "processNext() subquery cross-tenant leakage",
"mitigation": "Scope both outer WHERE and inner NOT IN subquery by owner"
}
],
"assumptions": [
"TenantConfigService from #348 exposes getConfig().org returning the tenant owner string",
"TenantModule exports TenantConfigService and can be imported by other modules",
"SQLite synchronize:true handles adding the new column with default value to existing rows"
],
"open_questions": []
}