数字核心 · REST API 参考

唯一的 API

DWFW 核心在 /api 下提供 JSON 格式的 REST API。策展人面板、管理后台和公共网站使用的都是同一个 API:没有"内部"与"外部"之分。本参考由已部署的真实数据模式生成——端点、字段、权限和 OpenAPI——因此始终描述实际存在的内容。

基础 URL https://dwfw.trabemflex.com/apiOpenAPI 3.0MCP 服务器

01

简介

数据模式中的每个集合都是一个 REST 资源,支持常规五种操作(列表、读取、创建、更新、删除)外加计数。API 由 Payload CMS 根据 TypeScript 数据模式生成,因此不会与模型或权限脱节:管理后台允许的,就是 API 允许的。

约定:UTF-8 JSON;数字 id;ISO 8601 日期(UTC);slug 与 select 取值为无重音的西班牙语(它们是标识符,不是文本);写入时使用 Content-Type: application/json。GraphQL 已停用:一切皆为 REST。

  • 基础 URL:https://dwfw.trabemflex.com/api(开发环境为 http://localhost:3000/api)。
  • 版本:API 跟随仓库的数据模式版本;破坏性变更在 README 和本文档中公布。
  • 没有流行度指标:任何资源都没有点赞、浏览量或排名,这是原则(算法悬置)。

02

快速开始

三次调用了解工作方式:未登录读取公开数据、登录、登录后读取。

# 1 · 未登录:公开数据(档案),英文
curl "https://dwfw.trabemflex.com/api/obras?locale=en&depth=1&limit=20"

# 2 · 登录(设置 payload-token cookie 并返回 JWT)
TOKEN=$(curl -s -H "Content-Type: application/json" \
  -d '{"email":"media@dwfw.test","password":"dwfw-demo-2026"}' \
  "https://dwfw.trabemflex.com/api/usuarios/login" | jq -r .token)

# 3 · 登录后:权限范围内的一切
curl -H "Authorization: JWT $TOKEN" "https://dwfw.trabemflex.com/api/obras?locale=en&depth=1"

03

认证

会话即 Payload 会话。POST /api/usuarios/login 传入 email 与 password,返回用户、JWT 及其过期时间(exp),并设置 HttpOnly 的 payload-token cookie。两种方式均可:cookie(浏览器,需 credentials: include;受 CSRF 保护,仅接受来自本站源的请求)或 Authorization: JWT <token> 请求头(服务器、脚本、应用:浏览器之外必须使用)。令牌 2 小时后过期;/api/usuarios/refresh-token 可在无需再次输入密码的情况下续期。

GET /api/usuarios/me 返回会话用户(无会话时 user: null)。GET /api/access 汇总当前会话在每个集合中允许的操作和字段:这是构建随角色自适应界面的推荐方式。

# 登录:返回用户、JWT,并设置 payload-token cookie(HttpOnly)
curl -H "Content-Type: application/json" \
  -d '{"email":"media@dwfw.test","password":"dwfw-demo-2026"}' \
  "https://dwfw.trabemflex.com/api/usuarios/login"
# → { "user": { … }, "token": "<jwt>", "exp": 1790000000 }   (+ cookie payload-token)

# 使用 Authorization: JWT 请求头(脚本、服务器、应用)
curl -H "Authorization: JWT <token>" "https://dwfw.trabemflex.com/api/usuarios/me"

# 浏览器中 cookie 即可(同源;启用 csrf 后,没有匹配的 Origin 头时 cookie 会被忽略)
fetch('/api/usuarios/me', { credentials: 'include' })

# 在过期前刷新令牌(默认 2 小时)
curl -H "Authorization: JWT <token>" -X POST "https://dwfw.trabemflex.com/api/usuarios/refresh-token"

# 当前会话在每个集合和字段上可执行的操作
curl -H "Authorization: JWT <token>" "https://dwfw.trabemflex.com/api/access"

# 退出登录
curl -H "Authorization: JWT <token>" -X POST "https://dwfw.trabemflex.com/api/usuarios/logout"

04

