Commit Graph
1619 Commits
Author SHA1 Message Date
Claude af3800aa09 chore: remove committed session cookies, debug artifacts and dead code
Repo hygiene pass:
- cookie.txt / cookies.txt held real session cookies and must never be
  committed; .gitignore now blocks them along with .env files
- half a megabyte of debug screenshots, one-shot production hotfix scripts
  (all superseded by the automatic startup migrations), scratch files and
  the unused attached_assets folder (with its dangling @assets vite alias)
- dead code: server/storage-old.ts (unreferenced, 167 of the project's 430
  TypeScript errors) and five client pages no route ever imported
  (BLReconciliationNative, Avoirs_backup, TasksSimplified, TasksListSimple,
  TasksProductionSimple)

TypeScript error count drops from 430 to 261 with no behavior change; the
client build is unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHdE9nEh8zHhQNGpCgrtYe
2026-08-14 16:14:45 +00:00
Claude 9de717387f feat(securite): encrypt SMTP passwords and NocoDB tokens at rest, log supplier mails
Encryption (server/crypto.ts):
- AES-256-GCM with a key derived from ENCRYPTION_KEY, falling back to
  SESSION_SECRET so existing deployments need no new configuration
- stored format enc:v1:<iv>:<tag>:<data>; encryption is idempotent and
  decryption passes legacy plaintext through unchanged, so nothing breaks
  mid-migration
- tampered data or a changed key raises an explicit error instead of
  returning garbage
- encrypt/decrypt is confined to the storage layer: group writes encrypt
  smtpPassword (decrypted only in emailService at connection time, never sent
  to the client), NocoDB config writes encrypt apiToken and reads decrypt it
  so the invoice verification and the admin page behave as before
- startup migration sweep encrypts secrets already stored in plaintext,
  idempotently; the active-config log line no longer prints the token

Mail history (supplier_mail_logs):
- every send attempt is recorded: delivery, store, supplier, recipient,
  subject, status sent/failed with error, message id, user id and name;
  a logging failure never fails the send itself
- GET /api/supplier-mail-logs restricted to the user's stores (admin may
  filter by store)
- on the reconciliation page the mail icon turns green once a request has
  been sent, with the date and sender in the tooltip; clicking again resends
- table created in init.sql, versioned migrations and the production
  startup migration, with delivery/group indexes

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHdE9nEh8zHhQNGpCgrtYe
2026-08-14 16:02:55 +00:00
Claude 012024a293 feat(mails): send supplier document requests over each store's own SMTP
Replaces the mailto: link with a server-side send, so the message carries the
store's signature and logo instead of depending on each workstation's Outlook.

Store record (groups):
- address, phone and logo (data URI, 200 KB cap) feed the mail signature
- per-store SMTP settings: host, port, SSL/STARTTLS, credentials, sender
  address and display name, with an enable switch
- "test connection" button verifies the server without sending anything
- the empty-form literal, previously repeated five times, becomes one constant

Sending:
- nodemailer transport built per store from its own settings
- multipart mail: plain-text alternative plus HTML whose signature embeds the
  logo as an inline CID attachment, which Outlook renders without the remote
  image blocking that a data: URI would hit
- delivery details are HTML-escaped
- Reply-To set to the store address; the row shows a spinner and refuses a
  second click while a send is in flight

Credentials:
- the SMTP password is never returned to the client; a response-layer
  sanitizer strips it from every /api payload and replaces it with a
  smtpPasswordSet flag, covering the ten-plus queries that join full group
  rows into deliveries, orders and user relations
- an empty password field on save keeps the stored one rather than clearing it

Verified end-to-end against a local SMTP server: transport, auth, From/Reply-To,
multipart structure and the inline logo attachment.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHdE9nEh8zHhQNGpCgrtYe
2026-08-14 15:25:00 +00:00
Claude 02645c34a5 refactor(rapprochement): end supplier mail body at the closing line
The generated body stopped with the brand name and the store, which would be
repeated by the Outlook signature configured on each workstation. It now ends
at "Cordialement," and lets that signature carry the brand, the store details
and the logo.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHdE9nEh8zHhQNGpCgrtYe
2026-08-14 14:29:06 +00:00
Claude 02b70d6b59 fix(rapprochement): stop the auto-verification request flood
The reconciliation page saturated the browser with concurrent requests
(net::ERR_INSUFFICIENT_RESOURCES), re-verifying the same deliveries dozens
of times. Three compounding causes:

- the auto-verification effect depended on verificationResults and
  verifyingDeliveries, so every incoming result re-ran it and re-scheduled
  the same deliveries; the effect now depends only on the data, and
  de-duplication uses a ref applied synchronously instead of state
- verifications fired all at once; they now go through a queue capped at 3
  concurrent requests, which also drops the random 0-1s scatter and the
  200ms stagger of "verify all"
- each auto-filled delivery invalidated the deliveries cache, triggering a
  refetch that re-ran the effect; invalidation now happens once, when the
  queue drains

