PROBLEM: - Agents completing with questions were incorrectly marked as "crashed" - Race condition: polling handler AND crash handler both called handleCompletion() - Caused database corruption and lost pending questions SOLUTION: - Add completion mutex in OutputHandler to prevent concurrent processing - Remove duplicate completion call from crash handler - Only one handler executes completion logic per agent TESTING: - Added mutex-completion.test.ts with 4 test cases - Verified mutex prevents concurrent access - Verified lock cleanup on exceptions - Verified different agents can process concurrently FIXES: residential-cuckoo and 12+ other agents stuck in crashed state
36 lines
1.3 KiB
TypeScript
36 lines
1.3 KiB
TypeScript
/**
|
|
* Proposal Repository Port Interface
|
|
*
|
|
* Port for Proposal aggregate operations.
|
|
* Implementations (Drizzle, etc.) are adapters.
|
|
*/
|
|
|
|
import type { Proposal, NewProposal } from '../schema.js';
|
|
|
|
/**
|
|
* Data for creating a new proposal.
|
|
* Omits system-managed fields (id, createdAt, updatedAt).
|
|
*/
|
|
export type CreateProposalData = Omit<NewProposal, 'id' | 'createdAt' | 'updatedAt'>;
|
|
|
|
/**
|
|
* Data for updating a proposal.
|
|
*/
|
|
export type UpdateProposalData = Partial<Pick<NewProposal, 'status'>>;
|
|
|
|
/**
|
|
* Proposal Repository Port
|
|
*/
|
|
export interface ProposalRepository {
|
|
create(data: CreateProposalData): Promise<Proposal>;
|
|
createMany(data: CreateProposalData[]): Promise<Proposal[]>;
|
|
findById(id: string): Promise<Proposal | null>;
|
|
findByAgentId(agentId: string): Promise<Proposal[]>;
|
|
findByInitiativeId(initiativeId: string): Promise<Proposal[]>;
|
|
findByAgentIdAndStatus(agentId: string, status: string): Promise<Proposal[]>;
|
|
update(id: string, data: UpdateProposalData): Promise<Proposal>;
|
|
updateManyByAgentId(agentId: string, data: UpdateProposalData): Promise<void>;
|
|
updateManyByAgentIdAndStatus(agentId: string, currentStatus: string, data: UpdateProposalData): Promise<void>;
|
|
countByAgentIdAndStatus(agentId: string, status: string): Promise<number>;
|
|
}
|