conceptadev / conceptadev/rockets

docs: update documentation so new projects can start from it (gaps found in a multi-tenant evaluation)

Open
#118 0 comments 0 reactions 0 assignees View on GitHub
documentation
Dominant language
TypeScript
Stars
1
Forks
2
Avg merge
2d 10h
Merged PRs (30d)
23

Description

### Use case

We evaluated Rockets (`1.0.0-alpha.8`, HEAD `f229356`, pinned to `@concepta/nestjs-*` `8.0.0-alpha.12`) as the base for a new multi-tenant ERP by building a territory-isolation spike and a CRUD resource with a shared 22-test contract, using only the documentation first. Build and tests are green, and most of the surface worked from the docs. But several points could only be resolved by reading the source, a few documented statements do not match the code, and the known limitations that matter for a real project are not written down anywhere.

For Rockets to be usable for new projects from the docs alone before publication, the items below should be addressed.

### Proposal

#### 1. Documentation that does not match the code

- [ ] **Token claims in `Actor.metadata`.** rockets-core README "Custom row scoping (group / dealer / tenant)" says to put the tenant in `Actor.metadata`, sourced from a token claim. `ActorOverlay` (`packages/rockets-core/src/infrastructure/interceptors/actor.overlay.ts`) publishes only `{ id, type }`, so no code path copies adapter data into `metadata` and `resolve(actor)` never sees the claim. Either change the code (preferred) or document the required app interceptor and its ordering.
- [ ] **Versions.** README "Versions" still says the v8 modules are pinned to `8.0.0-alpha.10`; `package.json` pins `8.0.0-alpha.12`.
- [ ] **Minimum `defineResource` example.** CONFIGURATION.md §4 "Minimum" is not runnable: without `dto` / response schemas every route returns 500 at serialization. Make the minimum example complete.

#### 2. Behaviour that is only discoverable in the source

- [ ] `TenantScopeHook` covers `beforeFindAndCount` and `beforeFindOne` only, not `beforeFind`; a hand-written service calling `repo.find({ ctx })` is not scoped. State this next to the hook.
- [ ] `public: true` on a resource still passes the global guard; an unauthenticated API also needs `enableGlobalGuard: false`.
- [ ] `RocketsCoreExceptionsFilter` must be registered per app, otherwise hook rejections (403/400/401 from `TenantStampHook`) surface as 500.
- [ ] Swagger defaults to `/api` and is not mounted by core: document `swagger.settings.path` plus `SwaggerUiService.setup(app)`.
- [ ] List limits: `defineResource` has no limit option and `CrudLimit` / `CrudMaxLimit` are not re-exported; document the `decorators` workaround and the extra dependency (or re-export them).
- [ ] `txCtx.trx.getOrStart(key)` is the only way to reach the transaction client and is untyped.

#### 3. Missing guides

- [ ] **Build a multi-tenant app end to end:** external identity provider token → claims → `TenantScopeHook` + `TenantStampHook` → `acl` + `CanAccess` → `routePolicy` → OpenAPI contract, as one runnable walkthrough, with `examples/sample-server` referenced as the reference project.
- [ ] **Database row-level security with Rockets:** one transaction per request with `SET LOCAL` / `set_config` on the transaction client, for HTTP and for background jobs. Today `SET LOCAL`, `set_config`, RLS and "row level" have zero hits in READMEs, CONFIGURATION.md and `packages/*/src`.
- [ ] **External JWKS / OIDC adapter** (Entra ID, Auth0) with issuer, audience, tenant and key-rotation checks, next to the Firebase adapter.
- [ ] **Unrestricted access for an admin role on the same endpoint:** the hook forbids returning every tenant id as "no restriction", and the README routes admins to a separate surface; document the supported pattern.
- [ ] **Starting a new project:** install from git with `resolutions`, the stale `*.tsbuildinfo` gotcha when copying the repo, and `workspace:^` in packed tarballs.

#### 4. Known limitations to document until fixed

Found with the shared contract tests; each belongs in a "Known limitations" section with the workaround.

- [ ] `?includeDeleted=1` lists and reads soft-deleted rows for any caller; it is even documented in the generated OpenAPI.
- [ ] 500 instead of 400 on an unknown sort field, an invalid enum filter, `?select=` and a non-uuid id (top-level resources do not type `id` as uuid; only sub-resources do).
- [ ] `contains` is case-sensitive on Postgres (`LIKE`), and `%` / `_` are not escaped; the only fix patches a non-public method and needs an unexported enum value (`'contains'`, not `'$contains'`).
- [ ] Stale `If-Match` returns 409 by design; document how to map it to 412 if a contract needs it.
- [ ] Generated OpenAPI documents create and delete as 200 (actual 201 and 204) and omits 404 on read.
- [ ] Jobs, idempotency and rate limit ship in-memory adapters only.
- [ ] Storage supports filesystem and S3 only.
- [ ] Hooks are skipped when `ctx` is omitted (CONFIGURATION.md §8a); pair the warning with the RLS guide above.

Upstream issues that would remove some of these from Rockets: conceptadev/nestjs-modules#473 (fail-closed tenant scope hook), conceptadev/nestjs-modules#474 (reject writes that carry another tenant), conceptadev/nestjs-modules#475 (boot-time check for unguarded routes).

#### 5. Structure

- [ ] CONFIGURATION.md section numbers are out of order (§5a and §5b appear after §6c); renumber and add a table of contents that matches.
- [ ] One "where to look" page: README (overview and get started), CONFIGURATION.md (reference), package READMEs (package-specific) — today the same topic is split across all three.

Contributor guide

Open the contributing guide

Research direction

Start by comparing README, CONFIGURATION.md, package READMEs, package.json, and examples/sample-server against the evaluation findings; inspect actor.overlay.ts where the issue names it. Run the existing build and contract tests while checking each documented behavior. Done means the identified mismatches, workflows, limitations, project-start steps, and documentation structure are covered by accurate, runnable guidance.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
documentation
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.