Skip to content

Conversation

yvalentin
Copy link
Contributor

No description provided.

@yvalentin yvalentin requested review from ttdm and Copilot September 11, 2025 14:56
@yvalentin yvalentin self-assigned this Sep 11, 2025
@yvalentin yvalentin linked an issue Sep 11, 2025 that may be closed by this pull request
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements a FAQ system for the application by migrating from hardcoded FAQ data to a Baserow-powered dynamic system. The changes enable FAQ content to be managed through Baserow CMS and automatically generated as static JSON files.

Key changes:

  • Implements a complete FAQ data pipeline from Baserow to frontend JSON files
  • Migrates from hardcoded FAQ data (FaqJson.ts) to dynamic JSON imports
  • Adds comprehensive test coverage for the FAQ system
  • Updates Node.js version from 20.x to 22.x across CI/CD workflows

Reviewed Changes

Copilot reviewed 54 out of 57 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
libs/data/src/faq/ New FAQ domain logic including converters, filters, and features
libs/data/tests/faq/ Comprehensive test suite for FAQ functionality
libs/data/static/frontend/faq/ Generated static JSON files for FAQ content
apps/nuxt/src/tools/faq/FaqJson.ts Removed hardcoded FAQ data file
Various Vue components Updated to import FAQ data from static JSON files
GitHub Actions workflows Updated Node.js version and added FAQ generation workflow

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@@ -25,7 +24,7 @@ export class LinkValidator {
}

public static async findInvalidLinks(inputText: string): Promise<string[]> {
const urlRegex = /(https?:\/\/[^\s]+)/g
const urlRegex = /(https?:\/\/[^\s]+[a-zA-Z0-9])/g
Copy link
Preview

Copilot AI Sep 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern change appears to require URLs to end with alphanumeric characters, but this could break valid URLs that end with other characters like '/' or query parameters. Consider if this restriction is intentional or if it might cause false negatives for valid URLs.

Suggested change
const urlRegex = /(https?:\/\/[^\s]+[a-zA-Z0-9])/g
const urlRegex = /(https?:\/\/[^\s]+)/g

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ttdm tu en penses quoi ? Est-ce que ça peut être génant ? Est-ce que l'on a des urls que l'on check qui pourrait finir par autres choses qu'un chiffre ou une lettre ?

Le fait qu'un url finisse par un / n'est pas bloquant, ça reviens normalement au même avec ou sans slash

Copy link
Contributor

@ttdm ttdm Sep 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Justement non ?
Avec la modif de code, on exclu '/' qui était avant accepté puisque la regex précédente accepte tout.
Et ça va forcer les éditeur à supprimer / des urls ou nous à remove les trailings /.

Certains liens finissent aussi par #; les ancres vides. Et c'est moins courant mais d'autres caractères spéciaux sont acceptés ? et - au minimum.

je suggère donc de remettre comme avant.

Sinon c'est possible d'utiliser zod comme tu me l'avais conseillé ailleurs. (La seule chose qu'avec zod, il faut utiliser un refine pour limiter aux http et https sinon il accepte tout type d'url dont les mails qu'on ne veut pas vérifier. et au final dans le refine, on réécrit quasiment le code en dessous.)

Du coup le plus simple serait directement :

function isValidHttpURL(val: string): boolean {
  try {
    const url = new URL(val);
    return url.protocol === "http:" || url.protocol === "https:";
  } catch {
    return false;
  }
}

Et ce serait plus clair que la regex si tu ne trouves pas la regex claire.

Si tu touches à ce code, ça peut être bien de renommer tous les "url checks" en httpUrlCheck". A l'époque, je ne savais pas que mailto, ftp, tel ... étaient tous considérés comme des urls valides ;)

Copy link
Contributor

@ttdm ttdm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Petit oubli sur le bouton "elles l'ont fait" des fiches projet, sinon RAS.

Questions :
Tu as testé la maj des opérateurs avec le déplacement dans public ?
Et celle des témoignages ?

Comment on lines +74 to +79
protected _replaceLinkObjectByTableData<T extends Id, O extends boolean = false>(
links: LinkObject[],
referencedTableData: T[],
one?: O
): O extends true ? T | undefined : T[] {
return ReplacerBaserow.replaceLinkObjectByTableData<T, O>(links, referencedTableData, one)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remarque:
à mon avis c'est tout aussi simple de call la méthode avec [myObj] puis de sélectionner [0] que de penser à ajouter one = true.
Potentiellement le mieux, aurait été de rename ma méthode _replaceLinkObjectSByTableData
et de créer replaceLinkObject au singulier.
Je t'accorde que ma méthode était mal nommée !
A noter que précédement, on avait nécessaire T[] et que la nouvelle signature introduit T|undefined

})

fs.writeFileSync(fileName, markdownContent, 'utf8')
}

private _sortLogs(): LogEvent[] {
return this.logs.sort((a, b) => {
if (a.criticity === LogLevel.Info && b.criticity !== LogLevel.Info) {
if (a.criticality === LogLevel.Info && b.criticality !== LogLevel.Info) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, merci de m'apprendre l'anglais :)

Comment on lines 39 to 42
public static foundLinks(inputText: string) {
const urlRegex = /(https?:\/\/[^\s]+[a-zA-Z0-9])/g
return inputText.match(urlRegex) || []
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CF discussions en direct, c'est pas l'état final sur cette partie.
Merci pour les modifs,

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment:
Perso je préfère quand l'adaptateur dataprovider->domain est dans l'infra du dataprovider.
Donc par cohérence avec le reste du code, ce code devrait être dans le dossier baserow.
A la place de sort, il y aurait l'ajout d'un attribut priority avec priority = lineNumber et le sorting aurait lieu dans le domain.

la je trouve qu'on fait à la fois la conversion baserow - domain et la transformation domain - json au même endroit.

Comment on lines +14 to +17
private _baserow: FaqBaserowInterface,
private _converter: FaqConverterInterface,
private _filter: FaqFilterInterface,
private _logger: LoggerInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment:
Perso je trouve ça lourd de passer par des interfaces ici.
Ne serait ce que quand on remonte l'historique des methodes appelées; on retombe sur l'interface puis ensuite seulement à partir de l'interface on remonte sur la méthode créée dans le domain. Mais il faut manuellement sélectionner la déclaration vs les réuitlisations.
Si tu as simplement un load+convert puis des méthodes qui call le domain sans interface ça me semble tout aussi clair.

Sachant que la tu as bien du code dans le domain et une interface qui a pour but de clarifier le code; mais ta méthode byActive, qui appartient au domaine prend en entrée des format qui sont des format qui dépendant de ton appplication : "BaserowXXXX"
En terme de valeur d'archi; je trouve qu'avoir byActive qui s'applique sur "FaQ" ou "DataFAQ" est plus intéressant que d'avoir une interface.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, au moins le sorting est clair :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super cool ;)
Proposition:
ajouter des cas markdown en jouant sur le nombre de parenthèses (quitte à les commenter si on fail mais au moins on sait exactement où on en est :) )

- Refactored `foundLinks` to utilize the new MarkedUrl class for extracting external links.
- Added MarkedUrl class to handle markdown parsing and URL extraction.
- Updated LinkValidator tests with additional scenarios to ensure better coverage.
- Enhanced BaserowProject type with BaserowMetaData inheritance.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Faq et BaseRow
2 participants