权限:角色与权限项

访问由基于权限的 RBAC 决定,而非视图。用户可兼有多个角色;每个角色是一组权限的快捷方式;授权可附加单项权限并可选到期日(自动失效)。下表来自代码(src/access/capabilities.ts)。

另有两项限制:scopeEdiciones 将合作伙伴的读取限定在其届次;obra:editar_propia 让创作者只能修改关联其作者档案的作品。权限不足的请求返回 403;受限读取只返回允许的内容(Media 没有 obra:leer,仅能看到档案)。

权限direccionfounding curatorcuradorinvestigadorcreadorpartnermediaadvisory
obra:leer●●●●●●·●
obra:crear●●●·●···
obra:editar●●●·····
obra:editar_propia●···●···
obra:borrar●·······
autor:leer●●●●●●●●
autor:gestionar●·······
autor:editar_taller●···●···
nodo:leer●●●●●··●
nodo:gestionar●●●·····
conexion:leer●●●●●··●
conexion:proponer●●●●····
conexion:confirmar●●●·····
significado:leer●●●●●··●
significado:asignar●●●·····
movimiento:avanzar●●●·····
index:leer●●●●···●
edicion:leer●●●●●●●●
edicion:gestionar●·······
capitulo:gestionar●·······
pieza:gestionar●·······
usuario:gestionar●·······

05

查询:参数、筛选与分页

所有列表接受相同参数。列表响应带分页元数据(totalDocs、totalPages、nextPage……)。

参数用途
locale内容语言:es(默认)、en、zh、ja。读写均适用。`all` 返回全部翻译。
fallback-locale缺少翻译时回退的语言(默认 es)。`none` 表示不回退。
depth解析关联的层级数(0 = 仅 id)。默认 2。越小越快。
limit · page分页:每页大小(默认 10)与页码(从 1 起)。`pagination=false` 返回全部(慎用)。
sort排序字段;前置短横线为降序(sort=-createdAt)。多个字段以逗号分隔。
where[campo][op]=valor筛选。可嵌套:where[and][n][字段][op] / where[or][n][字段][op]。关联字段用点号:autor.nombre、origen.value。
select[campo]=true限制返回字段。populate[集合][字段]=true 选择关联中解析哪些字段。
draft · joins本数据模式不适用(无草稿或 join)。在此说明以免在 /api/access 响应中产生疑惑。

运算符

运算符含义
equals等于。适用于 select、关联 id、布尔值与 ISO 日期。
not_equals不等于。
in · not_in在 / 不在逗号分隔的列表中。
contains · like文本:包含(不区分大小写)/ 含全部词语的模式。
greater_than · greater_than_equal大于 / 大于等于:数字与日期。
less_than · less_than_equal小于 / 小于等于。
existsexists=true / false:字段是否有值。
near · within · intersects仅 point 类型字段(本数据模式中没有)。
# 分页排序列表,日文内容,关联解析两层
curl "https://dwfw.trabemflex.com/api/obras?locale=ja&depth=2&limit=10&page=1&sort=-updatedAt"

# 简单筛选:档案中的作品(环节 7)
curl -g "https://dwfw.trabemflex.com/api/obras?where[estadoCuratorial][equals]=movimiento_7"

# 组合筛选:and / in / exists
curl -g "https://dwfw.trabemflex.com/api/obras?where[and][0][tipo][in]=modelo_3d,avatar&where[and][1][edicion][exists]=true"

# 多态关联:同时按 value 和 relationTo 筛选(不同集合的 id 会重复)
curl -g "https://dwfw.trabemflex.com/api/conexiones?where[or][0][origen.value][equals]=1&where[or][0][origen.relationTo][equals]=obras"

# 仅返回部分字段(更轻量的响应)
curl -g "https://dwfw.trabemflex.com/api/obras?select[titulo]=true&select[estadoCuratorial]=true&depth=0"

