feat: accounting integration (D27), SMS relay driver (D26), rebuild user apps
- Add Tahesab/Zarrin accounting sync module with admin panel UI - Add SMS relay driver as default provider, refactor SMS into driver pattern - Update customer services, orders, products, and catalog queries - Rebuild user-app and user-app-v2 dist assets - Add Prisma migration for accounting tables - Update docker-compose and env examples - Update parity docs (DECISIONS, ISSUES, PROGRESS) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
a72fa607a5
commit
19d490e790
@@ -1,6 +1,7 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { PrismaService } from '../../prisma/prisma.service';
|
||||
import { AccountingSyncService } from '../accounting-sync/accounting-sync.service';
|
||||
|
||||
// passwordHash must never leave the API — every customer read goes through this.
|
||||
const PUBLIC_CUSTOMER_SELECT = {
|
||||
@@ -35,7 +36,10 @@ const PUBLIC_CUSTOMER_SELECT = {
|
||||
*/
|
||||
@Injectable()
|
||||
export class CustomersService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
constructor(
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly accounting: AccountingSyncService,
|
||||
) {}
|
||||
|
||||
async getOrThrow(customerId: string) {
|
||||
const customer = await this.prisma.customer.findUnique({
|
||||
@@ -43,7 +47,21 @@ export class CustomersService {
|
||||
select: PUBLIC_CUSTOMER_SELECT,
|
||||
});
|
||||
if (!customer) throw new NotFoundException(`Customer ${customerId} not found`);
|
||||
return customer;
|
||||
|
||||
// D27 — with the accounting integration on, the customer sees the balance
|
||||
// the accounting software holds. The apps only display these two fields;
|
||||
// the credit-limit check runs server-side on the internal ledger, untouched.
|
||||
const accounting = await this.accounting.customerBalance(customerId);
|
||||
if (accounting) {
|
||||
return {
|
||||
...customer,
|
||||
goldDebtGrams: accounting.gold,
|
||||
fiatDebtRial: accounting.rial,
|
||||
balanceSource: 'accounting' as const,
|
||||
balanceAt: accounting.at,
|
||||
};
|
||||
}
|
||||
return { ...customer, balanceSource: 'app' as const, balanceAt: null };
|
||||
}
|
||||
|
||||
getOrders(customerId: string) {
|
||||
|
||||
Reference in New Issue
Block a user