ci: docker_tag=ext | fix(api-url): normalise les slashs + retire Hotjar + message login
All checks were successful
build-and-push-ext / build_push (push) Successful in 1m41s

This commit is contained in:
Debian Dev4 2025-09-18 07:49:32 +00:00
parent 2c1a33330c
commit 0f0a035967
8 changed files with 86 additions and 42 deletions

View File

@ -39,8 +39,6 @@ NEXT_PUBLIC_DOCAPOSTE_API_URL=
NEXT_PUBLIC_API_URL=https://dev4.4nkweb.com/api
NEXT_PUBLIC_DEFAULT_VALIDATOR_ID=28c9a3a8151bef545ebf700ca5222c63d0031ad593097e95c1de202464304a99
NEXT_PUBLIC_DEFAULT_STORAGE_URLS=https://dev4.4nkweb.com/storage
NEXT_PUBLIC_HOTJAR_SITE_ID=0
NEXT_PUBLIC_HOTJAR_VERSION=
SIGNER_BASE_URL=https://dev3.4nkweb.com/signer/
# WS

44
docs/analyse.md Normal file
View File

@ -0,0 +1,44 @@
### Objet
Analyse synthétique de `lecoffre-front` (Next.js) : périmètre, dépendances, configuration, intégrations et points dattention.
### Périmètre et stack
- **Framework**: Next.js 14 (React 18), rendu côté serveur désactivable selon pages
- **Langage**: TypeScript
- **Styles**: SCSS + MUI (@mui/material), Emotion
- **Bundle**: `output: 'standalone'`, `basePath: '/lecoffre'`
### Arborescence notable
- **`src/front/`**: API client (services, entités, SDK) et composants UI (DesignSystem, Layouts, Elements)
- **`pages/`**: routes Next (tableau client, gestion utilisateurs, dossiers, documents, souscriptions)
- **`src/common/Api/LeCoffreApi`**: modules Admin/Customer/Notary/SuperAdmin et `sdk`
- **`src/front/Stores/`**: stores locaux (User, Customer, Window, Toasts)
- **`src/front/Services/`**: services utilitaires (JWT, PDF, Watermark, Crypto, Cookie)
### Configuration et variables
- **`next.config.js`**: publie `NEXT_PUBLIC_*` aux clients et serveur; `reactStrictMode: false`; `ignoreBuildErrors: true`
- **BasePath**: `/lecoffre` (impacte le routage et les assets)
- **Intégrations**: Hotjar, GTM, Docaposte, 4NK (iframe/URL), Idnot (OAuth)
### Dépendances clés
- **UI**: `@mui/material`, `@emotion/*`, `react-select`, `react-toastify`
- **Utilitaires**: `jwt-decode`, `file-saver`, `jszip`, `pdf-lib`, `sass`, `sharp`
- **Ressources**: `le-coffre-resources` (dépôt Git 4NK)
### Intégrations externes (indiciaires)
- **Back**: via `NEXT_PUBLIC_BACK_API_*` et `NEXT_PUBLIC_API_URL`
- **Idnot**: endpoints OAuth (authorize, base_url, redirect_uri)
- **Docaposte**: `NEXT_PUBLIC_DOCAPOSTE_API_URL`
### Points dattention
- **TypeScript**: `ignoreBuildErrors: true` masque des erreurs de typage
- **BasePath**: vérifier la cohérence côté Nginx et lors du déploiement
- **Ressources Git**: accès SSH requis pour `le-coffre-resources`
- **Sécurité**: exposition de multiples `NEXT_PUBLIC_*` (vérifier quaucun secret nest divulgué)
### Tests et qualité
- **Scripts**: `build` sans lint, `lint` séparé, `format` ciblé `src/`
- **`tests/`**: présent (à enrichir avec scénarios e2e/smoke sur pages principales)
### Déploiement
- **Dockerfile**: présent (build Next standalone)
- **Intégration**: orchestré via `lecoffre_node` (voir analyse dédiée)

View File

