Code-standaarden en conventies
Codeerstandaarden, werkruimtegrenzen en conventies voor bijdragen aan LibreChat.
Workspace Boundaries
LibreChat is een monorepo. Alle nieuwe code moet gericht zijn op de juiste workspace:
| Workspace | Taal | Kant | Doel |
|---|---|---|---|
/api | JS (legacy) | Backend | Express server — minimaliseer wijzigingen hier |
/packages/api | TypeScript | Backend | Nieuwe backend-code bevindt zich hier (alleen TS, wordt verbruikt door /api) |
/packages/data-schemas | TypeScript | Backend | Databasemodellen/schema's en database-specifieke gedeelde logica |
/packages/data-provider | TypeScript | Gedeeld | API-types, endpoints, data-service — gebruikt door frontend en backend |
/client | TypeScript/React | Frontend | Frontend SPA |
/packages/client | TypeScript | Frontend | Gedeelde frontend-hulpprogramma's |
- Alle nieuwe backend-code moet TypeScript zijn in
/packages/api. - Houd
/apiwijzigingen tot een absoluut minimum (dunne JS-wrappers die/packages/apiaanroepen). - Database-specifieke gedeelde logica staat in
/packages/data-schemas. - Gedeelde API-logica voor frontend/backend (endpoints, types, data-service) bevindt zich in
/packages/data-provider. - Bouw alle gecompileerde code vanuit de project root:
npm run build. - Bouw gedeelde data-provider code opnieuw op na API/type wijzigingen:
npm run build:data-provider.
Algemene richtlijnen
- Gebruik "clean code"-principes: houd functies en modules klein, hanteer het single responsibility principle en schrijf expressieve en leesbare code.
- Gebruik betekenisvolle en beschrijvende namen voor variabelen en functies.
- Geef prioriteit aan de leesbaarheid en onderhoudbaarheid van code boven beknoptheid.
- Gebruik de meegeleverde
.eslintrcen.prettierrcbestanden voor consistente code-opmaak. - Los alle opmaak-lintfouten op met behulp van auto-fix waar beschikbaar. Alle TypeScript/ESLint-waarschuwingen en -fouten moeten zijn opgelost.
Naamgeving en bestandsorganisatie
- Gebruik waar mogelijk bestandsnamen van één woord, zoals
permissions.ts,capabilities.tsofservice.ts. - Wanneer meerdere woorden nodig zijn, heeft een map met één woord de voorkeur die context geeft aan het bestand, zoals
admin/capabilities.tsin plaats vanadminCapabilities.ts. - Laat de directory context bieden. Geef de voorkeur aan
app/service.tsbovenapp/appConfigService.ts.
Codestructuur
- Never-nesting: gebruik early returns, vlakke code, minimale inspringing. Splits complexe operaties op in goed benoemde helpers.
- Functioneel eerst: pure functies, immutable data,
map/filter/reduceboven imperatieve loops. Gebruik OOP alleen wanneer dit het domeinmodel of de inkapseling van de status duidelijk verbetert. - Geen dynamische imports tenzij absoluut noodzakelijk.
- Extraheer herhaalde logica naar toegewezen utility-functies (DRY). Geef de voorkeur aan geparametriseerde helpers, constanten, gedeelde validators, gecentraliseerde foutafhandeling en gedeelde types boven bijna-duplicaat implementaties.
Iteratie en prestaties
- Minimaliseer looping — vooral over gedeelde datastructuren zoals bericht-arrays, waar vaak overheen wordt geïtereerd. Elke extra doorloop telt op bij schaalvergroting.
- Consolideer sequentiële O(n)-operaties waar mogelijk in één enkele doorloop; loop nooit twee keer over dezelfde collectie als het werk gecombineerd kan worden.
- Kies datastructuren die de noodzaak om te itereren verminderen (bijv.
Map/Setvoor opzoekingen in plaats vanArray.find/Array.includes). - Vermijd het onnodig aanmaken van objecten; overweeg de afwegingen tussen ruimte en tijd.
- Voorkom geheugenlekken: wees voorzichtig met closures, ruim resources/event listeners op en vermijd circulaire referenties.
Type Safety
- Gebruik nooit
any. Expliciete types voor alle parameters, retourwaarden en variabelen. - Beperk
unknown— vermijdunknown,Record<string, unknown>enas unknown as Tassertions. EenRecord<string, unknown>duidt bijna altijd op een ontbrekende expliciete typedefinitie. - Dupliceer geen types — controleer of een type al bestaat in het project (vooral in
packages/data-provider) voordat je een nieuwe definieert. Hergebruik en breid bestaande types uit. - Gebruik union types, generics en interfaces op de juiste manier.
Opmerkingen en documentatie
- Schrijf zelfdocumenterende code; gebruik geen inline-commentaar dat beschrijft wat de code doet.
- JSDoc alleen voor complexe/niet-voor-de-hand-liggende logica of intellisense op publieke API's.
- Single-line JSDoc voor beknopte documentatie, multi-line voor complexe gevallen.
- Vermijd zelfstandige
//commentaren tenzij absoluut noodzakelijk.
Importvolgorde
Imports zijn onderverdeeld in drie secties (in deze volgorde):
- Package imports — gesorteerd van kortste naar langste regel (
reactis altijd de eerste import). import typeimports — gesorteerd van lang naar kort (eerst pakket-types, daarna lokale types; lengtesortering wordt gereset tussen subgroepen).- Lokale/project-imports — gesorteerd van langste naar kortste.
- Consolideer waarde-imports uit dezelfde module zoveel mogelijk.
- Gebruik altijd standalone
import type { ... }voor type-imports; gebruik nooit het inlinetypetrefwoord binnen waarde-imports (bijv.import { Foo, type Bar }is fout).
Loop-voorkeuren
- Beperk lussen zoveel mogelijk. Geef de voorkeur aan transformaties in één doorgang en vermijd het herhaaldelijk doorlopen van dezelfde gegevens.
for (let i = 0; ...)voor prestatiekritieke of index-afhankelijke operaties.for...ofvoor eenvoudige array-iteratie.for...inalleen voor het opsommen van objecteigenschappen.
Node.js API-server
API-ontwerp
- Volg RESTful-principes bij het ontwerpen van API's.
- Gebruik betekenisvolle en beschrijvende namen voor routes, controllers, services en models.
- Gebruik de juiste HTTP-methoden (GET, POST, PUT, DELETE) voor elke route.
- Gebruik de juiste statuscodes en responsstructuren voor consistente API-antwoorden (2xx voor succes, 4xx voor een foutief verzoek van de client, 5xx voor een serverfout).
- Gebruik try-catch-blokken om uitzonderingen op een correcte manier op te vangen en af te handelen.
- Implementeer correcte foutafhandeling en retourneer consistent passende foutmeldingen.
- Gebruik het logsysteem in de
utilsdirectory om belangrijke gebeurtenissen en fouten te loggen. - Voer JWT-gebaseerde, stateless authenticatie uit met behulp van de
requireJWTAuthmiddleware.
Bestandsstructuur
Nieuwe backend-code komt in /packages/api als TypeScript. De legacy /api directory volgt deze structuur:
Routes
Specificeert elke HTTP-requestmethode, eventuele te gebruiken middleware en de controllerfunctie die voor elke route moet worden aangeroepen.
- Definieer routes met behulp van de Express Router in afzonderlijke bestanden voor elke resource of logische groepering.
- Gebruik beschrijvende routenamen en houd je aan RESTful-conventies.
- Houd routes beknopt en gericht op één enkele verantwoordelijkheid.
- Voorzie alle routes van het
/apinamespace-voorvoegsel.
Controllers
Bevat de logica voor elke route, inclusief het aanroepen van de juiste servicefuncties en het retourneren van de juiste respons-statuscode en JSON-body.
- Maak een apart controller-bestand voor elke route om de request/response-logica af te handelen.
- Geef controllerbestanden een naam volgens de PascalCase-conventie en voeg "Controller" toe aan de bestandsnaam (bijv.
UserController.js). - Houd controllers slank door complexe operaties te delegeren aan service- of modelbestanden.
Services
Bevat complexe bedrijfslogica of bewerkingen die worden gedeeld door meerdere controllers.
- Geef servicebestanden een naam volgens de PascalCase-conventie en voeg "Service" toe aan de bestandsnaam (bijv.
AuthService.js). - Vermijd het nauw koppelen van services aan specifieke modellen of databases voor een betere herbruikbaarheid.
- Handhaaf het principe van een enkele verantwoordelijkheid binnen elke service.
Modellen
Definieert Mongoose-modellen om data-entiteiten en hun relaties weer te geven.
- Gebruik enkelvoudige, PascalCase namen voor modelbestanden en hun bijbehorende collecties (bijv.
User.jsenuserscollectie). - Neem alleen de noodzakelijke velden, indexen en validaties op in de models.
- Houd modellen onafhankelijk van de API-laag door directe verwijzingen naar request/response-objecten te vermijden.
Databasetoegang (MongoDB en Mongoose)
- Gebruik Mongoose (https://mongoosejs.com) als de MongoDB ODM.
- Maak afzonderlijke modelbestanden voor elke entiteit en zorg voor een duidelijke scheiding van verantwoordelijkheden.
- Gebruik Mongoose schema-validatie om gegevensintegriteit af te dwingen.
- Beheer databaseverbindingen efficiënt en voorkom verbindingslekken.
- Gebruik Mongoose query builders om beknopte en leesbare database-queries te maken.
React Client
Algemene TypeScript en React best practices
- Gebruik TypeScript best practices om te profiteren van statische typering en verbeterde tooling.
- Groepeer gerelateerde bestanden in feature-mappen (bijv.
SidePanel/Memories/). - Geef componenten een naam volgens de PascalCase-conventie.
- Gebruik beknopte en beschrijvende namen die het doel van de component nauwkeurig weergeven.
- Splits complexe componenten in kleinere, herbruikbare componenten wanneer dit gepast is.
- Houd de rendering-logica binnen componenten minimaal.
- Extraheer herbruikbare onderdelen naar afzonderlijke functies of hooks.
- Pas prop type-definities toe met behulp van TypeScript types of interfaces.
- Gebruik formuliervalidatie waar van toepassing (we gebruiken React Hook Form voor formuliervalidatie en verzending).
Lokalisatie
- Alle tekst die voor de gebruiker zichtbaar is, moet worden gelokaliseerd met behulp van de
useLocalize()hook. - Update alleen de Engelse sleutels in
client/src/locales/en/translation.json(andere talen worden extern geautomatiseerd). - Gebruik semantische lokalisatiesleutel-voorvoegsels:
com_ui_,com_assistants_, enz. - Zorg er altijd voor dat er zinvolle fallback-tekst is voor nieuwe lokalisatiesleutels.
Data Services
- Maak data provider hooks aan in
client/src/data-provider/[Feature]/queries.ts. - Exporteer alle hooks vanuit
client/src/data-provider/[Feature]/index.ts. - Voeg feature-exports toe aan de hoofd
client/src/data-provider/index.ts. - Gebruik React Query (
@tanstack/react-query) voor alle API-interacties. - Implementeer correcte query-invalidation bij mutations.
- Voeg QueryKeys en MutationKeys toe aan
packages/data-provider/src/keys.ts.
Bij het toevoegen van gedeelde API-integratie, update:
packages/data-provider/src/api-endpoints.ts(endpoints)packages/data-provider/src/data-service.ts(data service functies)packages/data-provider/src/types/queries.ts(TypeScript-types)
Prestaties
- Geef prioriteit aan geheugen- en snelheidsefficiëntie op schaal.
- Implementeer de juiste cursor-paginering voor grote datasets.
- Vermijd onnodige re-renders met de juiste dependency arrays.
- Maak gebruik van de caching- en achtergrond-refetching-functies van React Query.
Testen en documentatie
- Schrijf unit tests voor alle kritieke en complexe functionaliteiten met behulp van Jest.
- Schrijf integratietests voor alle API-endpoints met behulp van Supertest.
- Schrijf end-to-end tests voor alle client-side functionaliteiten met behulp van Playwright.
- Gebruik beschrijvende testcase- en functienamen om het doel van de test duidelijk uit te drukken.
- Voer tests uit vanuit hun werkmap:
cd api && npx jest <pattern>,cd packages/api && npx jest <pattern>, enz. - Dek laad-, succes- en foutstatussen voor UI/data-flows.
- Gebruik
test/layout-test-utilsvoor het renderen van componenten in frontend-tests. - Geef de voorkeur aan echte logica boven mocks. Mock alleen wat niet lokaal kan worden beheerd, zoals externe HTTP API's, diensten met rate-limiting en niet-deterministische systeemaanroepen.
- Gebruik spies wanneer je aanroepen wilt verifiëren zonder de onderliggende implementatie te vervangen.
- Gebruik
mongodb-memory-servervoor tests die gebaseerd zijn op MongoDB, zodat queries en schema-validatie het gedrag van een echte database simuleren.
Hoe is deze gids?