# 仅计数,不返回文档
curl -g "https://dwfw.trabemflex.com/api/obras/count?where[estadoCuratorial][equals]=movimiento_7"
{
  "docs": [ { "id": 3, "titulo": "Metsä · Micelio v3", "estadoCuratorial": "movimiento_7", "…": "…" } ],
  "totalDocs": 1,
  "limit": 10,
  "totalPages": 1,
  "page": 1,
  "pagingCounter": 1,
  "hasPrevPage": false,
  "hasNextPage": false,
  "prevPage": null,
  "nextPage": null
}

06

语言

内容(标题、描述、备注、alt……)按语言存储:西班牙语(默认)、英语、简体中文和日语。通过 ?locale= 请求;若翻译不存在则返回西班牙语,因此不会出现空白。?locale=all 一次返回全部翻译({ es, en, zh, ja })。技术 id 不翻译:它们是数据。

以另一种语言写入即带 ?locale=xx 的 PATCH,只发送本地化字段:关联与状态不随语言变化。每个资源参考中的"本地化"列标明哪些字段是本地化的。

07

写入

POST 创建,PATCH 部分更新(仅发送的字段),DELETE 删除。关联以 id 发送;多态关联为 { relationTo, value }。文件通过 multipart/form-data 上传至 Media。

  • 校验:必填字段与 select 取值在服务器端检查;400 会详述字段与原因。
  • 原则钩子:Significados 强制 procedencia=humano;estadoCuratorial 仅通过 movimiento:avanzar 改变;创作者不能认领他人作品。
  • 幂等性:PATCH 与 DELETE 幂等;POST 不幂等(每次调用创建一个文档)。
# 创建(需要 obra:crear)。保存在指定 locale;关联使用 id
curl -H "Authorization: JWT $TOKEN" -H "Content-Type: application/json" -X POST \
  -d '{"titulo":"Nueva obra","tipo":"modelo_3d","autor":1,"nodoOrigen":"laboratorio_ia"}' \
  "https://dwfw.trabemflex.com/api/obras?locale=es"
# → 201 { "message": "…", "doc": { "id": 4, … } }

# 在另一 locale 上部分更新:仅本地化字段,其余不变
curl -H "Authorization: JWT $TOKEN" -H "Content-Type: application/json" -X PATCH \
  -d '{"titulo":"New work","descripcionFormal":{"silueta":"…"}}' \
  "https://dwfw.trabemflex.com/api/obras/4?locale=en"

# 写入多态关联:{ relationTo, value }
curl -H "Authorization: JWT $TOKEN" -H "Content-Type: application/json" -X POST \
  -d '{"origen":{"relationTo":"obras","value":4},"destino":{"relationTo":"nodos","value":2},"tipoRelacion":"dialoga_con","procedencia":"humano","estado":"propuesta"}' \
  "https://dwfw.trabemflex.com/api/conexiones"

# 确认连接(需要 conexion:confirmar;否则返回 403 并附明确信息)
curl -H "Authorization: JWT $TOKEN" -X PATCH -H "Content-Type: application/json" \
  -d '{"estado":"confirmada","procedencia":"humano"}' "https://dwfw.trabemflex.com/api/conexiones/1"

# 上传文件到 Media:multipart,含 `file` 和 `_payload`(其余字段的 JSON)
curl -H "Authorization: JWT $TOKEN" -F "file=@look-03.png" -F '_payload={"alt":"Look 03"}' "https://dwfw.trabemflex.com/api/media"

# 删除(需要 obra:borrar)
curl -H "Authorization: JWT $TOKEN" -X DELETE "https://dwfw.trabemflex.com/api/obras/4"

08

资源参考

每个集合一个区块:路径、谁可读谁可写、字段类型与本地化,以及渲染本页时从公开 API 获取的真实示例。

