73 lines
2.1 KiB
TypeScript
73 lines
2.1 KiB
TypeScript
import type pg from 'pg';
|
|
import type { PosStoreRepository } from '../domain/ports.js';
|
|
import type { PosStore, ListStoresOptions } from '../domain/store.js';
|
|
|
|
interface StoreRow {
|
|
id: string;
|
|
name: string;
|
|
slug: string;
|
|
address: string | null;
|
|
tax_id: string | null;
|
|
contact_email: string | null;
|
|
contact_phone: string | null;
|
|
receipt_header: string | null;
|
|
receipt_footer: string | null;
|
|
settings: Record<string, unknown>;
|
|
active: boolean;
|
|
created_at: Date;
|
|
updated_at: Date;
|
|
}
|
|
|
|
function toStore(row: StoreRow): PosStore {
|
|
return {
|
|
id: row.id,
|
|
name: row.name,
|
|
slug: row.slug,
|
|
address: row.address,
|
|
taxId: row.tax_id,
|
|
contactEmail: row.contact_email,
|
|
contactPhone: row.contact_phone,
|
|
receiptHeader: row.receipt_header,
|
|
receiptFooter: row.receipt_footer,
|
|
settings: row.settings,
|
|
active: row.active,
|
|
createdAt: row.created_at,
|
|
updatedAt: row.updated_at,
|
|
};
|
|
}
|
|
|
|
export class PgStoreRepository implements PosStoreRepository {
|
|
constructor(private readonly pool: pg.Pool) {}
|
|
|
|
async findById(id: string): Promise<PosStore | undefined> {
|
|
const result = await this.pool.query<StoreRow>(
|
|
'SELECT * FROM pos_stores WHERE id = $1',
|
|
[id],
|
|
);
|
|
return result.rows[0] ? toStore(result.rows[0]) : undefined;
|
|
}
|
|
|
|
async list(options: ListStoresOptions = {}): Promise<{ stores: PosStore[]; total: number }> {
|
|
const { active = true, limit = 50, offset = 0 } = options;
|
|
const where = active !== undefined ? 'WHERE active = $1' : '';
|
|
const countParams: number[] = active !== undefined ? [active ? 1 : 0] : [];
|
|
const listParams: number[] = [...countParams, limit, offset];
|
|
|
|
const [countResult, listResult] = await Promise.all([
|
|
this.pool.query<{ count: string }>(
|
|
`SELECT COUNT(*) as count FROM pos_stores ${where}`,
|
|
countParams,
|
|
),
|
|
this.pool.query<StoreRow>(
|
|
`SELECT * FROM pos_stores ${where} ORDER BY name LIMIT $${listParams.length - 1} OFFSET $${listParams.length}`,
|
|
listParams,
|
|
),
|
|
]);
|
|
|
|
return {
|
|
stores: listResult.rows.map(toStore),
|
|
total: parseInt(countResult.rows[0]?.count ?? '0', 10),
|
|
};
|
|
}
|
|
}
|