Also fixes cached results computed after the setState that was supposed to
apply them, so deliveries with a known invoice amount never got their green
check and were re-examined on every pass, and silences toasts for automatic
verifications (one toast per row on a network outage).

Mail signature is now the LaFoir'Fouille brand plus the store recorded on
the delivery, instead of the current user's name.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHdE9nEh8zHhQNGpCgrtYe
2026-08-14 12:04:35 +00:00
Claude ee4fca64d0 feat(rapprochement): add supplier mail button to request invoice PDF or BL Excel
Each reconciliation row now shows a mail icon that opens the default mail
client (Outlook) with the supplier address, subject and body pre-filled,
asking for the invoice as PDF or the delivery note as Excel.

- new client/src/lib/supplierMail.ts helper building the subject, body and
  mailto URL from the delivery (supplier, store, delivery date, BL number,
  BL amount, invoice reference) with the current user as signature
- body line breaks encoded as CRLF per RFC 6068 so Outlook keeps the layout
- supplier email read from the delivery join, with fallback to the suppliers
  list; when no email is set the button explains where to add it
- button added to both the manual and validated tabs

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHdE9nEh8zHhQNGpCgrtYe
2026-08-14 11:47:49 +00:00
MichaelandClaude Fable 5 753b301066 perf: add missing indexes and remove N+1 queries
The app degraded progressively over a year of data growth. Four causes,
all cumulative:

1. No indexes. Apart from primary keys, unique constraints and
   session.expire, no table carried an index. PostgreSQL does not index
   foreign keys automatically, so every filter and join on group_id,
   supplier_id, order_id and the date columns did a sequential scan.
   Worst offender: user_groups.user_id, read by getUserWithGroups() on
   every authenticated request.

2. N+1 in the order and delivery listings. getOrders,
   getOrdersByDateRange, getDeliveries and getDeliveriesByDateRange
   issued one to two queries per row to load relations. Relations are now
   loaded in bulk and grouped in Node: three queries regardless of volume.

3. /api/sync-order-delivery-status reloaded the whole deliveries table on
   every iteration of its loop over orders. It now uses the deliveries
   getOrders() already attaches.

4. clearExpiredCache() was implemented but never called, so
   invoice_verification_cache grew without bound. Now scheduled every 6h.

Also replaces the full-history downloads on the Groups and Suppliers
pages, which fetched every order and delivery with nested relations only
to count rows, with aggregate endpoints that count in the database.

Indexes are created via scripts/auto-migrate-production.sh, the script
that actually runs at deploy time, using CREATE INDEX CONCURRENTLY so no
write lock is taken. Note that server/migrations.ts explicitly ignores
the migrations/ directory and runs only hardcoded migrations; the SQL
file added there is for reference and manual application.

