Merge pull request #80 from R0m1k3/1.1

1.1
This commit is contained in:
LogiFlow authored and GitHub committed 2025-08-13 13:30:23 +02:00
commit 64890003f5
7 files changed
+250 -1011

No files matched your search

@@ -0,0 +1,140 @@
🔗 Database initialization: {
NODE_ENV: 'production',
isProduction: true,
hasDbUrl: true,
dbHost: 'logiflow-db'
}
🐳 PRODUCTION: Using standard PostgreSQL
✅ PostgreSQL connection test successful
🐳 PRODUCTION: Using PostgreSQL storage
🐳 PRODUCTION: Local auth configured with PostgreSQL sessions
🐳 PRODUCTION: Starting LogiFlow application
🐳 Environment: { NODE_ENV: 'production', DATABASE_URL: 'Present', PORT: '3000' }
🔍 Using development storage and authentication
🔧 Using memory session store for development
Warning: connect.session() MemoryStore is not
designed for a production environment, as it will leak
memory, and will not scale past a single process.
🐳 Serving static files from: /app/dist/public
🐳 PRODUCTION: LogiFlow serving on port 3000
✅ Production admin user found: { id: 'admin_local', username: 'admin', passwordFormat: 'present' }
✅ Admin user exists, preserving current password
HEAD /api/health 200 in 5ms
📄 SPA: Serving index.html for /bl-reconciliation
🔍 PRODUCTION /api/user - req.user: {
id: 'admin_local',
role: 'admin',
hasUserGroups: true,
userGroupsLength: 0,
userGroups: []
}
GET /api/user 304 in 10ms
🔍 PRODUCTION /api/user - req.user: {
id: 'admin_local',
role: 'admin',
hasUserGroups: true,
userGroupsLength: 0,
userGroups: []
}
GET /api/user 304 in 9ms
GET /api/suppliers 304 in 19ms
🔍 PRODUCTION /api/user - req.user: {
id: 'admin_local',
role: 'admin',
hasUserGroups: true,
userGroupsLength: 0,
userGroups: []
}
GET /api/user 304 in 20ms
🔍 PRODUCTION /api/user - req.user: {
id: 'admin_local',
role: 'admin',
hasUserGroups: true,
userGroupsLength: 0,
userGroups: []
}
GET /api/user 304 in 8ms
Deliveries API called with: {
startDate: undefined,
endDate: undefined,
storeId: undefined,
withBL: undefined,
userRole: 'admin'
}
Admin filtering deliveries with groupIds: undefined
Fetching all deliveries
Deliveries returned: 81 items
GET /api/deliveries 304 in 50ms
GET /api/groups 304 in 36ms
HEAD /api/health 200 in 1ms
Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 KiB

