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
106 changes: 74 additions & 32 deletions ERP-HANDOFF.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
# ERP purpose and deployment handoff
# Workshop ERP deployment handoff

## What the source system does
Workshop ERP is a free, open-source ERP backbone/template based on a working,
field-tested implementation. The public source has been sanitized and runs as
a synthetic localhost copy. This handoff describes how an adopter could turn
that source into a shared deployment; it is **not** a claim that the current
download can be exposed on a network by filling in paths and tokens.

The source ERP is a company-wide **website** for a small engineering and
manufacturing organization. Staff open the same browser/PWA application from
workstations and phones; it is not a separate desktop app on each PC. A Node.js
server on one active Windows host serves the frontend and API, and persists
shared records in SQLite. A Cloudflare tunnel can expose that one host to
authorized users outside the office. The tunnel transports requests; it does
not render pages or 3D models on the host. Browsers render the UI and GLB
viewer locally.
## Intended architecture

The shared ERP is a **website** opened from workstations and phones, not a
separate desktop app on each PC. A Node.js server on one active host serves
the frontend and API. Browsers render the UI and GLB viewer locally. Users on
the same LAN could reach a secured host directly; remote users could reach it
through a Cloudflare Tunnel with an access policy. Neither path is enabled in
this public copy.

The common unit of work is a project. A configured set of project directories
is scanned and reconciled with ERP project IDs. Staff use those projects to
Expand All @@ -32,23 +36,22 @@ Typical flow:
5. Everyone sees saved changes through the server's API/SSE. Project renames,
missing folders and manual activation changes produce visible notices.

The production design uses one active host at a time. Other enrolled PCs run
standby watchdogs; a standby can take over after the active host fails. The
active host alone runs the HTTP server and tunnel connector. This file-based
coordination, network-share SQLite access, storage fencing, startup installers
and backup pruning are operational safety mechanisms, not optional decoration.
Changing a path or token without adapting and testing those mechanisms can
lose data or start competing hosts.
The design calls for one active host at a time. Standby machines may take
over only after a tested, exclusive handoff. The active host alone runs the
HTTP server and optional tunnel connector. Storage fencing, crash recovery,
startup control and backups are safety requirements, not just settings.
Changing a path or token without implementing and testing them could start
competing hosts or lose data.

## What this repository currently runs
## What the public repository currently runs

`npm.cmd start` runs `demo-server.mjs` only on `127.0.0.1`. It shows all
25 menu views with synthetic, profile-local persistent data. Optional local
password mode is still localhost-only. Its local project/document scans are
confined to the selected profile. It does not use a real network share,
watchdog, tunnel, production Helper or production database.
confined to the selected profile. It does not use shared storage, a watchdog,
a tunnel or the fuller backend.

The original Node backend source is preserved under `app/` for adaptation,
The fuller Node backend source is preserved under `app/` for adaptation,
but `app/server.js` intentionally throws before any startup work. The real
host launchers, Cloudflare executable and token are not in this repository.
Generic wrappers with the expected `.bat`/`.cmd` names now live at the root;
Expand All @@ -63,22 +66,61 @@ has matching source and third-party notices. See
`config.example.json` is the public, synthetic single-file starter. Its
ordinary fields configure the **running localhost demo**: name, people,
projects, catalogs, sample data, port, optional local OCR and security. The
new `futureHosting` section records the intended organization, storage,
new `futureHosting` section records the intended site, storage,
network, Cloudflare token-file paths, one-host watchdog, Helper and backup
settings for a later company deployment. It is parsed and checked, but
settings for a later deployment. It is parsed and checked, but
**never applied** by this server. Its `status` and every hosted-service
`enabled` field must remain disabled. Put no token value or password in the
file; `tokenSourceFile` and `tokenLocalFile` are path references only.
An installation's edited `config.json` is ignored by Git and excluded from
the downloadable source ZIP. More field detail is in
[`CUSTOMIZE.md`](CUSTOMIZE.md).