Verified: typecheck baseline 440 errors, 430 after, none new in the
changed code; vite build passes; server boots; functional test confirms
the aggregate endpoints match the source data including the delivered
count.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 11:55:49 +02:00
MichaelandClaude Sonnet 4.6 693d9460cb feat(contacts): add company field to free contacts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 11:29:56 +02:00
MichaelandClaude Sonnet 4.6 a430aa1910 feat(contacts): allow admin/directeur to edit supplier coordinates from contacts page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 11:27:33 +02:00
MichaelandClaude Sonnet 4.6 b8ecacee3b merge(main): resolve conflicts keeping codefou + email on suppliers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 11:14:35 +02:00
MichaelandClaude Sonnet 4.6 805664dc32 feat(contacts): add contacts page with per-store management and supplier email field
- New contacts table (group_id, name, role, phone, email, notes) per store
- Suppliers table: add email field with form and card display
- Page /contacts: two-column layout (suppliers read-only / free contacts CRUD)
- Permissions: read all roles, create/edit/delete admin + directeur + manager
- Admin can filter contacts by store; other roles see their own stores only
- Migration SQL: 20260515_add_contacts_and_supplier_email.sql

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 10:44:39 +02:00
Michael 3cdd76e223 feat: add BAP webhook configuration and testing routes to server API 2026-04-29 12:11:16 +02:00
Michael 79cd5d4f61 feat: implement date normalization utility and add BAP webhook configuration management routes 2026-04-29 12:02:21 +02:00
Michael 0255dc4aba feat: add BAP file upload functionality to sidebar with processing status modal 2026-04-02 14:58:17 +02:00
Michael 71625031df feat: add WebhookBAPConfig page for managing and testing n8n webhook settings 2026-04-02 14:52:51 +02:00
Michael 8aa5dd1c83 feat: add mobile-optimized customer orders page with creation form and article lookup integration 2026-04-02 14:25:08 +02:00
Michael 7e2eed93df feat: add CustomerOrderForm component with automated product lookup and validation 2026-04-02 14:01:31 +02:00
Michael 95a5a2facc feat: add CustomerOrderForm component with automated product lookup and supplier matching 2026-04-02 13:54:29 +02:00
Michael 22897ede48 feat: add CustomerOrderForm component with automated product lookup and supplier matching 2026-04-02 13:37:16 +02:00
Michael cf57cb5b2d feat: add CustomerOrders page with CRUD operations, status management, and client contact tracking 2026-04-02 12:58:56 +02:00
Michael 55191c511b feat: implement BAP webhook configuration management and customer order tracking support 2026-04-02 12:52:20 +02:00
Michael 576db2d7f4 feat: implement customer order form with automated product lookup and mobile-responsive order page 2026-04-02 11:50:46 +02:00
Michael 6df51a3934 feat: add CustomerOrderForm component with automated article lookup and supplier matching 2026-04-02 11:40:50 +02:00
Michael 58dde2f785 feat: implement CustomerOrderForm component with automated product lookup and create mobile-responsive customer orders page 2026-04-02 11:36:02 +02:00
Michael a91027c10b feat: implement DLC tracking page with EAN lookup and CRUD operations for product expiration management 2026-04-02 09:46:59 +02:00
Michael 44950d2239 feat: implement supplier management module with CRUD operations and optimistic updates 2026-04-02 09:38:30 +02:00
Michael 1488accbdb feat: implement mobile-optimized DLC management page with EAN lookup and status-based filtering 2026-04-02 09:28:46 +02:00
Michael 475c52cede feat: implement dashboard page with store-specific stats, announcement modals, and DLC alerts 2026-04-02 09:25:09 +02:00
Michael b090c8f36a feat: implement DLC management page with EAN lookup, filtering, and CRUD operations 2026-04-02 09:20:54 +02:00
Michael fcf8518684 feat: implement RouterProduction component to handle environment-aware desktop and mobile routing 2026-04-02 09:00:00 +02:00
Michael 4318bb3b5c feat: implement production router with mobile/desktop support and add sidebar navigation component 2026-04-02 08:54:39 +02:00
LogiFlow ea8aed7e01 Merge pull request #560 from R0m1k3/1.1
1.1
2026-02-10 09:44:46 +01:00
Michael 40cf456a64 fix(backup): resolve real admin user ID instead of hardcoded 'system' for automatic backups
Fixes FK violation: database_backups.created_by -> users.id
The 'system' user does not exist in the users table, causing
INSERT failures every hour for scheduled backups.
2026-02-10 09:41:12 +01:00
Michael cb1a1a933c fix(dlc): filter stockEpuise products from DLC stats and invalidate stats cache 2026-02-10 09:37:02 +01:00
LogiFlow 14ba6272c2 Merge pull request #559 from R0m1k3/1.1
fix(db): increase connection pool size and timeout to handle concurre…
2026-01-13 16:55:09 +01:00
Michael 16ef17957d fix(db): increase connection pool size and timeout to handle concurrent verifications 2026-01-13 16:54:26 +01:00
LogiFlow 7adb3f7767 Merge pull request #558 from R0m1k3/1.1
fix(server): resolve duplicate fetch declaration in invoice proxy
2026-01-13 16:45:09 +01:00
Michael 03cb562866 fix(server): resolve duplicate fetch declaration in invoice proxy 2026-01-13 16:44:46 +01:00
LogiFlow 7b02acf6c1 Merge pull request #557 from R0m1k3/1.1
chore(server): add logging for webhook url in invoice proxy
2026-01-13 16:43:01 +01:00
Michael 443093573a chore(server): add logging for webhook url in invoice proxy 2026-01-13 16:41:47 +01:00
LogiFlow ac89171b9e Merge pull request #556 from R0m1k3/1.1
fix(server): use createRequire for form-data to resolve dynamic impor…
2026-01-13 16:37:16 +01:00
Michael 65eb74a96e fix(server): use createRequire for form-data to resolve dynamic import issues 2026-01-13 16:36:46 +01:00
LogiFlow 31f5c575d6 Merge pull request #555 from R0m1k3/1.1
fix(server): fix form-data dynamic import for webhook invoice sending
2026-01-13 16:27:55 +01:00
Michael 9c0ba9559d fix(server): fix form-data dynamic import for webhook invoice sending 2026-01-13 16:27:35 +01:00
LogiFlow 4b3bcf70eb Merge pull request #554 from R0m1k3/1.1
chore(deps): npm audit fix - reduce vulnerabilities
2026-01-12 14:37:09 +01:00
Michael f39b8240e7 chore(deps): npm audit fix - reduce vulnerabilities 2026-01-12 14:36:25 +01:00
LogiFlow 0ec8c029fe Merge pull request #553 from R0m1k3/1.1
feat(security): ameliorations securite - CSRF, sanitization validator…
2026-01-12 14:30:31 +01:00
Michael 0f8920f326 feat(security): ameliorations securite - CSRF, sanitization validator.js, eval removal 2026-01-12 14:29:02 +01:00
LogiFlow 5d07344051 Merge pull request #552 from R0m1k3/1.1
1.1
2026-01-12 14:13:59 +01:00
Michael 78adc2c5ae feat(BAP): remplacer destinataire Celia par Jeremy 2026-01-12 14:13:21 +01:00