10. Known Issues & Limitations
This page lists behaviours of the current code that differ from what the configuration format suggests. Each item gives the location in the code and a workaround. Check this page before relying on one of these features.
10.1 Settings never dispatch
- Where:
src/module/common_v2/helper/excute.ts(executeSetting) readssetting.Case; the shipped settings usecase. - Effect: no setting ever selects a policy. Selection falls back to
piority+condition_context. - Workaround: use
condition_context+piority(Recipe 8.6). Or fix the dispatcher, e.g.const cases = setting.case || setting.Case || [];.
10.2 @options:resource_id is never populated
- Where: no code path sets
options.resource_id(seesrc/module/common_v2/common.ts). - Effect: the variable stays unresolved in
policy-team-read-basic/-full,policy-tenant-read-basic/-full,setting-team-readandsetting-tenant-read. Their context queries return nothing, so the reads they govern return no data. - Workaround: detail reads already carry the id as an
_idfilter from the URL. Write conditions that do not depend onresource_id, for example_id=in.@context:my_memberships:data:team_idwith a membership query keyed onuser_idonly.
10.3 Team roles are not assigned automatically
- Where: roles come from the JWT's
role_name(src/module/common_v2/common.ts,buildRoles). Nothing in this build derivesteam_admin,team_managerorteam_userfromuser_teammemberships. - Effect: policies for those roles only apply when the token itself carries such a role, e.g. issued by an external SSO provider.
- Workaround: issue tokens with those role names, or rewrite the policies for the roles your tokens actually carry. Their membership checks (
data+@context) still work.
10.4 Super administrators and @context filters
- Where:
src/module/common_v2/helper/builder.ts(super-admin branch). - Effect: super admins reuse the
conditionof the top-priorityadminpolicy, including its filters, but itsdataqueries are not run. A filter like_id=in.@context:…stays unresolved and matches nothing. - Workaround: keep
admin-role policies free of@contextfilters.
10.5 rel(*) probably returns only _id
- Where:
src/core_v2/query/converter.ts.*inside parentheses is treated as a field literally named*. - Effect:
templates(*),groupfield_id(*),member(*), … may populate only the related_id. This conclusion comes from reading the code; verify it on your data. - Workaround: use
rel()(empty parentheses) for the whole document, or list the fields:rel(title,slug).
10.6 Joined users never include email
- Where:
src/core_v2/adapters/mongodb/converters/join-converter.ts. - Effect:
password,email,roleandrole_systemare always stripped from joineduserdocuments, even when selected (e.g.created_by(username,full_name,email)). - Workaround: query
/api/v1/userdirectly when an email is really needed.
10.7 form on a policy drops the submitted body
- Where:
src/module/common_v2/helper/builder.ts,formbranch. - Effect: the filtered body is built from form-setting defaults only, so the client's values are discarded.
- Workaround: do not use
formon policies until this is fixed; usecondtion_bodyand the entity'sjson_schemainstead.
10.8 Flags and fields that look enforced but are not
| Field | Reality |
|---|---|
policy.is_active, setting.is_active | Not checked. Remove the file or the role to disable |
resource.action[] | Not checked. Policies are the only gate |
json_schema.properties.<field>.readonly / require | UI only. Use the root required[] array and policy rules |
entity.unique_keys | No index is created |
entity.use_seo_path | SEO paths follow use_slug |
"false" (string) as a use_* value | Counts as enabled. collection, cron-job, rule and role ship with use_sync_relationship_multiply_language: "false" |
10.9 Validation quirks
PATCHis not partial for validation: core updates validate asPUT, sorequiredfields must be present on every update.- Lower-case
datetimewidget: not validated as a date; stored as a plain string. UsedateTimefor format checking. datewidget: mapped to thedate-timeformat, which requires a time part. Date-only values may be rejected.functionwidget overridestype: it always validates as a string.api-configfields declared asobjectwith this widget (endpoint_map,extra_headers,request_template) may reject object values.not=(single condition)produces a top-level$not, which MongoDB rejects. Use the inverse operator (neq,nin,not_contains, …).
10.10 Tenant header is a partition key, not an authorization check
- Where:
src/module/common_v2/common.ts. Thex-tenant-idvalue is not compared withTENANTor with the user's memberships. - Effect: within one deployment, any authenticated caller whose policy allows a resource can read other
tenant_idpartitions by changing the header. - Workaround: run one deployment (one MongoDB database) per tenant, as described in Deployment §9.4, or validate the header in a proxy.
10.11 Code records run unsandboxed
- Where:
src/module/common_v2/helper/excute.ts(executeCode) runs records withnew AsyncFunction(...)in the server process. - Effect: whoever can write
coderecords can run arbitrary code. The shippedpolicy-code-admingrants theadminrole full CRUD oncode. - Workaround: restrict the
coderesource tosuper_admin, and review code records like source code.
10.12 Deployment
json/is required at runtime. Startup wipes the Redis schema keys and reloads them fromjson/, butDockerfile.single-tenantdoes not copyjson/into the image. Mount it. See Deployment §9.1.- Hand edits need a restart. The file watcher is disabled; only API edits are synced live.
- Context queries return at most 20 rows unless their
condtionsetslimit. scripts/seed-e2e-user.tswrites to the databasemangoadsregardless ofMONGODB_URL.- SQL adapters. Comments still mention SQLite, but only the
mongodbandrestadapters exist.