Add a `/api/v1/meta` discovery endpoint describing limits, tiers, and capabilities
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 22/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- nodejs, typescript
Research direction
Start by reading how the rate-limit tiers are resolved (resolveRateLimitTierFromRole and the RATE_LIMIT_* values in env.validation.ts), then the module registry in src/modules/ (module-registry.service.ts, tenant-module-state.entity.ts). The new GET /api/v1/meta endpoint should read from those same sources, and a test must show it matches the enforcement path and that no secret from .env.example appears in the response. Done means the documented shape is returned, tenant module state is reflected when authenticated, and the endpoint is in docs/openapi.json.
Written by the indexing model from the issue text.
Description
Problem
Clients have no way to discover server capabilities at runtime. Everything about rate limits, tiers, and feature flags has to be hardcoded by the integrator.
The information exists but is scattered:
- Rate-limit tiers:
RATE_LIMIT_FREE_PER_MINUTE,RATE_LIMIT_PAID_PER_MINUTE,RATE_LIMIT_ENTERPRISE_PER_MINUTE(README lines 239-241) resolveRateLimitTierFromRole(...), used by the auth services to set thetierclaim- Feature flags in
env.validation.ts(507 lines) and the.envtemplates - The module registry at
src/modules/—module-registry.service.tswithmodule-manifest.schema.json,module.entity.ts,tenant-module-state.entity.ts, andmodule-lifecycle.loader.ts. This is a full plugin system that presumably knows which modules are enabled, but exposes it only throughmodule-registry.controller.tsfor admins.
docs/module-registry.md documents that system.
Why it matters
An integrator cannot answer "what is my current rate limit?" or "is the simulator module enabled for my tenant?" without reading the source or hardcoding values that drift. The tier is already computed into the JWT (tier: resolveRateLimitTierFromRole(user.role) in enhanced-auth.service.ts:561), so the client already half-knows — but only after login, and only its own tier, not the enforced numbers.
For a platform with a plugin system, a capability endpoint is what makes the extension model usable by third parties.
Suggested Direction
- Add
GET /api/v1/metareturning:{ "apiVersion": "v1", "rateLimits": { "tier": "paid", "perMinute": 120, "windowMs": 60000 }, "features": { "simulator": true, "graphql": true, "webhooks": false }, "limits": { "maxUploadBytes": 52428800, "maxPageSize": 100 }, "modules": [ { "id": "portfolio", "status": "enabled" } ] } - Derive every value from the same source the enforcement code uses. Read the values from
ConfigServiceand from the module registry's resolved state — do not duplicate the numbers, or this endpoint will lie. - Scope by tenant and tier, not just global. The module registry already models per-tenant state (
tenant-module-state.entity.ts), so a tenant with a module disabled should see that reflected. This is the main reason to build it rather than hardcoding a static response. - Keep it unauthenticated but non-sensitive for the global parts, and require auth for tenant-specific parts. Verify nothing secret leaks — no DSNs, no internal URLs, no signing config.
- Document it in
docs/and add@ApiResponsedecorators so it appears in the generated SDKs.
Constraints
- The single most important constraint: this endpoint must not become a place where config values leak. Audit every field against the actual secret values in
.env.examplebefore shipping. - Feature flags should reflect effective state, including tenant overrides, not raw env booleans.
- Cache the response briefly (or compute once at startup) so it is not a hot path that reads config on every request.
- Do not let it become an internal-config dump; if a value is not useful to a client, leave it out.
Acceptance Criteria
-
GET /api/v1/metaexists and returns the documented shape. - Values come from the same config the enforcement path reads, verified in a test.
- Tenant-specific module state is reflected for an authenticated tenant.
- No secret values (keys, DSNs, internal hosts) appear in the response — assert this in a test.
- The endpoint appears in
docs/openapi.jsonwith@ApiResponsedecorators. -
docs/module-registry.mdand the README reference it.
- Dominant language
- TypeScript
- Stars
- 7
- Forks
- 55
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 5
Getting set up
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from SourceXXL/alian_structure-api
-
good first issue help wanted security
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SourceXXL/alian_structure-api#266 ·
-
Parallelize the cache-warming loop in `cache-warming.service.ts` — warmers run strictly sequentiallyPossibly taken @syntaxsuuvam-spec claimed this 5 days ago. Opengood first issue performance
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SourceXXL/alian_structure-api#240 ·
-
documentation help wanted intermediate refactor
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
SourceXXL/alian_structure-api#215 ·
-
good first issue refactor tooling
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
SourceXXL/alian_structure-api#199 ·
-
help wanted intermediate refactor
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
SourceXXL/alian_structure-api#196 ·
All issues in SourceXXL/alian_structure-api
Similar issues
-
bnv-manager-v2: accept_invite creates the Mailcow domain admin before the commitPossibly taken @myOmikron claimed this today. Openbug ready-for-agent
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
platform:windows tool triaged wontfix
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
nicolettas-muggelbude/RechnungsFee#448 ·
Maintainers usually reply within 1 day
-
Android bug feature/error-tracking react-native team/error-tracking
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
PostHog/posthog-js#5310 · 1 comment ·
Maintainers usually reply within 1 day