feat(api): add endpoint to list community prefixes with pagination
Introduced a new GET endpoint `/v1/communities/{id}/prefixes` to retrieve unique prefixes associated with a community, including pagination support via cursor and limit parameters. Updated OpenAPI documentation to reflect this addition. Implemented backend logic in both PostgreSQL and in-memory storage to handle the new functionality, ensuring proper authorization checks and response formatting.
This commit is contained in:
@@ -1252,6 +1252,91 @@ func (p *Postgres) GetCommunity(tenantID, id string) (*store.Community, error) {
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
func (p *Postgres) ListCommunityPrefixes(tenantID, communityID, cursor string, limit int) ([]store.PrefixRow, string, bool, error) {
|
||||
if _, err := p.GetCommunity(tenantID, communityID); err != nil {
|
||||
return nil, "", false, err
|
||||
}
|
||||
if limit <= 0 {
|
||||
limit = 500
|
||||
}
|
||||
if limit > 5000 {
|
||||
limit = 5000
|
||||
}
|
||||
off := 0
|
||||
if cursor != "" {
|
||||
if n, err := strconv.Atoi(cursor); err == nil && n >= 0 {
|
||||
off = n
|
||||
}
|
||||
}
|
||||
ctx := context.Background()
|
||||
useSnap := prefixSnapshotTableExists(ctx, p.pool)
|
||||
var rows pgx.Rows
|
||||
var err error
|
||||
if useSnap {
|
||||
rows, err = p.pool.Query(ctx, `
|
||||
WITH latest AS (
|
||||
SELECT DISTINCT ON (module_id) id, prefix_snapshot_id
|
||||
FROM config_revision
|
||||
WHERE tenant_id = $1::uuid AND module_id IS NOT NULL
|
||||
ORDER BY module_id, created_at DESC
|
||||
),
|
||||
combined AS (
|
||||
SELECT rmp.prefix::text AS prefix, COALESCE(rmp.source, '') AS source
|
||||
FROM revision_materialized_prefix rmp
|
||||
JOIN latest l ON l.id = rmp.revision_id
|
||||
WHERE l.prefix_snapshot_id IS NULL AND rmp.community_id = $2::uuid
|
||||
UNION
|
||||
SELECT psr.prefix::text, COALESCE(psr.source, '')
|
||||
FROM prefix_snapshot_row psr
|
||||
JOIN latest l ON l.prefix_snapshot_id = psr.snapshot_id
|
||||
WHERE l.prefix_snapshot_id IS NOT NULL AND psr.community_id = $2::uuid
|
||||
)
|
||||
SELECT prefix, source FROM combined
|
||||
ORDER BY prefix
|
||||
LIMIT $3 OFFSET $4`, tenantID, communityID, limit+1, off)
|
||||
} else {
|
||||
rows, err = p.pool.Query(ctx, `
|
||||
WITH latest AS (
|
||||
SELECT DISTINCT ON (module_id) id
|
||||
FROM config_revision
|
||||
WHERE tenant_id = $1::uuid AND module_id IS NOT NULL
|
||||
ORDER BY module_id, created_at DESC
|
||||
)
|
||||
SELECT DISTINCT rmp.prefix::text, COALESCE(rmp.source, '')
|
||||
FROM revision_materialized_prefix rmp
|
||||
JOIN latest l ON l.id = rmp.revision_id
|
||||
WHERE rmp.community_id = $2::uuid
|
||||
ORDER BY 1
|
||||
LIMIT $3 OFFSET $4`, tenantID, communityID, limit+1, off)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, "", false, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var all []store.PrefixRow
|
||||
comm := communityID
|
||||
for rows.Next() {
|
||||
var pr store.PrefixRow
|
||||
if err := rows.Scan(&pr.Prefix, &pr.Source); err != nil {
|
||||
continue
|
||||
}
|
||||
pr.CommunityID = &comm
|
||||
all = append(all, pr)
|
||||
}
|
||||
more := len(all) > limit
|
||||
if more {
|
||||
all = all[:limit]
|
||||
}
|
||||
next := ""
|
||||
if more {
|
||||
next = fmt.Sprintf("%d", off+limit)
|
||||
}
|
||||
if len(all) == 0 {
|
||||
return nil, "", false, nil
|
||||
}
|
||||
return all, next, more, nil
|
||||
}
|
||||
|
||||
func (p *Postgres) CreateCommunity(tenantID string, in *store.Community) (*store.Community, error) {
|
||||
if in == nil {
|
||||
return nil, store.ErrInvalidInput
|
||||
|
||||
Reference in New Issue
Block a user