Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions docs/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ GoForj has two main configuration layers:
- `.goforj.yml` for project rendering and development workflow.
- environment variables for runtime behavior.

This page defines accepted keys and values. Start with [Configuration](/getting-started/configuration) for the first working change, or [forj dev](/developer-tools/forj-dev) for the build, SPA, and runtime loop. The lifecycle examples below illustrate configuration shapes rather than a second development tutorial.
This page is a lookup for accepted keys and values. It does not replace the task-oriented setup guides or define production runtime policy. Start with [Configuration](/getting-started/configuration) for the first working change, or [forj dev](/developer-tools/forj-dev) for the build, SPA, and runtime loop. The lifecycle examples below illustrate configuration shapes rather than a second development tutorial.

## `.goforj.yml`

Expand Down Expand Up @@ -70,7 +70,17 @@ Compiled defaults fill values that remain unset after normal file-backed loading

Compiled overrides take precedence over process and file-backed values. A compiled `APP_ENV` override selects its matching environment file and remains authoritative after loading.

Use these options for controlled packaging workflows. Prefer environment files and process environment for normal local development. See [CLI Reference](/reference/cli#framework-command-options) for the complete `forj build` option list.
These values become part of the artifact contract:

| Build input | Runtime can replace it? | Appropriate use |
| --- | --- | --- |
| `--env-defaults KEY=value` | Yes, with a process or file-backed value | A non-secret fallback that should travel with this artifact. |
| `--env-overrides KEY=value` | No; rebuild the artifact to change it | A non-secret packaging constraint that must remain fixed for every process using this artifact. |
| Process environment or deployment configuration | Yes, when the deployment changes it | Environment-specific endpoints, credentials, ports, scaling, retention, and operational policy. |

Do not compile secrets into either channel. Compiled values can be recovered from or observed with the artifact, and an override prevents the deployment platform from correcting that key at startup. Treat a change to a compiled default or override like any other artifact change: rebuild, identify, test, and promote the new binary or image.

Most production configuration remains deployment-owned. Use the deployment platform's environment, configuration, and secret delivery mechanisms for values that differ by environment or must rotate independently of a build. Prefer environment files and process environment for normal local development. See [CLI Reference](/reference/cli#framework-command-options) for the complete `forj build` option list and [Deploy an App](/operations/deployment-basics#keep-configuration-outside-the-artifact) for the production handoff.

## Development Tasks

Expand Down Expand Up @@ -334,6 +344,8 @@ Catalog dependencies are resolved in memory by the renderer. For example, metric

## Module Replaces

`render.module_replaces` manages local Go module replacements during Project rendering. On render, GoForj applies each entry to `go.mod` with `go mod edit -replace` and records which module paths it owns in `.goforj.module_replaces.json`. When an owned entry is later removed from `.goforj.yml`, the next render drops that replacement without touching unrelated replacements that a maintainer added directly to `go.mod`.

Use paths that are stable from the Project root. For local sibling repositories, prefer a relative path:

```yaml
Expand All @@ -342,7 +354,7 @@ render:
github.com/goforj/web: ../web
```

Do not use container-specific absolute paths; they only work in one local environment.
This is a development and rendering aid, not runtime dependency configuration. Do not use container-specific or machine-specific absolute paths in shared Project configuration; they only work in one local environment. Before a release build, confirm that `go.mod` does not resolve production dependencies through unintended local replacements.

## Related Pages

Expand Down
15 changes: 9 additions & 6 deletions docs/reference/env-vars.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Variables for components that are not selected are not rendered and have no gene
| `APP_DIAG_TOKEN` | Generated when Web API is rendered | Bearer token for protected diagnostic commands and endpoints. |
| `APP_SHUTDOWN_TIMEOUT` | `30s` | Root graceful-shutdown budget. |
| `APP_VERSION` | Empty | Deployment version reported to Lighthouse. |
| `APP_REVISION` | Empty | Immutable deployment revision used by framework-managed metrics discovery. Keep it bounded and low-cardinality, such as a commit SHA. |
| `APP_INSTANCE_ID` | Empty | Explicit process or replica identity reported to Lighthouse. When empty, Lighthouse identifies the instance by hostname, then its generated agent ID. |
| `APP_INSTANCE_KIND` | Empty | Optional deployment-specific instance classification reported to Lighthouse. |
| `APP_MODE` | Empty | Optional runtime mode used in generated log labels. Runtime commands normally set their own context. |
Expand All @@ -64,6 +65,8 @@ Variables for components that are not selected are not rendered and have no gene
| `APP_LOG_DEDUPE_WINDOW_MS` | `1200` | Dedupe window in milliseconds. |
| `APP_LOG_DEDUPE_BURST` | `2` | Matching messages emitted before suppression begins within a window. |
| `APP_LOG_DEDUPE_SUMMARY_EVERY` | `1000` | Suppressed occurrences between summary messages. |
| `APP_LOG_REDACT_KEYS` | Empty | Comma-separated application-specific field names to redact in addition to mandatory secret-bearing names. |
| `APP_LOG_REDACT_MESSAGE_PATTERNS` | Empty | JSON array of regular expressions replaced with `[REDACTED]` before output and sink delivery. Invalid JSON or expressions fail during logger construction. |

See [Logging](/operations/logging) for event shape, output modes, and sensitive-data guidance.

Expand Down Expand Up @@ -196,7 +199,7 @@ Framework-owned instrumentation toggles all default to `true` when their compone
| `METRICS_DATABASE_ENABLED` | Database operations. |
| `METRICS_AUTH_ENABLED` | Auth flows. |
| `METRICS_SCHEDULER_ENABLED` | Scheduler operations. |
| `METRICS_MONITORING_ENABLED` | Monitoring metrics in the generated demo App. |
| `METRICS_MONITORING_ENABLED` | Monitoring metrics in the demo App. |

See [Metrics](/operations/metrics) for endpoints, labels, and scrape topology.

Expand Down Expand Up @@ -249,7 +252,7 @@ The default connection uses `DB_<SUFFIX>`. Named connections use `DB_<NAME>_<SUF
| `MYSQL_MAX_OPEN_CONNECTIONS` | Driver default | Compatibility fallback for `DB_MAX_OPEN_CONNECTIONS`. Prefer the `DB_` key. |
| `DB_CONNECTIONS`, `DB_SUPPORTED_CONNECTIONS` | Empty | Legacy comma-separated connection-name discovery used by backup commands. New Apps discover `DB_<NAME>_*` directly. |

The renderer supplies usable local MySQL or Postgres connection values when those services are selected. Active driver values also accept the compatibility aliases `sqlite3`, `mariadb`, and `postgresql`; supported-driver lists and new configuration should use the canonical names above. See [Database Strategy](/data/database-strategy) and [Database Shell](/data/database-strategy#shell-options).
The renderer supplies usable local MySQL or Postgres connection values when those services are selected. Active driver values also accept the compatibility aliases `sqlite3`, `mariadb`, and `postgresql`; supported-driver lists and new configuration should use the canonical names above. See [Database Connections](/data/database-strategy) and [Database Shell](/data/database-strategy#shell-options).

## Shared Redis and NATS

Expand Down Expand Up @@ -481,8 +484,8 @@ See [Mail](/applications/mail) for local delivery, named mailers, and production
| Variable | Default | Purpose |
| --- | --- | --- |
| `SCHEDULER_COMMAND_TIMEOUT` | `10m` | Maximum runtime for a command launched by a scheduled task. |
| `SCHEDULER_SUBPROCESS_SHUTDOWN_TIMEOUT` | `APP_SHUTDOWN_TIMEOUT`; rendered as `90s` | Grace period for scheduler-owned subprocesses. |
| `QUEUE_SHUTDOWN_TIMEOUT` | `10s` | Queue shutdown budget, also listed with Queue settings. |
| `SCHEDULER_SUBPROCESS_SHUTDOWN_TIMEOUT` | `APP_SHUTDOWN_TIMEOUT` | Grace period for scheduler-owned subprocesses, capped by the remaining App shutdown budget. |
| `QUEUE_SHUTDOWN_TIMEOUT` | `10s` | Queue shutdown budget, capped by the remaining App shutdown budget and also listed with Queue settings. |

## Local Observability

Expand Down Expand Up @@ -550,7 +553,7 @@ S3-backed `STORAGE_<NAME>_*` resources can be inventoried as backup inputs, but

See [Make Command Shared Options](/reference/make-commands#shared-options) and [forj dev](/developer-tools/forj-dev).

## Generated Demo App
## Demo App

These controls exist only when the demo monitoring and Lighthouse benchmark surfaces are rendered.

Expand All @@ -572,6 +575,6 @@ These controls exist only when the demo monitoring and Lighthouse benchmark surf

- [Configuration](/getting-started/configuration)
- [Driver Selection](/data/driver-selection)
- [Generated Components](/core/code-generation)
- [Code Generation](/core/code-generation)
- [Named Resources](/core/named-resources)
- [Production Hardening](/security/production-hardening)
4 changes: 2 additions & 2 deletions docs/reference/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Likely causes:

Start with:

- [Generated Components](/core/code-generation)
- [Code Generation](/core/code-generation)
- [Generation Commands](/reference/generation-commands)
- [Configuration Reference](/reference/configuration)

Expand All @@ -40,7 +40,7 @@ Start with:
- [Providers](/core/dependency-injection#providers)
- [Wiring Recipes](/developer-tools/wiring-recipes)
- [Reading Wire Errors](/developer-tools/reading-wire-errors)
- [Generated Files](/reference/generated-files)
- [File Ownership](/reference/generated-files)

## Runtime Readiness Errors

Expand Down
118 changes: 70 additions & 48 deletions docs/reference/generated-files.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,82 @@
---
title: Generated Files
description: Lookup reference for common generated files and ownership boundaries in GoForj Projects.
title: File Ownership
description: Identify which GoForj Project files belong to your application, the Framework, generators, or build tooling.
---

# Generated Files

Generated files are not all owned the same way.

Check file headers and local package READMEs before editing.

## Common Files and Directories

| Path | Purpose |
| --- | --- |
| `.goforj.yml` | Project render and development contract. |
| `.env` | Local runtime environment defaults. |
| `cmd/app/main.go` | Default app binary entrypoint. |
| `cmd/<app>/main.go` | Additional app binary entrypoint. |
| `cmd/<app>/frontend/` | Frontend source and embedded build output for an app with Web UI. |
| `app/commands.go` | Default app command exposure. |
| `app/lifecycle.go` | Default app lifecycle hooks. |
| `app/routes.go` | Default app route exposure. |
| `app/schedules.go` | Default app schedule exposure. |
| `app/wire/wire.go` | Default app Wire injector definitions. |
| `app/wire/wire_gen.go` | Generated Wire output. Do not edit by hand. |
| `app/<app>/...` | Additional app composition files. |
| `app/<app>/wire/...` | Additional app Wire graph. |
| `internal/runtime/apps.go` | App metadata derived from Project configuration and deterministic runtime defaults. Do not edit by hand. |
| `internal/caches/*_gen.go` | Generated cache accessors and config when Cache is enabled. |
| `internal/storages/*_gen.go` | Generated storage accessors and config when File Storage is enabled. |
| `internal/queues/*_gen.go` | Generated queue accessors and config when Background Jobs is enabled. |
| `internal/events/*_gen.go` | Generated event bus accessors and config when Events is enabled. |
| `internal/database/*_gen.go` | Generated DB accessors and config when a database component is enabled. |
| `build/api_index.json` | Default app API index output. |
| `build/api_index.diagnostics.json` | Default app API index diagnostics. |
| `build/openapi.json` | Default app OpenAPI output. |
| `build/.webindex-artifacts.lock` | Publication lock coordinating the default app artifact set. |
| `build/<app>/api_index.json` | Per-app API index output. |
| `build/<app>/api_index.diagnostics.json` | Per-app API index diagnostics. |
| `build/<app>/openapi.json` | Per-app OpenAPI output. |
| `build/<app>/.webindex-artifacts.lock` | Publication lock coordinating one per-app artifact set. |
| `.goforj/backups/<set>/manifest.json` | Local backup set inventory. |
| `.goforj/backups/<set>/checksums.txt` | Checksums for backup artifacts. |
# File Ownership

Files in a GoForj Project have different owners. Some are normal application code, some are extension points created once, and some are refreshed from configuration or build inputs.

Use this page when deciding whether to edit a file or change the input that creates it. File headers remain authoritative when a specific file says `DO NOT EDIT`.

## Application and App Composition

| Path | Owner | Created or refreshed by | Edit? |
| --- | --- | --- | --- |
| `internal/<domain>/...` | Application | You and `forj make:*` | Yes |
| `app/commands.go` | App | Initial render and make commands | Yes |
| `app/lifecycle.go` | App | Initial render | Yes |
| `app/routes.go` | App | Initial render and controller commands | Yes |
| `app/schedules.go` | App | Initial render | Yes |
| `app/wire/inject_*_app.go` | App | Initial render and make commands | Yes |
| `app/<app>/...` | Additional App | Same conventions as the default App | Follow the matching default-App file |
| `migrations/` | Application | `forj make:migration` and application changes | Yes |

## Framework-Managed Project Files

These files implement the selected Project configuration. Change `.goforj.yml`, component selection, or the owning framework template instead of treating them as durable extension points.

| Path | Created or refreshed by | Edit? |
| --- | --- | --- |
| `cmd/app/main.go` | `forj render` | No; use App registration files |
| `cmd/<app>/main.go` | `forj render` | No; use that App's registration files |
| `app/root_cmd.go` | `forj render` | No |
| `app/wire/app.go`, `app/<app>/wire/app.go` | `forj render` | No; add providers through `_app.go` files |
| `app/wire/wire.go` | `forj render` | Avoid; compose custom sets through `_app.go` files |
| `app/wire/inject_*.go` without `_app` | `forj render` | No |
| `internal/runtime/apps.go` | `forj render` | No |

## Generated Go Output

These filenames are the concrete outputs readers will encounter; they are not wildcard categories.

| Capability | Paths | Refreshed by | Edit? |
| --- | --- | --- | --- |
| Wire | `app/wire/wire_gen.go`, `app/<app>/wire/wire_gen.go` | `forj build` or Wire generation | No |
| Cache | `internal/caches/manager_gen.go`, `internal/caches/accessors_gen.go` | Cache generation during `forj build` | No |
| Storage | `internal/storages/manager_gen.go`, `internal/storages/accessors_gen.go` | Storage generation during `forj build` | No |
| Queues | `internal/queues/manager_gen.go`, `internal/queues/accessors_gen.go` | Queue generation during `forj build` | No |
| Events | `internal/events/manager_gen.go`, `internal/events/accessors_gen.go` | Event generation during `forj build` | No |
| Mail | `internal/mail/manager_gen.go`, `internal/mail/accessors_gen.go` | Mail generation during `forj build` | No |
| Database | `internal/database/connections_gen.go` | Database generation during `forj build` | No |

## Build and Operational Output

| Path | Purpose | Owner |
| --- | --- | --- |
| `build/api_index.json` | Default App API index | Build tooling |
| `build/api_index.diagnostics.json` | Default App indexing diagnostics | Build tooling |
| `build/openapi.json` | Default App OpenAPI document | Build tooling |
| `build/.webindex-artifacts.lock` | Coordinates publication of the default App artifact set | Build tooling |
| `build/<app>/...` | Equivalent artifacts for an additional App | Build tooling |
| `bin/app`, `bin/<app>` | Compiled App binaries | GoForj build pipeline |
| `cmd/<app>/frontend/dist/` | Built frontend embedded by a Web UI App | SPA build tooling |
| `.goforj/backups/<set>/manifest.json` | Backup set inventory | Backup tooling and operators |
| `.goforj/backups/<set>/checksums.txt` | Backup artifact checksums | Backup tooling and operators |

Project inputs such as `.goforj.yml`, `.env`, and `go.mod` are configuration rather than generated output. See [Configuration Reference](/reference/configuration) and [Environment Reference](/reference/env-vars) for their separate render, build, and restart boundaries.

## Ownership Rules

- Files marked `DO NOT EDIT` should be regenerated.
- Render-once files are App-owned extension points.
- `internal/` owns behavior; `app/` owns exposure.
- Framework-wide changes belong in GoForj templates or generators, not only in a rendered Project.
- API artifacts and publication locks are tool-owned. Backup sets are operator-owned data and must not be committed.
- Edit application behavior and App-owned `_app.go` extension points normally.
- Change inputs and regenerate files marked `DO NOT EDIT`.
- Keep Framework-wide fixes in GoForj templates or generators, not only in one rendered Project.
- Do not commit build output, publication locks, or operator backup sets unless a repository explicitly owns a checked artifact.

## Related Pages

- [Apps](/core/apps)
- [Generated Components](/core/code-generation)
- [Generated Extension Points](/core/code-generation#choose-a-safe-extension-point)
- [Project Structure](/getting-started/project-structure)
- [App Extension Points](/core/code-generation#choose-a-safe-extension-point)
- [Code Generation](/core/code-generation)
- [Backup and Restore](/operations/backups)
2 changes: 1 addition & 1 deletion docs/reference/generation-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,6 @@ Use `forj build` when unsure.
## Related Pages

- [Code Generation](/core/code-generation)
- [Generated Components](/core/code-generation)
- [Code Generation](/core/code-generation)
- [Make Command Reference](/reference/make-commands)
- [Rendered App Smoke Tests](/testing/rendered-app-smoke-tests)
2 changes: 1 addition & 1 deletion docs/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Use reference pages after you know the workflow and need exact command names, en
- [CLI Reference](/reference/cli)
- [Environment Reference](/reference/env-vars)
- [Configuration Reference](/reference/configuration)
- [Generated Files](/reference/generated-files)
- [File Ownership](/reference/generated-files)
- [Generation Commands](/reference/generation-commands)
- [Errors](/reference/errors)

Expand Down
15 changes: 5 additions & 10 deletions docs/reference/make-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,19 +342,14 @@ func NewSyncReportsJob(queues *queues.Manager) *SyncReportsJob {
return &SyncReportsJob{queues: queues}
}

// Queue creates a task and dispatches it to the selected queue.
// Add application inputs as arguments when defining the payload contract.
func (t *SyncReportsJob) Queue(ctx context.Context, name string) error {
var p SyncReportsJobPayload
// add your payload fields here
// p.User = name

payload, err := json.Marshal(p)
// Queue dispatches the typed payload to the selected queue.
func (t *SyncReportsJob) Queue(ctx context.Context, payload SyncReportsJobPayload) error {
data, err := json.Marshal(payload)
if err != nil {
return err
}
_, err = t.queues.WithContext(ctx).Dispatch(
queue.NewJob(SyncReportsJobTypeName).Payload(payload).OnQueue("billing"),
queue.NewJob(SyncReportsJobTypeName).Payload(data).OnQueue("billing"),
)
return err
}
Expand Down Expand Up @@ -856,7 +851,7 @@ Generate a model and repository helpers in an explicit package.
forj make:model invoices --package billing
```

The generator inspects the existing `invoices` table through the default database connection, so that connection must be available. Models use `--package` rather than `-d` because their placement follows database table ownership.
The positional argument is the exact name of an existing table. The generator inspects `invoices` through the default database connection, so that connection must be available. It does not create or migrate the table, and `make:model` does not select a named connection. The generated Go type and filename are singularized from the inspected table name; when an exact table is missing, the command may suggest an existing singular or plural variant. Models use `--package` rather than `-d` because their placement follows database table ownership.

```bash
forj make:model invoices --package billing --remove
Expand Down