Repository navigation
EN Projects and JSON
English · Türkçe · Languages / Diller
Scope: JSON API Forge 0.5.1 · Source review: 17 September 2026 · Language: English
| Path | Purpose |
|---|---|
app/<Project>/app.json |
Project manifest; an alternative manifest filename is also supported in the loader |
app/<Project>/config/*.json |
Direct child JSON fragments, merged alphabetically |
app/<Project>/hooks/*.py |
Explicitly imported Python code |
app/<Project>/graphs/*.forgegraph.json |
Editor design documents |
app/<Project>/data/ |
Project-local data files |
.env in the deployment root |
Process settings and application secrets |
Reserved roots such as app/config, app/data, app/hooks, app/plugins and app/schemas are not treated as applications. An empty directory alone is not a project. Slugs and API prefixes must not conflict with other enabled projects.
{
"slug": "notes",
"name": "Notes",
"version": "1.0.0",
"api_prefix": "/api/notes/v1",
"enabled": true,
"docs_enabled": true,
"audit_enabled": true
}Required fields and defaults are in the complete project reference. project_dir is runtime metadata; do not embed machine-specific absolute paths in portable configuration.
Fragments load alphabetically. Equal-width prefixes such as 10-, 20- and 40- make ordering explicit.
| Data | Merge behavior |
|---|---|
| Objects/dictionaries | Recursive field merge |
| Scalars or type changes | Later value replaces the earlier value |
resources, mongo_resources, operations, data_sources
|
Append to the list |
dependencies, custom_endpoints, event_channels, webhook_docs
|
Append to the list |
| All other lists | Later list replaces the earlier list |
For example, a later cors_origins: [] clears the previous origins, while resources: [] does not remove earlier resources. Adding the same resource path a second time does not update the earlier definition; it can create a conflict. Edit the original definition instead.
This distinction matters for security: replacing an allowlist with a narrower list must not retain the old broad values. The append-list entries above were checked directly against _APPEND_LIST_KEYS.
{
"databases": {
"primary": {
"url": "$env:NOTES_DATABASE_URL:-sqlite+aiosqlite:///./data/notes.db"
}
}
}The entire string must use $env:NAME or $env:NAME:-default. ${NAME} and $env: embedded in a larger string are not equivalent. Resolution checks the process environment, then loaded dotenv values, then an optional default. With neither a value nor a default, resolution can return None; subsequent type validation determines the error. An empty string is distinct from a missing variable.
Environment resolution is not a general JSON/bool/int parser. The result still passes through the target model's type rules. Do not provide public default values for secrets.
project.schema.json describes the merged project; manifest.schema.json the manifest; fragment.schema.json its fragments; and editor-graph.schema.json graph documents. $schema helps editors and does not replace runtime semantic validation. A valid fragment can still belong to an invalid merged project.
pattern and patternProperties use a linear-time regex engine with a 512-character pattern limit. Look-around and backreferences are unsupported. A string request parameter with a pattern gets max_length=16384 unless a smaller bound is set.
JSON does not allow comments or trailing commas. Run forge validate after changes, then inspect forge routes and OpenAPI. See the full reference index.
This page describes the behavior at the pinned commits below. Recheck these contracts when upgrading.
main/framework/config.pymain/framework/safe_regex.pymain/schemas/project.schema.jsonmain/docs/36-Configuration-Merge-Semantics.md