When to use
- Register a new plugin under plugins/<name>/ for local development
- The plugin needs a module row before it can be installed from the ERP UI
- Following the README module INSERT pattern for local/dev
Prerequisites
- Local developing setup is active (prepare-local-dev.sh / local core workflow)
- psql available
- Postgres reachable with credentials from base/backend/.env
DB credentials
Read connection values from base/backend/.env. Do not hardcode passwords in docs, commits, or chat logs.
- DB_HOST — expect localhost / 127.0.0.1 for local/dev
- DB_PORT, DB_USERNAME, DB_PASSWORD, DB_SCHEMA
- If DB_HOST is not local, stop — this flow is local/dev only
# From repo root — values from base/backend/.env
export PGPASSWORD="$DB_PASSWORD"
psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USERNAME" -d "$DB_SCHEMA"Seed INSERT
Map fields from plugins/<name>/module.metadata.json. Unique constraint is (name, plugin_version).
- name ← metadata.name (must match plugin folder / metadata)
- displayName ← human title (ask if missing; do not invent brand-heavy copy)
- description ← metadata.description
- unInstallable ← true for normal plugins
- module_entry_object ← metadata.moduleEntryObject (usually Module)
- plugin_version ← metadata.pluginVersion (usually 1.0.0)
- dependencies ← JSON string of metadata.pluginDependencies ('{}' when empty)
- base_version ← metadata.requiredBasedVersion (usually 1.0.0)
- version ← row/optimistic version — use 1 like README seeds
INSERT INTO module
("name","displayName","description","unInstallable","module_entry_object","plugin_version","dependencies","base_version","version")
VALUES
('<name>','<Display Name>','<description>',true,'Module','1.0.0','{}','1.0.0',1);Check before insert
If a row already exists, do not duplicate unless you explicitly want an update. Prefer a targeted UPDATE over blind re-insert.
SELECT id, name, "displayName", plugin_version, installed
FROM module
WHERE name = '<name>' AND plugin_version = '<plugin_version>';One-shot example
1export PGPASSWORD="$DB_PASSWORD"
2psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USERNAME" -d "$DB_SCHEMA" -v ON_ERROR_STOP=1 <<'SQL'
3INSERT INTO module
4("name","displayName","description","unInstallable","module_entry_object","plugin_version","dependencies","base_version","version")
5VALUES
6('reward-point','Reward Point','Reward point management plugin',true,'Module','1.0.0','{}','1.0.0',1);
7SQLRecommended flow
- 01
Confirm local DB
Read base/backend/.env and verify DB_HOST is localhost / 127.0.0.1.
- 02
Identify plugin
Load plugins/<name>/module.metadata.json (and displayName if needed).
- 03
Existence check
SELECT by name + plugin_version before inserting.
- 04
Insert & verify
Run INSERT with psql, then SELECT and confirm id / name / displayName.
Do not
- Seed UAT/prod or non-local databases
- Commit .env, passwords, or connection dumps
- Invent extra columns beyond the README seed shape unless the live schema requires it
- Skip the existence check for a known plugin name