store-management-tool
v0.1.6
Published
An Authentik-protected Next.js dashboard for managing existing databases, permissions, uploads, and friendly data-entry forms.
Downloads
881
Maintainers
Readme
Store Management Tool
store-management-tool is an Authentik-protected dashboard for Next.js App Router applications. It combines dynamic SQLite administration, a small CMS, table and form permissions, managed uploads, and friendly Google-Forms-style data entry.
The installing application owns all runtime data. Store Management Tool never keeps durable state inside node_modules.
Install
npm install store-management-toolStore Management Tool needs Node.js 20.9 or newer, Next.js 15.5.20+ or 16.2.10+, React 19.2.6+, and Auth.js 5.
The dashboard uses better-sqlite3, which installs a native binding during a normal npm install.
Do not install with --ignore-scripts. If scripts were disabled earlier, repair only that dependency:
npm rebuild better-sqlite3 --ignore-scripts=falseIf npm reports that better-sqlite3 is waiting for script approval, approve and rebuild it from the installing
project:
npm approve-scripts better-sqlite3
npm rebuild better-sqlite3Current stable Next.js releases pin an older PostCSS build. Until Next.js updates it, add this to the installing
application's root package.json so npm uses the patched PostCSS release:
{
"overrides": {
"next": {
"postcss": "^8.5.10"
}
}
}Mount the dashboard
The UI uses one optional catch-all page. This single page owns /dashboard, its login screen, list editor, form builder, permissions pages, and end-user form routes.
// app/dashboard/[[...path]]/page.tsx
export const dynamic = "force-dynamic";
export const runtime = "nodejs";
export { default } from "store-management-tool/dashboard";OAuth callbacks and uploads are HTTP route handlers, so Next.js requires one separate API wrapper:
// app/api/store-management-tool/[...path]/route.ts
export const runtime = "nodejs";
export { GET, POST } from "store-management-tool/api";Import the scoped dashboard stylesheet once from the host root layout:
// app/layout.tsx
import "store-management-tool/styles.css";Finally, preserve the native SQLite dependency in the server bundle:
// next.config.ts
import { withStoreManagementTool } from "store-management-tool/next-config";
export default withStoreManagementTool({});Do not also define app/dashboard/page.tsx or other host routes under /dashboard; the package catch-all owns that subtree.
Host environment
Next.js loads the installing application's .env files. Store Management Tool reads process.env at runtime and does not load or publish a package-local .env.
# The host application's existing managed database.
DATABASE_URL=file:./data/app.db
# Store Management Tool's own metadata, kept outside node_modules.
CMS_STATE_DATABASE_URL=file:./.store-management-tool/state.sqlite
# Existing files here are discovered; new uploads are added here.
CMS_UPLOADS_DIR=./uploads
# Optional when process.cwd() is not the host project root.
CMS_PROJECT_ROOT=
AUTH_SECRET=replace-with-a-long-random-secret
AUTH_URL=http://localhost:3000
AUTHENTIK_ISSUER=https://auth.example.com/application/o/store-management-tool/
AUTHENTIK_CLIENT_ID=
AUTHENTIK_CLIENT_SECRET=
AUTHENTIK_REDIRECT_URI=http://localhost:3000/api/auth/callback/authentik
AUTHENTIK_GROUPS_CLAIM=groups
AUTHENTIK_ALLOWED_GROUPS=cms-users
AUTHENTIK_ADMIN_GROUPS=cms-adminsAll relative database and upload paths resolve from the installing project's root. Keep AUTH_URL as the
public site origin only, without /dashboard or /api appended.
Set AUTHENTIK_REDIRECT_URI to the exact callback URI the installing project must send to Authentik. The package
uses its configured base path instead of forcing /api/store-management-tool. Auth.js requires the final
/callback/authentik portion; everything before it is selected by the installing project. Register the same complete
value on the Authentik OAuth2/OIDC provider as a Strict redirect URI:
https://your-app.example.com/api/auth/callback/authentikThe protocol, hostname, port, path, and absence of a trailing slash must match. The login page validates this
contract before it sends a request to Authentik. AUTHENTIK_ISSUER is explicit rather than calculated; copy the
provider's per-application issuer from Authentik. Advanced installations may override discovery by configuring all
three of AUTHENTIK_AUTHORIZATION_ENDPOINT, AUTHENTIK_TOKEN_ENDPOINT, and AUTHENTIK_USERINFO_ENDPOINT
together. AUTHENTIK_ISSUER remains required for OIDC token validation.
Authentication settings are environment-only and cannot be changed from the browser.
Data ownership and safety
Store Management Tool uses two separate databases:
- The managed database is the installer's existing SQLite database. Its tables, columns, foreign keys, and rows are discovered dynamically. It changes only after an authorized schema command, row action, or form submission.
- The state database belongs to Store Management Tool and stores form definitions, grants, migrations, and observed Authentik principals. It defaults to
.web-cms/state.sqlitefor backward compatibility; setCMS_STATE_DATABASE_URL=file:./.store-management-tool/state.sqlitefor new installations.
The state database must not point to the managed database. Removing node_modules does not remove either database or the uploads directory.
Opening the dashboard never silently creates a missing managed SQLite database. An administrator instead sees the configured path and an explicit, confirmed option to create an empty database. Store Management Tool automatically creates and migrates only its own state database.
Existing managed tables, rows, foreign keys, and files are read dynamically. They do not need to have been created by Store Management Tool.
Permissions
Authentik remains mandatory. User grants use the stable OIDC sub; group grants use values from the configured groups claim. Effective permissions are the union of direct user and group grants, while global administrators retain access.
Table permissions cover viewing, adding, editing, and deleting rows; changing schema; managing forms; and managing permissions. Form permissions are separate:
useallows opening and submitting a published form without exposing its table.manageallows editing that form and granting its permissions.
Authorization is enforced in pages, server actions, and upload APIs—not only by hiding controls.
Forms and routes
Administrators build forms under /dashboard/forms with a drag-and-drop Form.io visual builder. The builder exposes
the selected table's live columns as database Fields, so questions remain mapped to known columns instead of writing
unstructured response data. Foreign keys render as friendly choices while submissions store the referenced key.
Published user forms open at /dashboard/submit/<slug> and use the same separate Authentik login at
/dashboard/login.
Visual definitions are stored in the package-owned state database; submissions continue to be validated and written
through Store Management Tool's database provider. File and image questions continue to use CMS_UPLOADS_DIR.
Existing forms are converted to visual definitions when first edited, and the state schema migration preserves their
fields and permissions.
The client-only builder is pinned to @formio/js 5.4.2 under MIT. This package does not use the Form.io server,
hosted API, enterprise modules, accounts, license keys, or response-based services. See
THIRD_PARTY_NOTICES.md for the included notice. Future Form.io upgrades must pass npm run check:licenses before
release.
Forms can hide technical columns, inject fixed values, show friendly labels and help text, upload files, present fixed choices, and turn single-column SQLite foreign keys into dropdowns. Submission is validated against the current live schema before insertion.
The Form editor exposes a provider-reported ID strategy for each primary key: manual input, database-generated, or server-generated UUID. SQLite rowid integer keys and database defaults are omitted for SQLite to generate; UUID/GUID-compatible keys can use crypto.randomUUID() and stay out of the user-facing Form. Composite keys are never silently assigned a package-generated strategy.
Form storage uses a versioned engine envelope and the dashboard calls a form-engine adapter plus generic editor/renderer boundaries. Form.io is the current formio engine, but database mapping, permissions, ID generation, validation, and submission are engine-neutral. A future engine can replace the adapter and UI boundary without changing those layers. The adapter entry point is store-management-tool/form-engine.
Local development
npm install
npm run lint
npm run typecheck
npm run build
npm run package:build
npm pack --dry-runCurrent limits
- SQLite is the implemented managed database provider; the provider contract leaves room for PostgreSQL and MySQL adapters.
- A form targets one table.
- Automatic relationship dropdowns support single-column foreign keys and load at most 500 choices.
- Anonymous forms are not supported; every user signs in through Authentik.
License
MIT