+8 -3
View File
@@ -142,9 +142,9 @@ export default function BLReconciliation() {
supplier: delivery.supplier
});
if (!delivery.group?.nocodbTableName && !delivery.group?.nocodbConfigId) {
if (!delivery.group?.nocodbTableName && !delivery.group?.nocodbConfigId && !delivery.group?.webhookUrl) {
toast({
title: "Vérification non disponible",
title: "Vérification non disponible",
description: "Ce magasin n'a pas de configuration NocoDB",
variant: "destructive",
});
@@ -178,6 +178,11 @@ export default function BLReconciliation() {
}
const deliveries = await response.json();
// Debug : examiner les données des groupes en production
console.log('🔍 DEBUG Production - Première livraison:', deliveries[0]);
console.log('🔍 DEBUG Production - Groupe de la première livraison:', deliveries[0]?.group);
console.log('🔍 DEBUG Production - Champs disponibles dans group:', deliveries[0]?.group ? Object.keys(deliveries[0].group) : 'Pas de groupe');
const filtered = Array.isArray(deliveries) ? deliveries.filter((d: any) => d.status === 'delivered') : [];
return filtered.sort((a: any, b: any) => new Date(b.deliveredDate || b.updatedAt).getTime() - new Date(a.deliveredDate || a.updatedAt).getTime());
@@ -641,7 +646,7 @@ export default function BLReconciliation() {
</div>
{/* Icône de vérification de facture */}
{(delivery.group?.nocodbTableName || delivery.group?.nocodbConfigId) && (
{(delivery.group?.nocodbTableName || delivery.group?.nocodbConfigId || delivery.group?.webhookUrl) && (
<div className="flex items-center">
{verifyingDeliveries.has(delivery.id) ? (
<Clock className="h-4 w-4 text-blue-500 animate-spin" title="Vérification en cours..." />
+21 -1008
View File
File diff suppressed because it is too large. Load diff
+32
View File
@@ -10,6 +10,8 @@ import {
customerOrders,
dlcProducts,
tasks,
nocodbConfig,
invoiceVerificationCache,
type User,
type UpsertUser,
type Group,
@@ -42,6 +44,10 @@ import {
type DlcProductWithRelations,
type Task,
type InsertTask,
type NocodbConfig,
type InsertNocodbConfig,
type InvoiceVerificationCache,
type InsertInvoiceVerificationCache,
} from "@shared/schema";
import { db } from "./db";
import { eq, and, inArray, desc, sql, gte, lte } from "drizzle-orm";
@@ -120,10 +126,16 @@ export interface IStorage {
// NocoDB Configuration operations
getNocodbConfigs(): Promise<NocodbConfig[]>;
getNocodbConfig(id: number): Promise<NocodbConfig | undefined>;
getActiveNocodbConfig(): Promise<NocodbConfig | undefined>;
createNocodbConfig(config: InsertNocodbConfig): Promise<NocodbConfig>;
updateNocodbConfig(id: number, config: Partial<InsertNocodbConfig>): Promise<NocodbConfig>;
deleteNocodbConfig(id: number): Promise<void>;
// Invoice Verification Cache operations
getInvoiceVerificationCache(cacheKey: string): Promise<InvoiceVerificationCache | undefined>;
createInvoiceVerificationCache(cache: InsertInvoiceVerificationCache): Promise<InvoiceVerificationCache>;
clearExpiredCache(): Promise<void>;
// Customer Order operations
getCustomerOrders(groupIds?: number[]): Promise<CustomerOrderWithRelations[]>;
getCustomerOrder(id: number): Promise<CustomerOrderWithRelations | undefined>;
@@ -1104,6 +1116,26 @@ export class DatabaseStorage implements IStorage {
await db.delete(nocodbConfig).where(eq(nocodbConfig.id, id));
}
async getActiveNocodbConfig(): Promise<NocodbConfig | undefined> {
const [config] = await db.select().from(nocodbConfig).where(eq(nocodbConfig.isActive, true));
return config;
}
// Invoice Verification Cache operations
async getInvoiceVerificationCache(cacheKey: string): Promise<InvoiceVerificationCache | undefined> {
const [cache] = await db.select().from(invoiceVerificationCache).where(eq(invoiceVerificationCache.cacheKey, cacheKey));
return cache;
}
async createInvoiceVerificationCache(cache: InsertInvoiceVerificationCache): Promise<InvoiceVerificationCache> {
const [newCache] = await db.insert(invoiceVerificationCache).values(cache).returning();
return newCache;
}
async clearExpiredCache(): Promise<void> {
await db.delete(invoiceVerificationCache).where(sql`${invoiceVerificationCache.expiresAt} < NOW()`);
}
// Customer Order operations
async getCustomerOrders(groupIds?: number[]): Promise<CustomerOrderWithRelations[]> {
try {
+49
View File
@@ -141,6 +141,37 @@ export const publicityParticipations = pgTable("publicity_participations", {
pk: primaryKey({ columns: [table.publicityId, table.groupId] })
}));
// Configuration NocoDB globale pour la vérification des factures
export const nocodbConfig = pgTable("nocodb_config", {
id: serial("id").primaryKey(),
name: varchar("name").notNull(),
baseUrl: varchar("base_url").notNull(),
projectId: varchar("project_id").notNull(),
apiToken: varchar("api_token").notNull(),
description: text("description"),
isActive: boolean("is_active").default(true),
createdBy: varchar("created_by"),
createdAt: timestamp("created_at").defaultNow(),
updatedAt: timestamp("updated_at").defaultNow(),
});
// Cache de vérification des factures
export const invoiceVerificationCache = pgTable("invoice_verification_cache", {
id: serial("id").primaryKey(),
cacheKey: varchar("cache_key", { length: 255 }).notNull(),
groupId: integer("group_id").notNull(),
invoiceReference: varchar("invoice_reference", { length: 255 }).notNull(),
supplierName: varchar("supplier_name", { length: 255 }),
exists: boolean("exists").notNull(),
matchType: varchar("match_type", { length: 50 }).notNull(),
errorMessage: text("error_message"),
cacheHit: boolean("cache_hit").default(false),
apiCallTime: integer("api_call_time"),
expiresAt: timestamp("expires_at").notNull(),
createdAt: timestamp("created_at").defaultNow(),
updatedAt: timestamp("updated_at").defaultNow(),
});
@@ -472,6 +503,21 @@ export const insertTaskSchema = createInsertSchema(tasks).omit({
dueDate: z.coerce.date().optional().nullable(), // Convertit automatiquement les chaînes en Date
});
export const insertNocodbConfigSchema = createInsertSchema(nocodbConfig).omit({
id: true,
createdAt: true,
updatedAt: true,
});
export const insertInvoiceVerificationCacheSchema = createInsertSchema(invoiceVerificationCache).omit({
id: true,
createdAt: true,
updatedAt: true,
});
export type InsertNocodbConfig = z.infer<typeof insertNocodbConfigSchema>;
export type InsertInvoiceVerificationCache = z.infer<typeof insertInvoiceVerificationCacheSchema>;
// Types
export type User = typeof users.$inferSelect;
export type UpsertUser = z.infer<typeof insertUserSchema>;
@@ -586,6 +632,9 @@ export type PublicityWithRelations = Publicity & {
export type NocodbConfig = typeof nocodbConfig.$inferSelect;
export type InsertNocodbConfig = z.infer<typeof insertNocodbConfigSchema>;
export type InvoiceVerificationCache = typeof invoiceVerificationCache.$inferSelect;
export type InsertInvoiceVerificationCache = z.infer<typeof insertInvoiceVerificationCacheSchema>;
export type CustomerOrder = typeof customerOrders.$inferSelect;
export type InsertCustomerOrder = z.infer<typeof insertCustomerOrderSchema>;