feat(F-190): completed feature

This commit is contained in:
chattie
2026-08-23 07:48:20 +02:00
parent 6b93e91ef4
commit eb3322e309
22 changed files with 287 additions and 67 deletions

View File

@@ -173,7 +173,7 @@ describe('GET /reporting/summary (REPORTING_SALES)', () => {
expect(body.dataAvailability.grossSales).toBe('available');
expect(body.dataAvailability.netSales).toBe('unavailable');
expect(body.dataAvailability.margin).toBe('unavailable');
expect(body.dataAvailability.paymentMethod).toBe('unavailable');
expect(body.dataAvailability.paymentMethod).toBe('available'); // F-190
expect(body.dataAvailability.shipping).toBe('available');
expect(body.dataAvailability.discounts).toBe('available');
});

View File

@@ -1,5 +1,7 @@
/**
* F-146 — ReportingService: summary and sales endpoints.
* F-190 — dataAvailability flags corrected: refunds and paymentMethod
* are now available via reporting_payment_lines.
*
* Uses the CTE `filtered_orders` pattern from REPORTING_ARCHITECTURE.md §7.
* All SQL is fully parameterized — no user input in the query string.
@@ -78,8 +80,8 @@ export interface SummaryResponse {
orders: 'available';
customers: 'available';
margin: 'unavailable';
paymentMethod: 'unavailable';
refunds: 'unavailable';
paymentMethod: 'available'; // F-190: reporting_payment_lines has provider data
refunds: 'available'; // F-190: reporting_payment_lines has refund rows
shipping: 'available';
};
totals: Metrics;
@@ -106,8 +108,8 @@ export interface SalesResponse {
orders: 'available';
customers: 'available';
margin: 'unavailable';
paymentMethod: 'unavailable';
refunds: 'unavailable';
paymentMethod: 'available'; // F-190: reporting_payment_lines has provider data
refunds: 'available'; // F-190: reporting_payment_lines has refund rows
shipping: 'available';
};
items: SalesRow[];
@@ -198,8 +200,8 @@ export class ReportingService {
* - unitsSold: available (SUM quantity)
* - orders/customers: available
* - margin: unavailable (cost_at_sale not populated)
* - paymentMethod: unavailable (needs JOIN with reporting_payment_lines)
* - refunds: unavailable (needs state filter)
* - paymentMethod: available (F-190: reporting_payment_lines has provider per payment)
* - refunds: available (F-190: reporting_payment_lines has refund rows)
* - shipping: available (orders_orders.shipping_cents from F-144)
*/
async summary(filters: ReportingFilters): Promise<SummaryResponse> {
@@ -231,8 +233,8 @@ export class ReportingService {
orders: 'available',
customers: 'available',
margin: 'unavailable',
paymentMethod: 'unavailable',
refunds: 'unavailable',
paymentMethod: 'available', // F-190
refunds: 'available', // F-190
shipping: 'available',
},
totals: current,
@@ -277,8 +279,8 @@ export class ReportingService {
orders: 'available',
customers: 'available',
margin: 'unavailable',
paymentMethod: 'unavailable',
refunds: 'unavailable',
paymentMethod: 'available', // F-190
refunds: 'available', // F-190
shipping: 'available',
},
items: rows,
@@ -520,8 +522,8 @@ export class ReportingService {
orders: 'available',
customers: 'available',
margin: 'unavailable',
paymentMethod: 'unavailable',
refunds: 'unavailable',
paymentMethod: 'available', // F-190
refunds: 'available', // F-190
shipping: 'available',
},
items: rows,

View File

@@ -68,8 +68,8 @@ describe('ReportingService', () => {
orders: 'available',
customers: 'available',
margin: 'unavailable',
paymentMethod: 'unavailable',
refunds: 'unavailable',
paymentMethod: 'available', // F-190
refunds: 'available', // F-190
shipping: 'available',
},
totals: {
@@ -144,8 +144,8 @@ describe('ReportingService', () => {
const svc = new ReportingService(pool);
const result = await svc.summary(makeFilters());
expect(result.dataAvailability.margin).toBe('unavailable');
expect(result.dataAvailability.paymentMethod).toBe('unavailable');
expect(result.dataAvailability.refunds).toBe('unavailable');
expect(result.dataAvailability.paymentMethod).toBe('available'); // F-190
expect(result.dataAvailability.refunds).toBe('available'); // F-190
expect(result.dataAvailability.netSales).toBe('unavailable');
expect(result.dataAvailability.grossSales).toBe('available');
expect(result.dataAvailability.shipping).toBe('available');