资源路径读取写入(权限)
作品/api/obras仅档案(环节 7)公开;其余按权限obra:crear · obra:editar / obra:editar_propia · obra:borrar · movimiento:avanzar (estadoCuratorial)
作者/api/autores公开autor:gestionar
节点/api/nodos公开nodo:gestionar
连接/api/conexiones公开conexion:proponer · conexion:confirmar
意义/api/significados公开significado:asignar
策展环节/api/movimientos公开movimiento:avanzar
届次/api/ediciones公开edicion:gestionar
品牌章节/api/capitulos公开capitulo:gestionar
视听作品/api/piezas公开pieza:gestionar
技术资产/api/media仅档案(环节 7)公开;其余按权限obra:crear (subir) · propio: editar / borrar si no publicado · obra:editar: todo y publicar
用户/api/usuarios需登录(每个用户只看到自己;usuario:gestionar 可见全部)usuario:gestionar

资源

作品

/api/obras

第一层。作为文化文献的作品:类型、作者、来源节点、策展状态(7 个环节)、形式描述与技术资产。

读取
仅档案(环节 7)公开;其余按权限
写入(权限)
obra:crear · obra:editar / obra:editar_propia · obra:borrar · movimiento:avanzar (estadoCuratorial)
操作
GET /api/obras GET /api/obras/count GET /api/obras/:id POST /api/obras PATCH /api/obras/:id DELETE /api/obras/:id

字段

字段类型必填本地化取值 / 目标
titulo 标题text是是—
tipo 类型select是—modelo_3davatarcoleccion_digitalprenda_fisicaexperiencia_inmersivacodigo_generativo
autor 作者relationship是—关联至 autores
nodoOrigen 来源节点(出处)select是—academico_investigadorcomunidad_digital_emergentelaboratorio_iainstitucion_archivo
estadoCuratorial 策展状态select是—movimiento_1movimiento_2movimiento_3movimiento_4movimiento_5movimiento_6movimiento_7
descripcionFormal.silueta 廓形textarea—是—
descripcionFormal.material 材质textarea—是—
descripcionFormal.sintaxisVisual 视觉句法textarea—是—
activosTecnicos 技术资产(顶点、贴图、视频)join———
edicion 届次relationship——关联至 ediciones

真实示例(GET,depth=0,公开视图)

GET https://dwfw.trabemflex.com/api/obras?depth=0&locale=zh&limit=1

{
  "id": 3,
  "titulo": "Metsä · 菌丝体 v3",
  "tipo": "codigo_generativo",
  "autor": 3,
  "nodoOrigen": "laboratorio_ia",
  "estadoCuratorial": "movimiento_7",
  "descripcionFormal": {
    "silueta": null,
    "material": "模拟菌丝体生长作为图案生成器。",
    "sintaxisVisual": "形式不是画出来的,而是培育出来的。"
  },
  "activosTecnicos": {
    "docs": [],
    "hasNextPage": false
  },
  "edicion": null,
  "updatedAt": "2026-08-22T18:29:49.582Z",
  "createdAt": "2026-08-21T07:12:39.411Z"
}

资源

作者

/api/autores

第二层。设计师、集体、实验室与机构。文化渊源仅为描述,绝非排序标准。

读取
公开
写入(权限)
autor:gestionar
操作
GET /api/autores GET /api/autores/count GET /api/autores/:id POST /api/autores PATCH /api/autores/:id DELETE /api/autores/:id

字段

字段类型必填本地化取值 / 目标
nombre 姓名text是——
tipo 类型select是—diseñadorinvestigadorartistacolectivolaboratorioinstitucion
origenCultural 文化渊源text—是—
bio 简介textarea—是—
trayectoria 履历textarea—是—
nodos 节点relationship[]——关联至 nodos
taller.capacidad 工作室产能textarea—是—
taller.materiales 所用材料select[]——algodonlanalinosedacueropuntodenimfibras_sinteticasmateriales_biobasadostextil_tecnicosin_material_fisico
taller.tecnologias 技术select[]——patronaje_digitalmodelado_3dsimulacion_textildiseno_generativoimpresion_3dcorte_laserbordado_digitalestampacion_digitaltejido_punto_industrialconfeccion_artesanaltenido_natural
taller.usaFibrasRecicladas 是否使用再生纤维?checkbox———
taller.fibrasRecicladasDetalle 再生纤维·说明textarea—是—
taller.notasSostenibilidad 可持续性说明textarea—是—

真实示例(GET,depth=0,公开视图)

GET https://dwfw.trabemflex.com/api/autores?depth=0&locale=zh&limit=1

{
  "id": 3,
  "nombre": "Lab Metsä",
  "tipo": "laboratorio",
  "origenCultural": "芬兰赫尔辛基",
  "bio": "生成式材料实验室。",
  "trayectoria": "专注于模拟生物纺织品的学术衍生机构。",
  "nodos": [],
  "taller": {
    "capacidad": null,
    "materiales": [],
    "tecnologias": [],
    "usaFibrasRecicladas": null,
    "fibrasRecicladasDetalle": null,
    "notasSostenibilidad": null,
    "procedencia": "humano"
  },
  "updatedAt": "2026-08-22T18:29:48.843Z",
  "createdAt": "2026-08-21T07:12:36.066Z"
}

资源

节点

/api/nodos

第三层。图谱的顶点:哲学思潮、技术发展、社群、机构、文化张力。

读取
公开
写入(权限)
nodo:gestionar
操作
GET /api/nodos GET /api/nodos/count GET /api/nodos/:id POST /api/nodos PATCH /api/nodos/:id DELETE /api/nodos/:id

字段

字段类型必填本地化取值 / 目标
nombre 名称text是是—
tipo 类型select是—corriente_filosoficadesarrollo_tecnologico_previocomunidad_subculturainstituciontension_cultural
descripcion 描述textarea—是—

真实示例(GET,depth=0,公开视图)

GET https://dwfw.trabemflex.com/api/nodos?depth=0&locale=zh&limit=1

{
  "id": 4,
  "nombre": "生成模型时代的作者身份",
  "tipo": "tension_cultural",
  "descripcion": null,
  "updatedAt": "2026-08-22T18:29:49.224Z",
  "createdAt": "2026-08-21T07:12:36.120Z"
}

资源

连接

/api/conexiones

第三层。图的有类型边。机器出处的连接以提议状态创建,仅由人确认。

读取
公开
写入(权限)
conexion:proponer · conexion:confirmar
操作
GET /api/conexiones GET /api/conexiones/count GET /api/conexiones/:id POST /api/conexiones PATCH /api/conexiones/:id DELETE /api/conexiones/:id

字段

字段类型必填本地化取值 / 目标
origen 起点relationship是—关联至 obrasnodos
destino 终点relationship是—关联至 obrasnodos
tipoRelacion 关系类型select是—dialoga_conposibilitada_porconversacion_paralela_con
procedencia 出处select是—maquinahumano
estado 状态select是—propuestaconfirmadadescartada
confirmadaPor 确认人relationship——关联至 usuarios
confirmadaEn 确认时间date———
nota 备注textarea—是—

真实示例(GET,depth=0,公开视图)

GET https://dwfw.trabemflex.com/api/conexiones?depth=0&locale=zh&limit=1

{
  "id": 6,
  "origen": {
    "relationTo": "obras",
    "value": 2
  },
  "destino": {
    "relationTo": "obras",
    "value": 1
  },
  "tipoRelacion": "conversacion_paralela_con",
  "procedencia": "maquina",
  "estado": "propuesta",
  "confirmadaPor": null,
  "confirmadaEn": null,
  "nota": "Coincidencia en el campo silueta: ambas describen la silueta por lo que le falta de sostén estructural. Aguacero 01: \"Volumen inflado, sin punto de apoyo.\" Kata: \"Hombro desestructurado: la autoridad se retira del cuerpo.\" Vocabulario compartido: \"sin punto de apoyo\" / \"desestructurado\" / \"se retira\" — en las dos la forma se define por la ausencia de estructura que la sostenga, no por lo que añade. Divergen en tipo (coleccion_digital vs modelo_3d), nodo de origen (comunidad_digital_emergente vs academico_investigador) y material (plástico de baja poligonización vs lana simulada), y no tienen conexión entre sí en la cartografía. Solo se usa la descripción formal; no se usa el significado asignado a Kata ni el origen cultural de los autores. Evidencia sintáctica, pendiente de lectura curatorial.",
  "updatedAt": "2026-09-03T07:10:25.005Z",
  "createdAt": "2026-09-03T07:10:25.005Z"
}

资源

意义

/api/significados

第四层。固定的诠释学问题与解读。始终为人工出处(由服务器强制)。

读取
公开
写入(权限)
significado:asignar
操作
GET /api/significados GET /api/significados/count GET /api/significados/:id POST /api/significados PATCH /api/significados/:id DELETE /api/significados/:id

字段

字段类型必填本地化取值 / 目标
obra 作品relationship是—关联至 obras
tensionSubyacente 这一创作回应了当代社会的何种张力?textarea是是—
lectura 解读array———
lectura[].tipo 类型select——antropologicaeticapoetica
lectura[].texto 文本textarea—是—
textosTeoricos 相关批评文献textarea—是—
curador 策展人relationship——关联至 usuarios
procedencia 出处 · 只读text———

真实示例(GET,depth=0,公开视图)

GET https://dwfw.trabemflex.com/api/significados?depth=0&locale=zh&limit=1

{
  "id": 2,
  "obra": 3,
  "tensionSubyacente": "jhksjhdkae",
  "lectura": [],
  "curador": 1,
  "procedencia": "humano",
  "updatedAt": "2026-09-04T12:02:19.341Z",
  "createdAt": "2026-09-04T12:02:19.340Z"
}

资源

策展环节

/api/movimientos

策展工作流:每件作品的七个环节,含负责人与出处。

读取
公开
写入(权限)
movimiento:avanzar
操作
GET /api/movimientos GET /api/movimientos/count GET /api/movimientos/:id POST /api/movimientos PATCH /api/movimientos/:id DELETE /api/movimientos/:id

字段

字段类型必填本地化取值 / 目标
obra 作品relationship是—关联至 obras
movimiento 环节select是—movimiento_1movimiento_2movimiento_3movimiento_4movimiento_5movimiento_6movimiento_7
estado 状态select是—pendienteen_cursocompletado
responsable 负责人relationship——关联至 usuarios
procedencia 出处select是—maquinahumano
notas 备注textarea—是—

真实示例(GET,depth=0,公开视图)

GET https://dwfw.trabemflex.com/api/movimientos?depth=0&locale=zh&limit=1

{
  "id": 21,
  "obra": 3,
  "movimiento": "movimiento_7",
  "estado": "en_curso",
  "responsable": 2,
  "procedencia": "humano",
  "updatedAt": "2026-08-21T07:12:40.179Z",
  "createdAt": "2026-08-21T07:12:40.179Z"
}

资源

届次

/api/ediciones

Event Stack。每一届(日期、主办城市、焦点国家)。

读取
公开
写入(权限)
edicion:gestionar
操作
GET /api/ediciones GET /api/ediciones/count GET /api/ediciones/:id POST /api/ediciones PATCH /api/ediciones/:id DELETE /api/ediciones/:id

字段

字段类型必填本地化取值 / 目标
nombre 名称text是是—
fechaInicio 开始日期date是——
fechaFin 结束日期date———
ciudadAnfitriona 主办城市(Country in Focus)text—是—
paisEnFoco 焦点国家text—是—

真实示例(GET,depth=0,公开视图)

GET https://dwfw.trabemflex.com/api/ediciones?depth=0&locale=zh&limit=1

{
  "id": 1,
  "nombre": "DWFW · 第一届",
  "fechaInicio": "2027-03-12T00:00:00.000Z",
  "fechaFin": "2027-03-15T00:00:00.000Z",
  "ciudadAnfitriona": "马德里",
  "paisEnFoco": "西班牙",
  "updatedAt": "2026-08-22T18:29:48.495Z",
  "createdAt": "2026-08-21T07:12:35.921Z",
  "fase": "antes",
  "cuentaAtras": 12331013
}

资源

品牌章节

/api/capitulos

Event Stack。某届的品牌章节:板块、大洲、时长、作品。

读取
公开
写入(权限)
capitulo:gestionar
操作
GET /api/capitulos GET /api/capitulos/count GET /api/capitulos/:id POST /api/capitulos PATCH /api/capitulos/:id DELETE /api/capitulos/:id

字段

字段类型必填本地化取值 / 目标
titulo 标题text是是—
edicion 届次relationship是—关联至 ediciones
autor 作者relationship——关联至 autores
duracionMin 时长(分钟)number———
seccion 板块select——country_in_focusicons_of_designfuture_labconversaciones
continente 大洲select——asiaoceaniaeuropaafricaamerica
obras 作品relationship[]——关联至 obras

真实示例(GET,depth=0,公开视图)

GET https://dwfw.trabemflex.com/api/capitulos?depth=0&locale=zh&limit=1

{
  "id": 3,
  "titulo": "对谈 · 作者身份与机器",
  "edicion": 1,
  "autor": 2,
  "duracionMin": 60,
  "seccion": "conversaciones",
  "continente": "america",
  "obras": [
    2
  ],
  "updatedAt": "2026-08-22T19:21:09.427Z",
  "createdAt": "2026-08-22T19:21:09.303Z"
}

资源

视听作品

/api/piezas

Event Stack。视听作品(首映、对谈、幕后花絮……)及流媒体引用。

读取
公开
写入(权限)
pieza:gestionar
操作
GET /api/piezas GET /api/piezas/count GET /api/piezas/:id POST /api/piezas PATCH /api/piezas/:id DELETE /api/piezas/:id

字段

字段类型必填本地化取值 / 目标
titulo 标题text是是—
tipo 类型select——premiereconversacionmaking_ofhero_lookreemisionclip
capitulo 章节relationship——关联至 capitulos
obra 作品relationship——关联至 obras
urlStreaming 流媒体网址text———

真实示例(GET,depth=0,公开视图)

GET https://dwfw.trabemflex.com/api/piezas?depth=0&locale=zh&limit=1

{
  "id": 3,
  "titulo": "与 Colectivo Aguacero 对谈",
  "tipo": "conversacion",
  "capitulo": 3,
  "obra": 2,
  "urlStreaming": null,
  "updatedAt": "2026-08-22T19:21:09.874Z",
  "createdAt": "2026-08-22T19:21:09.764Z"
}

资源

技术资产

/api/media

技术资产:图片(≤50 MB)、视频(≤2 GB)、3D 模型 .glb/.gltf/.usdz/.fbx/.obj(≤500 MB)和 PDF(≤20 MB)。默认私密(盲评):上传者与策展团队可见;作品到达环节 7 时公开。存储于 Cloudflare R2;视频与 3D 直传至存储桶。信息:描述、署名、材质、AI 使用、许可、软件。

读取
仅档案(环节 7)公开;其余按权限
写入(权限)
obra:crear (subir) · propio: editar / borrar si no publicado · obra:editar: todo y publicar
操作
GET /api/media GET /api/media/count GET /api/media/:id POST /api/media PATCH /api/media/:id DELETE /api/media/:id

字段

字段类型必填本地化取值 / 目标
titulo 标题text—是—
alt 替代文本text—是—
categoria 类别 · 只读select——imagenvideomodelo3ddocumento
obra 作品relationship——关联至 obras
publico 公开checkbox———
subidoPor 上传者 · 只读relationship——关联至 usuarios
ficha.descripcion 描述textarea—是—
ficha.creditos 署名 / 作者text———
ficha.materiales 材质 / 技术text—是—
ficha.usoIA AI 使用情况select——ningunoasistidogenerativo
ficha.licencia 许可select——todos_los_derechoscc_bycc_by_nccc_by_nc_nd
ficha.software 软件 / 流程text———

真实示例(GET,depth=0,公开视图)

未登录时无可见文档。

资源

用户

/api/usuarios

带角色和额外权限(可到期的授权)的账户,可选关联至作者。

读取
需登录(每个用户只看到自己;usuario:gestionar 可见全部)
写入(权限)
usuario:gestionar
操作
GET /api/usuarios GET /api/usuarios/count GET /api/usuarios/:id POST /api/usuarios PATCH /api/usuarios/:id DELETE /api/usuarios/:id POST …/login POST …/logout GET …/me POST …/refresh-token

字段

字段类型必填本地化取值 / 目标
nombre 姓名text是——
roles 角色select[]是—direccionfounding_curatorcuradorinvestigadorcreadorpartnermediaadvisory
concesiones 额外权限(临时或永久)array———
concesiones[].capacidad 权限select是—obra:leerobra:crearobra:editarobra:editar_propiaobra:borrarautor:leerautor:gestionarautor:editar_tallernodo:leernodo:gestionarconexion:leerconexion:proponerconexion:confirmarsignificado:leersignificado:asignarmovimiento:avanzarindex:leeredicion:leeredicion:gestionarcapitulo:gestionarpieza:gestionarusuario:gestionar
concesiones[].caduca 到期date———
concesiones[].motivo 原因text———
scopeEdiciones 仅限于这些届次relationship[]——关联至 ediciones
autor 作者relationship——关联至 autores
enableAPIKey checkbox———
apiKey text———
email email是——

真实示例(GET,depth=0,公开视图)

未登录时无可见文档。

09

错误

错误以 JSON 返回,带相应 HTTP 状态码和 errors 数组。我们的钩子使用带明确状态码的 APIError,消息语言随请求(Accept-Language)。

状态码何时
200 · 201成功。POST 返回 201 及 { message, doc };PATCH 与 DELETE 返回 200。
400校验失败或请求格式错误。`errors[0].data.errors` 列出字段与原因。
401需要登录的操作未登录(或令牌过期)。
403会话缺少所需权限;也包括原则性规则(无 conexion:confirmar 时确认连接)。
404文档不存在——或对当前会话不可见(RBAC 不暴露存在性)。
413 · 415上传过大或文件类型不允许(Media)。
500内部错误。Payload 返回 "Something went wrong";我们的钩子使用带明确状态码的 APIError,以避免到达此处。
HTTP/1.1 403 Forbidden
{ "errors": [ { "message": "Confirmar una conexión es un acto semántico: requiere la capacidad conexion:confirmar." } ] }

HTTP/1.1 400 Bad Request
{ "errors": [ { "name": "ValidationError", "message": "The following field is invalid: titulo",
                "data": { "errors": [ { "message": "This field is required.", "path": "titulo" } ] } } ] }

10

OpenAPI、类型与集成

OpenAPI 3.0 规范由同一配置生成:可导入 Postman、Insomnia、Stoplight,或用 openapi-generator 生成客户端。数据模式的 TypeScript 类型位于 src/payload-types.ts(通过 pnpm generate:types 重新生成)。

下载 openapi.jsonpayload-types.ts · GitHub

// 最简 JavaScript 客户端(浏览器或 Node 18+)
const API = 'https://dwfw.trabemflex.com/api'

const res = await fetch(`${API}/usuarios/login`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email, password }),
  credentials: 'include', // 浏览器中 cookie 即可;服务器端使用请求头
})
const { token } = await res.json()

// 使用请求头中的 JWT 读取
const obras = await fetch(`${API}/obras?locale=ja&depth=1&limit=20`, {
  headers: { Authorization: `JWT ${token}` },
}).then((r) => r.json())

// 数据模式的 TypeScript 类型(src/payload-types.ts)
import type { Obra, Autor } from './payload-types'

11

最佳实践

  • 只请求所需:depth=0 或 1 以及 select[...] 可大幅减小响应。
  • 公开列表务必分页(limit ≤ 100)并按稳定字段排序。
  • 多态关联同时按 value 和 relationTo 筛选。
  • 按角色构建界面时,每个会话查询一次 /api/access,而不是硬编码角色。
  • 将 select 取值和权限视为稳定标识符;在客户端用标签翻译,切勿重命名取值。
  • 服务器端使用 Authorization: JWT 请求头并通过 refresh-token 续期;浏览器依赖 cookie。
每一层都有出处 · 算法悬置 · 七个环节