@ -21,8 +21,6 @@ const nextConfig = {
NEXT_PUBLIC_IDNOT_BASE_URL: process.env.NEXT_PUBLIC_IDNOT_BASE_URL,
NEXT_PUBLIC_IDNOT_REDIRECT_URI: process.env.NEXT_PUBLIC_IDNOT_REDIRECT_URI,
NEXT_PUBLIC_DOCAPOSTE_API_URL: process.env.NEXT_PUBLIC_DOCAPOSTE_API_URL,
NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID,
NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION,
NEXT_PUBLIC_4NK_URL: process.env.NEXT_PUBLIC_4NK_URL,
NEXT_PUBLIC_4NK_IFRAME_URL: process.env.NEXT_PUBLIC_4NK_IFRAME_URL,
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
@ -43,8 +41,6 @@ const nextConfig = {
NEXT_PUBLIC_IDNOT_BASE_URL: process.env.NEXT_PUBLIC_IDNOT_BASE_URL,
NEXT_PUBLIC_IDNOT_REDIRECT_URI: process.env.NEXT_PUBLIC_IDNOT_REDIRECT_URI,
NEXT_PUBLIC_DOCAPOSTE_API_URL: process.env.NEXT_PUBLIC_DOCAPOSTE_API_URL,
NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID,
NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION,
NEXT_PUBLIC_4NK_URL: process.env.NEXT_PUBLIC_4NK_URL,
NEXT_PUBLIC_4NK_IFRAME_URL: process.env.NEXT_PUBLIC_4NK_IFRAME_URL,
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
@ -65,8 +61,6 @@ const nextConfig = {
NEXT_PUBLIC_IDNOT_BASE_URL: process.env.NEXT_PUBLIC_IDNOT_BASE_URL,
NEXT_PUBLIC_IDNOT_REDIRECT_URI: process.env.NEXT_PUBLIC_IDNOT_REDIRECT_URI,
NEXT_PUBLIC_DOCAPOSTE_API_URL: process.env.NEXT_PUBLIC_DOCAPOSTE_API_URL,
NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID,
NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION,
NEXT_PUBLIC_4NK_URL: process.env.NEXT_PUBLIC_4NK_URL,
NEXT_PUBLIC_4NK_IFRAME_URL: process.env.NEXT_PUBLIC_4NK_IFRAME_URL,
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,

View File

@ -37,7 +37,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-gtm-module": "^2.0.11",
"react-hotjar": "^6.3.1",
"react-select": "^5.7.2",
"react-toastify": "^9.1.3",
"sass": "^1.59.2",

View File

@ -16,13 +16,15 @@ export default abstract class BaseApiService {
protected readonly variables = FrontendVariables.getInstance();
protected constructor() {
BaseApiService.baseUrl ??=
this.variables.BACK_API_PROTOCOL +
this.variables.BACK_API_HOST +
':' +
this.variables.BACK_API_PORT +
this.variables.BACK_API_ROOT_URL +
this.variables.BACK_API_VERSION;
if (!BaseApiService.baseUrl) {
const protocol = (this.variables.BACK_API_PROTOCOL || '').replace(/:\/\/$/, '');
const host = (this.variables.BACK_API_HOST || '').replace(/\/$/, '');
const port = this.variables.BACK_API_PORT ? `:${this.variables.BACK_API_PORT.replace(/^:/, '')}` : '';
const root = `/${(this.variables.BACK_API_ROOT_URL || '')}`.replace(/\/+/g, '/').replace(/\/$/, '');
const version = `/${(this.variables.BACK_API_VERSION || '')}`.replace(/\/+/g, '/');
BaseApiService.baseUrl = `${protocol}://${host}${port}${root}${version}`;
}
}
protected getBaseUrl(): string {

View File

@ -117,12 +117,11 @@ export default function StepEmail(props: IProps) {
showCancelButton={false}
onAccept={closeErrorModal}
closeBtn
header={"Abonnement Manquant"}
header={"Problème de connexion"}
confirmText={"Fermer"}>
<div className={classes["modal-content"]}>
<Typography typo={ETypo.TEXT_MD_LIGHT} className={classes["text"]}>
Vous ne disposez pas d'un abonnement actif. Veuillez demander au référent de votre étude de souscrire à un
abonnement pour activer cette fonctionnalité. Pour toute question, contactez-nous à support@lecoffre.io.
Une erreur est survenue lors de la connexion. Veuillez réessayer ou contacter le support si le problème persiste.
</Typography>
<a className={classes["modal-button"]} href="mailto:support@lecoffre.io" target="_blank">
<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.COLOR_SECONDARY_500} className={classes["button-text"]}>

View File

@ -6,7 +6,6 @@ import type { AppType, AppProps } from "next/app";
import { useEffect, useState, type ReactElement, type ReactNode } from "react";
import getConfig from "next/config";
import { GoogleTagManager } from "@next/third-parties/google";
import { hotjar } from "react-hotjar";
import Loader from "src/common/Api/LeCoffreApi/sdk/Loader";
@ -35,8 +34,6 @@ type AppPropsWithLayout = AppProps & {
fcAuthorizeEndpoint: string;
fcClientId: string;
docaposteApiUrl: string;
hotjarSiteId: number;
hotjarVersion: number;
_4nkUrl: string;
_4nkIframeUrl?: string;
apiUrl: string;
@ -59,8 +56,6 @@ const MyApp = (({
fcAuthorizeEndpoint,
fcClientId,
docaposteApiUrl,
hotjarSiteId,
hotjarVersion,
_4nkUrl,
apiUrl,
}: AppPropsWithLayout) => {
@ -80,8 +75,6 @@ const MyApp = (({
instance.FC_AUTHORIZE_ENDPOINT = fcAuthorizeEndpoint;
instance.FC_CLIENT_ID = fcClientId;
instance.DOCAPOST_API_URL = docaposteApiUrl;
instance.HOTJAR_SITE_ID = hotjarSiteId;
instance.HOTJAR_VERSION = hotjarVersion;
instance._4NK_URL = _4nkUrl;
instance.API_URL = apiUrl;
@ -124,17 +117,7 @@ const MyApp = (({
return () => { };
}, []);
useEffect(() => {
if (!hotjarSiteId || !hotjarVersion) {
console.warn("No hotjar site id or version provided");
return;
}
console.log("Intializing hotjar");
hotjar.initialize({
id: hotjarSiteId,
sv: hotjarVersion,
});
}, [hotjarSiteId, hotjarVersion]);
// Hotjar supprimé
return getLayout(
<>
@ -165,8 +148,6 @@ MyApp.getInitialProps = async () => {
fcAuthorizeEndpoint: publicRuntimeConfig.NEXT_PUBLIC_FC_AUTHORIZE_ENDPOINT,
fcClientId: publicRuntimeConfig.NEXT_PUBLIC_FC_CLIENT_ID,
docaposteApiUrl: publicRuntimeConfig.NEXT_PUBLIC_DOCAPOST_API_URL,
hotjarSiteId: publicRuntimeConfig.NEXT_PUBLIC_HOTJAR_SITE_ID,
hotjarVersion: publicRuntimeConfig.NEXT_PUBLIC_HOTJAR_VERSION,
_4nkUrl: publicRuntimeConfig.NEXT_PUBLIC_4NK_URL,
_4nkIframeUrl: publicRuntimeConfig.NEXT_PUBLIC_4NK_IFRAME_URL,
apiUrl: publicRuntimeConfig.NEXT_PUBLIC_API_URL,

26
tests/analyse.md Normal file
View File

@ -0,0 +1,26 @@
### Objet
Axes de tests pour `lecoffre-front` (sans exemples dimplémentation).
### Couverture prioritaire
- **Routage**: accessibilité des pages clés sous `basePath` `/lecoffre`
- **Auth**: parcours login client et callbacks (Id360/IdNot)
- **Tableau client**: chargement données, états vides, erreurs
- **Dossiers/Documents**: création/affichage, téléchargements, filigrane
- **Souscription**: parcours complet (erreur/succès/gestion)
- **Notifications/Toasts**: affichage cohérent des erreurs
### Données et intégrations
- **API Back**: validation des URL via `NEXT_PUBLIC_BACK_API_*` et `NEXT_PUBLIC_API_URL`
- **Idnot/Docaposte**: vérification des redirections et scopes
### Non-régressions UI/UX
- **DesignSystem**: composants critiques (boutons, tabs, formulaires)
- **Accessibilité**: focus, contrastes, navigation clavier
### Performance
- **Chargement initial**: taille bundle avec `React.lazy`/`Suspense` si applicable
- **Rendu**: éviter re-renders via stores et mémoïsations locales
### Sécurité
- **Données sensibles**: absence de secrets dans `NEXT_PUBLIC_*`
- **JWT**: décodage côté client limité aux besoins