feat(11-02): add findByNumber and getNextNumber to PhaseRepository
- Add findByNumber method to lookup phase by initiative and number - Add getNextNumber method to get next available phase number - Implement both methods in DrizzlePhaseRepository adapter - Use drizzle-orm max() and and() for query construction
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
* Implements PhaseRepository interface using Drizzle ORM.
|
* Implements PhaseRepository interface using Drizzle ORM.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { eq, asc } from 'drizzle-orm';
|
import { eq, asc, and, max } from 'drizzle-orm';
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
import type { DrizzleDatabase } from '../../index.js';
|
import type { DrizzleDatabase } from '../../index.js';
|
||||||
import { phases, type Phase } from '../../schema.js';
|
import { phases, type Phase } from '../../schema.js';
|
||||||
@@ -58,6 +58,26 @@ export class DrizzlePhaseRepository implements PhaseRepository {
|
|||||||
.orderBy(asc(phases.number));
|
.orderBy(asc(phases.number));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async findByNumber(initiativeId: string, number: number): Promise<Phase | null> {
|
||||||
|
const result = await this.db
|
||||||
|
.select()
|
||||||
|
.from(phases)
|
||||||
|
.where(and(eq(phases.initiativeId, initiativeId), eq(phases.number, number)))
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
return result[0] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getNextNumber(initiativeId: string): Promise<number> {
|
||||||
|
const result = await this.db
|
||||||
|
.select({ maxNumber: max(phases.number) })
|
||||||
|
.from(phases)
|
||||||
|
.where(eq(phases.initiativeId, initiativeId));
|
||||||
|
|
||||||
|
const maxNumber = result[0]?.maxNumber ?? 0;
|
||||||
|
return maxNumber + 1;
|
||||||
|
}
|
||||||
|
|
||||||
async update(id: string, data: UpdatePhaseData): Promise<Phase> {
|
async update(id: string, data: UpdatePhaseData): Promise<Phase> {
|
||||||
const existing = await this.findById(id);
|
const existing = await this.findById(id);
|
||||||
if (!existing) {
|
if (!existing) {
|
||||||
|
|||||||
@@ -46,6 +46,18 @@ export interface PhaseRepository {
|
|||||||
*/
|
*/
|
||||||
findByInitiativeId(initiativeId: string): Promise<Phase[]>;
|
findByInitiativeId(initiativeId: string): Promise<Phase[]>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a phase by initiative and number.
|
||||||
|
* Returns null if not found.
|
||||||
|
*/
|
||||||
|
findByNumber(initiativeId: string, number: number): Promise<Phase | null>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next available phase number for an initiative.
|
||||||
|
* Returns MAX(number) + 1, or 1 if no phases exist.
|
||||||
|
*/
|
||||||
|
getNextNumber(initiativeId: string): Promise<number>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a phase.
|
* Update a phase.
|
||||||
* Throws if phase not found.
|
* Throws if phase not found.
|
||||||
|
|||||||
Reference in New Issue
Block a user