For a different organization, use a separate local profile, generic logo and
new local database for the demo. To build a real hosted deployment later,
engineers must first replace the original backend's fixed share/drive/project/
Helper/backup/process paths with validated config access, complete and review
the fail-closed generic launchers, implement first-run hosted accounts and secure
sessions, prove single-writer takeover and restore behavior on a test share,
then review tunnel, source offer and permissions. Do not use the live source
system's database or token as a test fixture. Configuration values alone do
not turn this localhost demo into a company-wide hosted ERP.
For a local trial, use a separate profile, generic logo and new local
database. Never use real records, a live database or a tunnel token as a test
fixture. Configuration values alone do not turn this source into a shared ERP.

## What an adopter must implement before shared use

1. **Adapt the backend and paths.** Refactor the guarded `app/server.js` and
its storage, CAD, Helper, backup and process modules to consume validated
configuration. Remove the startup guard only after those side effects are
isolated and tested. The local `demo-server.mjs` is not a shortcut to a
network host.
2. **Choose and test shared data storage.** Decide where records and files
live, define migrations and consistency checks, and prove that a crash or
disconnected share cannot corrupt or split the data. Implement an
exclusive single-writer lease/fence before allowing a standby to take over.
3. **Complete hosted accounts and authorization.** Provide first-run admin
creation with no default password, individual sign-in, role checks for all
sensitive API routes, secure sessions, CSRF protection and abuse limits.
The current optional password mode is only a single-process localhost
trial. LAN users need this protection too. If using a tunnel, Cloudflare
[Access can enforce an outer MFA gate](https://developers.cloudflare.com/cloudflare-one/access-controls/policies/mfa-requirements/),
but it does not replace ERP permissions or protect an unguarded LAN path.
4. **Implement non-destructive host controls.** The supplied launchers and
`hosting/host-control.mjs` currently refuse install/start/watch/stop/
restart/tunnel actions. Adapt them for a specific installation with exact
process identity, monitored health, exclusive takeover and reversible
startup registration. Test active-host failure and recovery with two
disposable hosts before using persistent records.
5. **Prove backup and restore.** Make consistent snapshots, verify hashes,
test a complete restore, and set retention deliberately. Do not rely on
the localhost profile-backup script for shared-host recovery.
6. **Configure remote access only after the app passes these gates.** A
remotely managed Cloudflare Tunnel can route a chosen hostname to the
active host; keep connector credentials in a protected file, not Git or
the template JSON. Apply a Cloudflare Access policy for intended users.
A LAN-only installation can omit the tunnel but still needs secure app
login, transport protection and host/firewall controls.
7. **Finish installation-specific features.** The financial area is
unfinished. Helper integration, push, a bundled/tested OCR engine and
network project scans are not complete in this public copy. Implement only
the features required by a particular installation, then test their
permissions and data handling.

The public skeleton is useful source for this work, but no hosted deployment,
failover, live-data migration or security acceptance has been performed on
this sanitized copy. See the official [Cloudflare Tunnel setup](https://developers.cloudflare.com/tunnel/get-started/)
and [Cloudflare Access web-app guidance](https://developers.cloudflare.com/cloudflare-one/access-controls/applications/http-apps/)
when designing remote access.
39 changes: 18 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
# Workshop ERP — localhost public-copy workbench
# Workshop ERP — free open-source ERP backbone

The [project page](https://simonsystem609.github.io/ERP_Workshop/) introduces
the [full synthetic screenshot gallery](https://simonsystem609.github.io/ERP_Workshop/gallery.html)
and the limits of this local demo.

This folder contains a generic, English-interface, synthetic-data ERP copy under development,
not the company's database. All 25 original menu views are present. It binds
only to `127.0.0.1` and stores edits in a separate persistent local SQLite
database. The default start command never imports the guarded original
backend or writes to a
production network share. It is not yet a secure hosted deployment or a
feature-complete clone.
The [ERP handoff](ERP-HANDOFF.md) explains how the source system is used
company-wide as a website for engineering projects and related operations,
and distinguishes that system from this local demo.
and the limits of the current local source package.

This free template is based on a working, field-tested ERP. The public source
contains a generic, English-interface, synthetic-data adaptation with all 25
menu views and persistent local records. Its financial side is unfinished.
The current start command binds only to `127.0.0.1`; it does not import the
guarded fuller backend or write to shared storage. This package is not yet a
secure LAN, tunnel or multi-host deployment. The [deployment handoff](ERP-HANDOFF.md)
describes the intended architecture and the code and validation still needed.

![Synthetic dashboard](docs/images/dashboard.png)
![Synthetic material requests](docs/images/materials.png)
Expand All @@ -26,7 +23,7 @@ and distinguishes that system from this local demo.
The [full 25-menu screenshot gallery](docs/images/README.md) and its four
function captures were taken from a separate synthetic localhost profile.
It includes the generated GLB cube in the 3D model list/viewer and a small
synthetic DXF in the project browser. No company database or live ERP page
synthetic DXF in the project browser. No private database or live ERP page
was used for these images.

## Run
Expand Down Expand Up @@ -63,7 +60,7 @@ which is the only file-browsing root for this profile. Details and a feature
matrix are in
[`CUSTOMIZE.md`](CUSTOMIZE.md).
The same config template now has a `futureHosting` deployment plan for
company-specific paths, proposed host ports, Cloudflare token-*file*
installation-specific paths, proposed host ports, Cloudflare token-*file*
locations, a single-active-host watchdog, Helper and backups. It is
reference-only: the localhost server validates but never applies it, and
the guarded original backend does not read it. Filling every value does
Expand All @@ -84,9 +81,9 @@ The intended public ERP source in this folder is licensed under
**AGPL-3.0-or-later**; see [LICENSE](LICENSE). The bundled GLB viewer uses
the same license. The viewer's bundled three.js code has a separate MIT
notice in `app/public/erp-glb-viewer/THIRD-PARTY-LICENSES.txt`.
The user confirmed company permission covers this exact C-only candidate,
including the guarded backend/Helper and approved images under that license.
This is a user attestation; it does not make the demo safe for hosted use or
The author confirmed publication rights for this exact source set, including
the guarded backend/Helper and approved images under that license.
This is an author attestation; it does not make the demo safe for hosted use or
replace a final check of changed release files.
The localhost app displays a source-code link on the login and main screens.
`/SOURCE.zip` contains the explicitly allowlisted ERP source, build scripts,
Expand Down Expand Up @@ -135,7 +132,7 @@ Restart after changing source so the served bundle matches the running app.
- A preserved, startup-disabled copy of the original backend and Helper
source. `npm.cmd run original:fixture -- --out <new local absolute .db path>`
creates a fresh original-schema SQLite file from the public sample template,
including dummy in-app notices. It never copies the company's DB. The
including dummy in-app notices. It never copies a private database. The
original backend still cannot be used as the demo server.

Helper, a bundled OCR engine,
Expand Down Expand Up @@ -186,8 +183,8 @@ for exact-file review can be built outside the project with
`npm.cmd run package:source -- --out <backup-root>\source-review-001.zip`.
That archive is not publication approval.

This repository contains the sanitized localhost demo source. The user
confirmed company permission for this candidate and approved
This repository contains the sanitized localhost demo source. The author
confirmed publication rights for this candidate and approved
AGPL-3.0-or-later. The technical source, privacy, notice and localhost checks
are recorded in the release notes; repeat the exact staged-tree review for
future changes. See
Expand Down
11 changes: 5 additions & 6 deletions docs/gallery.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@
.section-head p { max-width:350px; margin:0; color:var(--muted); }
.grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:19px; }
.card { min-width:0; margin:0; padding:10px; border:1px solid var(--line); border-radius:14px; background:#fff; }
.image-link { display:block; overflow:hidden; border:1px solid #e1e5e1; border-radius:8px; }
.image-link img { display:block; width:100%; aspect-ratio:1.65; object-fit:cover; object-position:top left; transition:transform .2s ease; }
.image-link:hover img { transform:scale(1.025); }
.image-link { display:block; border:1px solid #e1e5e1; border-radius:8px; }
.image-link img { display:block; width:100%; height:auto; border-radius:7px; }
figcaption { display:grid; gap:2px; padding:11px 5px 4px; }
figcaption strong { font-size:.98rem; }
figcaption span { color:var(--muted); font-size:.86rem; }
Expand All @@ -47,12 +46,12 @@
footer a { color:#e4eee9; }
@media (max-width:900px) { .grid { grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:620px) { .wrap { width:calc(100% - 28px); } .hero { padding:53px 0 59px; } section { padding-top:55px; } .section-head { display:block; } .section-head p { margin-top:13px; } .grid { grid-template-columns:1fr; } footer .wrap { flex-direction:column; } }
@media (prefers-reduced-motion:reduce) { html { scroll-behavior:auto; } .image-link img { transition:none; } }
@media (prefers-reduced-motion:reduce) { html { scroll-behavior:auto; } }
</style>
</head>
<body>
<header><nav class="wrap" aria-label="Main navigation"><a class="brand" href="index.html"><span class="mark" aria-hidden="true">W</span>WORKSHOP ERP</a><a class="back" href="index.html">← Project page</a></nav></header>
<div class="hero"><div class="wrap"><span class="eyebrow">Synthetic localhost gallery</span><h1>Every view of the workshop.</h1><p class="lead">All 25 menu screens and four function views from a separate synthetic demo profile. Select an image to see it at full size. These are interface previews, not a hosted ERP or production records.</p><nav class="jump" aria-label="Gallery sections"><a href="#overview">Overview</a><a href="#operations">Operations</a><a href="#engineering">Engineering &amp; finance</a><a href="#administration">Administration</a><a href="#functions">Function views</a></nav></div></div>
<div class="hero"><div class="wrap"><span class="eyebrow">Free ERP template · synthetic gallery</span><h1>Every view of the workshop.</h1><p class="lead">All 25 menu screens and four function views from a separate synthetic local profile. Each captured frame keeps its original proportions; select one for its original size. These previews contain no private records.</p><nav class="jump" aria-label="Gallery sections"><a href="#overview">Overview</a><a href="#operations">Operations</a><a href="#engineering">Engineering &amp; finance</a><a href="#administration">Administration</a><a href="#functions">Function views</a></nav></div></div>
<main class="wrap">
<section id="overview" aria-labelledby="overview-title"><div class="section-head"><div><span class="kicker">01 / OVERVIEW</span><h2 id="overview-title">From a project to the floor</h2></div><p>3 synthetic menu views</p></div><div class="grid">
<figure class="card"><a class="image-link" href="images/menus/01-dashboard.png" aria-label="Open full-size Dashboard screenshot"><img src="images/menus/01-dashboard.png" loading="lazy" decoding="async" alt="Synthetic Workshop ERP Dashboard screen"></a><figcaption><strong>Dashboard</strong><span>Tasks, meetings, and at-a-glance status</span></figcaption></figure>
Expand Down Expand Up @@ -93,7 +92,7 @@
<figure class="card"><a class="image-link" href="images/functions/modelling.png" aria-label="Open full-size Modelling photos screenshot"><img src="images/functions/modelling.png" loading="lazy" decoding="async" alt="Synthetic Workshop ERP Modelling photos screen"></a><figcaption><strong>Modelling photos</strong><span>Profile-local image workspace</span></figcaption></figure>
<figure class="card"><a class="image-link" href="images/functions/model-viewer.png" aria-label="Open full-size In-page 3D viewer screenshot"><img src="images/functions/model-viewer.png" loading="lazy" decoding="async" alt="Synthetic Workshop ERP In-page 3D viewer screen"></a><figcaption><strong>In-page 3D viewer</strong><span>A synthetic GLB box rendered in the browser</span></figcaption></figure>
</div></section>
<aside class="note"><p>All records and files shown here are synthetic. The downloadable source runs only on <code>127.0.0.1</code>; finance and hosted features remain incomplete. See the <a href="https://github.com/simonsystem609/ERP_Workshop">repository and setup notes</a> before running it.</p></aside>
<aside class="note"><p>All records and files shown here are synthetic. The downloadable source currently runs only on <code>127.0.0.1</code>; finance and shared-host deployment remain incomplete. See the <a href="https://github.com/simonsystem609/ERP_Workshop">repository and setup notes</a> before running it.</p></aside>
</main>
<footer><div class="wrap"><span>Workshop ERP · synthetic localhost demo · AGPL-3.0-or-later</span><span><a href="index.html">Project page</a> · <a href="https://github.com/simonsystem609/ERP_Workshop">Source</a></span></div></footer>
</body>
Expand Down
Loading
Loading