Search the public site through the API

Full-text on Postgres, stemmed in the language searched; word matching
elsewhere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-01 08:53:34 +02:00
parent 68c5bd4274
commit 6b3517743a
8 changed files with 417 additions and 0 deletions

View File

@@ -267,6 +267,55 @@ paths:
description: Null applies in every language.
"503": { $ref: "#/components/responses/Maintenance" }
/public/v1/search:
get:
tags: [Public]
summary: Search the site
description: |
What the site shows that matches some words, in the request's
language, best match first: published pages, projects and services,
open calls, public members, and technologies in use.
Full-text in production — words are stemmed in the language searched,
so "proyectos" finds "proyecto", and a title match ranks above one in
the body. `path` is where the result lives on the site; null for a
technology, which has no address on this side.
security: []
parameters:
- $ref: "#/components/parameters/Lang"
- name: q
in: query
required: true
schema: { type: string, minLength: 2, maxLength: 120 }
- name: type[]
in: query
description: "Limit to some kinds: `page`, `project`, `service`, `call`, `member`, `technology`."
schema:
type: array
items: { type: string, enum: [page, project, service, call, member, technology] }
- name: limit
in: query
schema: { type: integer, minimum: 1, maximum: 50, default: 20 }
responses:
"200":
description: Results
content:
application/json:
schema:
type: object
properties:
data:
type: array
items: { $ref: "#/components/schemas/PublicSearchResult" }
meta:
type: object
properties:
query: { type: string }
locale: { type: string }
count: { type: integer }
"422": { $ref: "#/components/responses/ValidationError" }
"503": { $ref: "#/components/responses/Maintenance" }
/public/v1/projects:
get:
tags: [Public]
@@ -4342,6 +4391,16 @@ components:
alternates: { $ref: "#/components/schemas/Alternates" }
path: { type: string, nullable: true }
PublicSearchResult:
type: object
properties:
type: { type: string, enum: [page, project, service, call, member, technology] }
id: { type: integer }
title: { type: string }
excerpt: { type: string, description: Plain text around the first match. }
path: { type: string, nullable: true, example: /proyectos/mi-proyecto }
score: { type: number, description: Higher is a better match. Only comparable within one response. }
PublicTechnology:
type: object
properties: