feat(slice3): listRFCs accepts facet selections, returns {items,facets} (§22.4a)
This commit is contained in:
+20
-4
@@ -203,11 +203,27 @@ export async function createProject({ projectId, name, type, visibility, content
|
||||
// §22.4 (Plan B) / §22 S2: per-collection serving. With a projectId + a
|
||||
// collectionId, read the collection-scoped routes; with only a projectId, the
|
||||
// project default-collection compat path; with neither, the unscoped path.
|
||||
export async function listRFCs(projectId, collectionId) {
|
||||
if (projectId && collectionId) {
|
||||
return jsonOrThrow(await fetch(`/api/projects/${projectId}/collections/${collectionId}/rfcs`))
|
||||
// §22.4a SLICE-3: faceted catalog. `opts.selections` is { field: string[] }
|
||||
// (each non-empty array becomes repeated query params, OR within the field);
|
||||
// `opts.malformed` toggles the malformed-only filter. Returns the full payload
|
||||
// { items, facets } — callers read both. With no selections it behaves as the
|
||||
// pre-SLICE-3 list (and a no-fields collection returns facets: {}). Facets are
|
||||
// served only on the project/collection-scoped paths, not the unscoped one.
|
||||
export async function listRFCs(projectId, collectionId, opts = {}) {
|
||||
const { selections = {}, malformed = false } = opts
|
||||
const qs = new URLSearchParams()
|
||||
for (const [field, values] of Object.entries(selections)) {
|
||||
for (const v of values) qs.append(field, v)
|
||||
}
|
||||
const url = projectId ? `/api/projects/${projectId}/rfcs` : '/api/rfcs'
|
||||
if (malformed) qs.set('malformed', 'true')
|
||||
const query = qs.toString()
|
||||
let base
|
||||
if (projectId && collectionId) {
|
||||
base = `/api/projects/${projectId}/collections/${collectionId}/rfcs`
|
||||
} else {
|
||||
base = projectId ? `/api/projects/${projectId}/rfcs` : '/api/rfcs'
|
||||
}
|
||||
const url = query ? `${base}?${query}` : base
|
||||
return jsonOrThrow(await fetch(url))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user