trekker
Une API de randonnées où chaque requête passe d’abord au gabarit du contrat partagé.
- Stack
- TypeScript · NestJS · Drizzle
- Année
- 2026
Anatomie
8 pièces · une seule les compteRecevoir la demande
Reçoit la demande de liste ; sans session ouverte, l’API répond 401.
TreksController15
@ApiTags('treks')16
@Controller('treks')17
export class TreksController {Vérifier chaque paramètre
Un seul contrat pour l’API, le web et le mobile : filtres, position, 100 par page.
trekListQuerySchema133
export const trekListQuerySchema = paginationQuerySchema134
.extend({135
difficulty: trekDifficultySchema.optional(),Refuser une demande fausse
Répond 422 avec la liste des champs fautifs, au format standard RFC 9457.
ZodValidationException52
if (exception instanceof ZodValidationException) {53
return {54
...base,Découper une page
Trie par nom puis id, saute les pages précédentes et garde 20 itinéraires.
toLimitOffset()127
const where = conditions.length > 0 ? and(...conditions) : undefined;128
const { limit, offset } = toLimitOffset(query);130
const [rows, total] = await Promise.all([Compter les résultats
Compte tous les résultats en même temps : 100 itinéraires donnent 5 pages.
$count()154
this.db.$count(treks, where),155
]);157
return {Alléger chaque résultat
Sert nom, distance et dénivelé sans la trace GPS, trop lourde pour une liste.
trekSummarySchema55
export const trekSummarySchema = entityBaseSchema.extend({56
name: nonEmptyString,57
distanceMeters: z.int().min(0),Accélérer le tri
Un index sur nom puis id : 0,9 ms au lieu de 130 ms par page, sur 2 442 itinéraires.
treks_name_id_idx148
index('treks_name_id_idx').on(table.name, table.id),Stocker les itinéraires
Une table Postgres : une ligne par itinéraire, avec sa trace et son départ.
treks57
export const treks = pgTable(58
'treks',59
{
Tirez une poignée pour demander sa pageFaites glisser un tiroir vers vous pour demander sa page
Nomenclature
- 01 Fente à serrure Reçoit la fiche de demande ; la serrure exige une session. Code : apps/api/src/modules/treks/treks.controller.ts, lignes 8–24 ↗
- 02 Gabarit à broches Vérifie chaque champ de la fiche de demande et ses verrous avant de la laisser passer. Code : packages/contracts/src/treks.ts, lignes 126–185 ↗
- 03 Bac de rejet Recueille la fiche refusée, avec le détail des champs fautifs. Code : apps/api/src/common/filters/problem-details.filter.ts, lignes 52–61 ↗
- 04 Tige et presse-fiches Tient les fiches dans l’ordre name, id ; le presse-fiches en isole vingt, après celles des tiroirs précédents. Code : apps/api/src/modules/treks/treks.service.ts, lignes 127–151 ↗
- 05 Totalisateur Compte toutes les fiches qui répondent, pendant que le tiroir sort, et en déduit le nombre de pages. Code : apps/api/src/modules/treks/treks.service.ts, lignes 152–160 ↗
- 06 Fiche résumé Ce qui sort du tiroir : la fiche sans son tracé, qui reste au fond. Code : packages/contracts/src/treks.ts, lignes 49–74 ↗
- 07 Glissières à billes Font sortir le tiroir sans qu’on trie le meuble. Code : packages/db/src/schema/treks.ts, lignes 142–148 ↗
- 08 Corps à tiroirs Le meuble lui-même : chaque fiche y est rangée une fois. Code : packages/db/src/schema/treks.ts, lignes 57–91 ↗