Browse Source

chore(config): ignore local config and generated assets

softword 2 months ago
parent
commit
a7d4eff373

+ 2 - 0
.gitignore

@@ -57,6 +57,8 @@ src_minified
 import
 import
 /cfg/*.old
 /cfg/*.old
 /cfg/*.bin
 /cfg/*.bin
+/cfg/config.ini
+/assets/app/
 /fbtpl
 /fbtpl
 
 
 # webpack generated files
 # webpack generated files

+ 1 - 1
AGENTS.md

@@ -10,7 +10,7 @@ PHP 8.5+, Fat-Free Framework 3.9, MySQL via F3 `DB\SQL`, React 19, React Router
 `index.php` boots F3, loads `cfg/config.bin`, then discovers `PluginStrategy` subclasses from `src/`. `OpenMind\Api\Api` registers `/api/v1` routes; React in `ui/app` consumes them through a same-origin client.
 `index.php` boots F3, loads `cfg/config.bin`, then discovers `PluginStrategy` subclasses from `src/`. `OpenMind\Api\Api` registers `/api/v1` routes; React in `ui/app` consumes them through a same-origin client.
 
 
 ## Commands
 ## Commands
-`composer install` · `npm ci` · `npm run buildDev` · `npm run buildProd` · `npm run watch` · `npm pack` · `scripts/generate-config-bin.sh` (only when `cfg/config.bin` is absent). No test, lint, or deploy command is declared.
+`composer install` · `npm ci` · `npm run buildDev` · `npm run buildProd` · `npm run watch` · `npm pack`. Copy `cfg/config.ini.example` to the ignored `cfg/config.ini` and provision `cfg/config.bin` outside the repository. No test, lint, deploy, or configuration-generation command is declared.
 
 
 ## Code Style
 ## Code Style
 Use PSR-4 namespaces under `OpenMind\` and `Modules\`; match nearby PHP style and `declare(strict_types=1)` in modern API code. Preserve frontend import/component conventions; `.prettierrc` defines single quotes, semicolons, LF endings, and 200-column print width.
 Use PSR-4 namespaces under `OpenMind\` and `Modules\`; match nearby PHP style and `declare(strict_types=1)` in modern API code. Preserve frontend import/component conventions; `.prettierrc` defines single quotes, semicolons, LF endings, and 200-column print width.

File diff suppressed because it is too large
+ 0 - 0
assets/app/assets/index-BKCGXNjj.css


File diff suppressed because it is too large
+ 0 - 0
assets/app/assets/index-BpJqOKYq.js


+ 0 - 14
assets/app/index.html

@@ -1,14 +0,0 @@
-<!doctype html>
-<html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <link rel="icon" href="/phengine/assets/images/favicon.ico" />
-    <title>OM-Link</title>
-    <script type="module" crossorigin src="/phengine/assets/app/assets/index-BpJqOKYq.js"></script>
-    <link rel="stylesheet" crossorigin href="/phengine/assets/app/assets/index-BKCGXNjj.css">
-  </head>
-  <body>
-    <div id="root"></div>
-  </body>
-</html>

+ 0 - 11
assets/app/manifest.json

@@ -1,11 +0,0 @@
-{
-  "index.html": {
-    "file": "assets/index-BpJqOKYq.js",
-    "name": "index",
-    "src": "index.html",
-    "isEntry": true,
-    "css": [
-      "assets/index-BKCGXNjj.css"
-    ]
-  }
-}

+ 4 - 4
cfg/config.ini → cfg/config.ini.example

@@ -7,9 +7,9 @@ DEBUG=2
 ENCODING="UTF-8"
 ENCODING="UTF-8"
 HIGHLIGHT=false
 HIGHLIGHT=false
 JAR.expire={{time()+31536000}}
 JAR.expire={{time()+31536000}}
-DSN="mysql:host=localhost;port=3306;dbname=omlink"
-dbuser=root
-dbpass=Softwd1!
+DSN="mysql:host=<DATABASE_HOST>;port=<DATABASE_PORT>;dbname=<DATABASE_NAME>"
+dbuser="<DATABASE_USER>"
+dbpass="<DATABASE_PASSWORD>"
 MAX_RETRY_FOR_FAULT=10
 MAX_RETRY_FOR_FAULT=10
 DEV=true
 DEV=true
 AGGREGATE_TIMEOUT=500
 AGGREGATE_TIMEOUT=500
@@ -22,4 +22,4 @@ LOGO_CUSTOMER={{@BASEURL}}/assets/images/logo.png
 ICON_LOGOUT={{@BASEURL}}/assets/images/logout.png
 ICON_LOGOUT={{@BASEURL}}/assets/images/logout.png
 
 
 ; Select which customer class enable
 ; Select which customer class enable
-CUSTOMERNAME=omlink
+CUSTOMERNAME=<CUSTOMER_NAME>

+ 0 - 36
scripts/generate-config-bin.sh

@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-
-set -euo pipefail
-
-readonly PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
-readonly SOURCE_FILE="${PROJECT_ROOT}/cfg/config.ini"
-readonly TARGET_FILE="${PROJECT_ROOT}/cfg/config.bin"
-
-if [[ ! -f "${SOURCE_FILE}" ]]; then
-	printf 'Configuration source not found: %s\n' "${SOURCE_FILE}" >&2
-	exit 1
-fi
-
-if [[ -e "${TARGET_FILE}" ]]; then
-	printf 'Configuration target already exists: %s\n' "${TARGET_FILE}" >&2
-	exit 1
-fi
-
-cd "${PROJECT_ROOT}"
-php -r '
-require $argv[1];
-
-$config = file_get_contents($argv[2]);
-if ($config === false) {
-    fwrite(STDERR, "Unable to read the configuration source.\n");
-    exit(1);
-}
-
-$encodedConfig = (new \OpenMind\System\OMUtils())->Encrypt($config);
-if (file_put_contents($argv[3], $encodedConfig) === false) {
-    fwrite(STDERR, "Unable to write the configuration target.\n");
-    exit(1);
-}
-' 'vendor/autoload.php' 'cfg/config.ini' 'cfg/config.bin'
-
-printf 'Created %s\n' "${TARGET_FILE}"

+ 7 - 3
specs/commands.md

@@ -20,17 +20,21 @@ Read this when you need the supported setup, build, packaging, or configuration
 
 
 ## Configuration
 ## Configuration
 
 
+`cfg/config.ini.example` is the tracked placeholder template. Copy it to the ignored `cfg/config.ini`, provide deployment-specific values, and provision the required `cfg/config.bin` outside the repository. No configuration-generation script is tracked.
+
 | Purpose | Command | Constraint |
 | Purpose | Command | Constraint |
 |---|---|---|
 |---|---|---|
-| Generate runtime config | `scripts/generate-config-bin.sh` | Reads `cfg/config.ini`; fails if `cfg/config.bin` already exists. |
+| Migrate role catalog | `php scripts/migrate-role-catalog.php` | Creates missing role/inventory schema and seeds, then converts legacy serialized user roles; review and run manually against the intended database. |
 
 
-The application bootstrap requires `cfg/config.bin`. The script uses the project's reversible base64+gzip encoding; do not treat it as cryptographic protection. See [configuration/spec.md](configuration/spec.md).
+The application bootstrap requires `cfg/config.bin`. Its base64+gzip encoding is reversible and must not be treated as cryptographic protection. See [configuration/spec.md](configuration/spec.md).
 
 
 ## Database
 ## Database
 
 
 `omlink.sql` is a MySQL dump for the `omlink` database. It contains `DROP DATABASE`, `CREATE DATABASE`, and sample user data; review it before importing and never run it against a database that must be preserved.
 `omlink.sql` is a MySQL dump for the `omlink` database. It contains `DROP DATABASE`, `CREATE DATABASE`, and sample user data; review it before importing and never run it against a database that must be preserved.
 
 
+The role-catalog migration is an explicit data-changing CLI operation. It is not run during boot, has no automatic rollback, and must be reviewed before execution.
+
 ## Not Declared
 ## Not Declared
-No `test`, `lint`, `format`, development server, migration, deployment, or release command is declared in the tracked manifests. Do not invent one in project documentation; use the repository's established operational process.
+No `test`, `lint`, `format`, development server, deployment, or release command is declared in the tracked manifests. The role-catalog migration is the only documented schema/data migration command; use the repository's established operational process for all other database work.
 
 
 See [conventions-database.md](conventions-database.md) and [integrations/index.md](integrations/index.md).
 See [conventions-database.md](conventions-database.md) and [integrations/index.md](integrations/index.md).

+ 4 - 3
specs/configuration/spec.md

@@ -9,15 +9,16 @@ The application loads F3 globals from a runtime configuration file and provides
 
 
 | Artifact | Format | Role |
 | Artifact | Format | Role |
 |---|---|---|
 |---|---|---|
-| `cfg/config.ini` | Plaintext F3 INI | Source configuration, including globals such as DSN, cache, base URL, and feature values. |
+| `cfg/config.ini.example` | Plaintext F3 INI | Tracked template containing placeholders for deployment-specific values. |
+| `cfg/config.ini` | Plaintext F3 INI | Ignored local configuration copied from the template; it may contain credentials. |
 | `cfg/config.bin` | `base64(gzcompress(ini-text))` | Runtime configuration loaded by `index.php`. |
 | `cfg/config.bin` | `base64(gzcompress(ini-text))` | Runtime configuration loaded by `index.php`. |
 | `cfg/config.bin.old` | Previous `config.bin` bytes | Single backup created before an administrator save. |
 | `cfg/config.bin.old` | Previous `config.bin` bytes | Single backup created before an administrator save. |
-| `config.ini` | Plaintext INI | Minimal root-level configuration artifact; not the source used by the generator script. |
+| `config.ini` | Plaintext INI | Legacy root-level configuration artifact; not loaded by the application bootstrap. |
 
 
 ## Business Rules
 ## Business Rules
 - Startup must validate PHP 8.5+, require `cfg/config.bin`, decode it to a temporary file, apply F3 configuration, then remove the temporary file.
 - Startup must validate PHP 8.5+, require `cfg/config.bin`, decode it to a temporary file, apply F3 configuration, then remove the temporary file.
 - `Encrypt()`/`Decrypt()` provide reversible base64+gzip encoding, not secrecy. Treat every configuration artifact as sensitive because it can contain credentials.
 - `Encrypt()`/`Decrypt()` provide reversible base64+gzip encoding, not secrecy. Treat every configuration artifact as sensitive because it can contain credentials.
-- The generator uses `cfg/config.ini` and refuses to overwrite an existing `cfg/config.bin`.
+- Operators copy `cfg/config.ini.example` to the ignored `cfg/config.ini` and provision `cfg/config.bin` outside the repository; no generation script is tracked.
 - Only an authenticated `admin` may read decoded configuration or save a replacement; save also requires CSRF validation.
 - Only an authenticated `admin` may read decoded configuration or save a replacement; save also requires CSRF validation.
 - Save first renames `config.bin` to `config.bin.old`, writes encoded replacement content, and restores the backup if writing the new file fails.
 - Save first renames `config.bin` to `config.bin.old`, writes encoded replacement content, and restores the backup if writing the new file fails.
 - The API accepts arbitrary string text; therefore callers must preserve valid F3 INI syntax and required runtime globals. No schema validation exists in the application.
 - The API accepts arbitrary string text; therefore callers must preserve valid F3 INI syntax and required runtime globals. No schema validation exists in the application.

+ 11 - 10
specs/file-structure.md

@@ -6,20 +6,21 @@ Read this when you need the repository map, boot order, or generated-file bounda
 |---|---|
 |---|---|
 | `index.php` | HTTP/CLI bootstrap: Composer autoload, F3 singleton, encrypted runtime config, plugin composition, then `run()`. |
 | `index.php` | HTTP/CLI bootstrap: Composer autoload, F3 singleton, encrypted runtime config, plugin composition, then `run()`. |
 | `composer.json` | PHP 8.5 and Fat-Free Framework dependencies; PSR-4 maps `OpenMind\` and `Modules\`. |
 | `composer.json` | PHP 8.5 and Fat-Free Framework dependencies; PSR-4 maps `OpenMind\` and `Modules\`. |
-| `cfg/config.ini` | Plaintext source of F3 globals and MySQL DSN; used to produce the runtime config. |
-| `cfg/config.bin` | Runtime configuration consumed by `index.php`; generated locally and not tracked. |
-| `scripts/generate-config-bin.sh` | Creates `cfg/config.bin` from `cfg/config.ini` only if no target exists. |
-| `src/OpenMind/System/` | Bootstrap, plugin discovery, framework services, mappers, roles, notifications, and error handling. |
-| `src/OpenMind/Api/` | API route registry and JSON controllers. |
-| `src/OpenMind/Admin/` | Administration plugin that registers the `admin` role and menu hierarchy. |
-| `src/Modules/Blank/` | Example plugin registering the `demo` role and menu entry. |
+| `cfg/config.ini.example` | Tracked F3 configuration template with deployment placeholders. |
+| `cfg/config.ini` | Ignored local F3 configuration, which may contain credentials. |
+| `cfg/config.bin` | Runtime configuration consumed by `index.php`; provisioned outside the repository and not tracked. |
+| `scripts/` | No tracked scripts. |
+| `src/OpenMind/System/` | Bootstrap, plugin discovery, framework services, role/user/inventory mappers, notifications, and error handling. |
+| `src/OpenMind/Api/` | API route registry and JSON controllers, including role and inventory administration. |
+| `src/OpenMind/Admin/` | Administration plugin that publishes the ID-1 administration menu hierarchy. |
+| `src/Modules/Blank/` | Retained plugin directory that publishes the ID-2 Inventory Monitor menu entry. |
 | `ui/app/` | Vite React source application. |
 | `ui/app/` | Vite React source application. |
 | `ui/app/src/api/client.js` | Same-origin API client and in-memory CSRF token holder. |
 | `ui/app/src/api/client.js` | Same-origin API client and in-memory CSRF token holder. |
-| `ui/app/src/features/` | Authentication, shell, administration, notification, home, and demo UI features. |
-| `assets/app/` | Vite build output, including hashed JS/CSS and the manifest; do not edit manually. |
+| `ui/app/src/features/` | Authentication, shell, administration, inventory demo, notification, and home UI features. |
+| `assets/app/` | Ignored local Vite build output, including hashed JS/CSS and the manifest; do not edit manually. |
 | `assets/images/` | Static images referenced by legacy menu entries and React pages. |
 | `assets/images/` | Static images referenced by legacy menu entries and React pages. |
 | `vite.config.js` | Builds `ui/app` into `assets/app` with base `/phengine/assets/app/` and suppresses Rollup `"use client"` module-directive warnings. |
 | `vite.config.js` | Builds `ui/app` into `assets/app` with base `/phengine/assets/app/` and suppresses Rollup `"use client"` module-directive warnings. |
-| `omlink.sql` | MySQL schema and sample data dump. |
+| `omlink.sql` | MySQL schema and sample data dump, including the role catalog and inventory tables. |
 
 
 ## Boot and Request Flow
 ## Boot and Request Flow
 1. `index.php` validates PHP, decrypts `cfg/config.bin`, and invokes `ApplicationComposition` over `src/`.
 1. `index.php` validates PHP, decrypts `cfg/config.bin`, and invokes `ApplicationComposition` over `src/`.

+ 6 - 6
specs/integrations/encrypted-config.md

@@ -9,13 +9,13 @@ Read this when changing configuration encoding, runtime loading, backup behavior
 | `index.php` | `LoadEncryptedConfig('cfg/config.bin')` during bootstrap |
 | `index.php` | `LoadEncryptedConfig('cfg/config.bin')` during bootstrap |
 | `src/OpenMind/System/OMUtils.php` | `LoadEncryptedConfig`, `Encrypt`, `Decrypt` |
 | `src/OpenMind/System/OMUtils.php` | `LoadEncryptedConfig`, `Encrypt`, `Decrypt` |
 | `src/OpenMind/Api/AdminController.php` | Admin read/save and backup restoration |
 | `src/OpenMind/Api/AdminController.php` | Admin read/save and backup restoration |
-| `scripts/generate-config-bin.sh` | First-time runtime config generation |
-| `cfg/config.ini` | Plaintext source used by the generator |
+| `cfg/config.ini.example` | Tracked placeholder template for local configuration |
+| `cfg/config.ini` | Ignored local plaintext configuration, potentially containing credentials |
 
 
 ## Flow
 ## Flow
 1. Bootstrap checks the PHP version and asks `OMUtils` to load `cfg/config.bin`.
 1. Bootstrap checks the PHP version and asks `OMUtils` to load `cfg/config.bin`.
 2. The utility decodes it to a temporary file, calls F3 `config()`, then deletes the temporary file.
 2. The utility decodes it to a temporary file, calls F3 `config()`, then deletes the temporary file.
-3. The generator encodes `cfg/config.ini` into a previously absent `cfg/config.bin`.
+3. Deployment tooling provisions `cfg/config.bin` before bootstrap; no configuration-generation script is tracked.
 4. An administrator can read plaintext through the API or submit replacement text.
 4. An administrator can read plaintext through the API or submit replacement text.
 5. Save renames the prior runtime config to `.old`, writes the encoded replacement, and restores the backup if writing fails.
 5. Save renames the prior runtime config to `.old`, writes the encoded replacement, and restores the backup if writing fails.
 
 
@@ -24,10 +24,10 @@ Read this when changing configuration encoding, runtime loading, backup behavior
 | Boundary | Mechanism | Location |
 | Boundary | Mechanism | Location |
 |---|---|---|
 |---|---|---|
 | Runtime config presence | Bootstrap throws when the required file is absent | `OMUtils::LoadEncryptedConfig()` |
 | Runtime config presence | Bootstrap throws when the required file is absent | `OMUtils::LoadEncryptedConfig()` |
-| Sensitive config disclosure | `admin` role required before reading plaintext | `AdminController::load()` |
-| Sensitive config mutation | `admin` role and CSRF validation required | `AdminController::save()` |
+| Sensitive config disclosure | Numeric permission ID `1` required before reading plaintext | `AdminController::load()` |
+| Sensitive config mutation | Numeric permission ID `1` and CSRF validation required | `AdminController::save()` |
 | Partial replacement failure | Backup rename and restore attempt after write failure | `AdminController::saveConfiguration()` |
 | Partial replacement failure | Backup rename and restore attempt after write failure | `AdminController::saveConfiguration()` |
-| Generator overwrite | Script exits if `cfg/config.bin` already exists | `scripts/generate-config-bin.sh` |
+| Local config source | Placeholder template is copied to an ignored local file | `cfg/config.ini.example` |
 
 
 ## Config
 ## Config
 - Runtime file: `cfg/config.bin`.
 - Runtime file: `cfg/config.bin`.

Some files were not shown because too many files changed in this diff