Repository navigation
Technical Overview
For administrators and developers. This page is a summary — the authoritative,
actively-maintained detail lives in
TECHNICAL.md in the
repository (also available in Polish and German).
-
Backend — ASP.NET Core (.NET) minimal API,
Npgsqlwith no ORM, endpoints split by function underEasyPDM.Api/Endpoints/. Serves the built frontend straight from its ownwwwroot/. A custom file logger writes daily-rotated logs (30-day retention), visible in the app under Settings → Logs. -
Frontend — React 19 + Vite + TypeScript + Tailwind v4 + shadcn/ui, built into
EasyPDM.Api/wwwroot/. Fully translated (Polish/English/German), light/dark theme. -
Database — PostgreSQL.
db/schema.sqlholds the full schema from scratch;db/migrations/holds the incremental migrations for an existing database. Migrations are embedded in the program and applied automatically on every startup — no manualpsqlstep needed. -
Tests —
EasyPDM.Api.Tests, xUnit +WebApplicationFactory, run the whole application against a real PostgreSQL instance (a separate schema, reset before every test class). -
CAD macros —
EasyPDM.SolidWorks/,EasyPDM.Inventor/(VBA),EasyPDM.FreeCad/(Python) — self-contained files that talk to the same REST API a browser session uses. See CAD Integrations.
-
Items (
itemstable) have one of four types: Folder, Part, Assembly, or Other file. Parts and Assemblies get a number from a single global sequence, a status (in progress → under review → released, plus cancelled), a revision letter, and an owner/lock. An Assembly's move to "under review"/"released" is additionally gated on the status of its direct BOM children (GET /api/items/{id}/status-precheckreports what is blocking;PATCH .../statusenforces it and, withpromoteChildren, moves the children and the assembly in one transaction). -
Structure is a separate table,
item_relations(parent/child/quantity/position) — not a tree column onitems— so the same Part/Assembly can be shared as a component across several assemblies and projects at once. A Part/Assembly can also exist with no project at all (project_idis nullable), reachable only through "Whole database" — useful for components that should exist purely as BOM entries, not as their own project-level item. - Owner/lock is independent of status: the creator of a Part/Assembly becomes its owner and locks it for editing; only the owner (or an administrator, explicitly) can edit or release it. Released/cancelled items have no owner and can't be locked. Editing outside "in progress" status is otherwise blocked.
- Catalogs (Materials, Manufacturers with Series/Type/Subtype, Clients with Name 2 variants) are company-wide tables linked to items by name, not by foreign key — deleting or renaming a catalog entry never rewrites items that already reference it.
-
Attachments (
item_attachments) are files attached to a Part/Assembly/File, separate from the tree structure — this is what CAD files, STEP/PDF exports, and drawings are uploaded as.project_attachmentsis the project-level counterpart, where a nullablerolecolumn marks the quote and order-confirmation slots and leaves NULL for ordinary files. -
Client verification (
item_client_verificationsplus its own attachments table) is keyed on the pair (item, project), not on the item alone — the same Part in two projects is accepted by two different clients. A NULLresultis not a third dictionary value but literally "no verdict yet", i.e. in progress, and each entry stores the revision it covered. - History — every item's detail panel shows a full chronological log: creation, status changes, revisions with comments, attachments added/removed, lock/release events.
Full detail (state machine transitions, BOM CSV export variants, project-deletion
semantics, numbering-sequence recovery, etc.) is in TECHNICAL.md's "Data model" and
"Login, roles, and project access" sections.
Session-cookie auth (pdm_session, 30-day validity), PBKDF2 password hashing. Two
roles: administrator (full access, every project) and user (only projects
they're assigned to via project_users). A fresh, empty database seeds a default
admin/admin account on first startup — change the password immediately.
The REST API (/api/*) is grouped by resource: auth (including the browser-login
"ticket" exchange the CAD macros use to open an already-logged-in browser), projects,
items/nodes (create, move, duplicate, delete, status, lock/release), relations/BOM,
attachments and documentation download, materials/manufacturers/clients catalogs, users,
notifications, and system settings (numbering, storage, backups, logs). The full,
authoritative endpoint table is in TECHNICAL.md.
Three ways to run EasyPDM, all covered in detail in TECHNICAL.md:
-
Windows installer (
packaging/windows/, Inno Setup) — producesEasyPDM_Windows_v<version>.exe. -
Linux, Docker —
install-easypdm-docker.sh/docker-compose.yml, pulling published images fromghcr.io/pawelcel/easypdm-apiandghcr.io/pawelcel/easypdm-postgres. -
Linux, native —
install-easypdm-linux.sh, a self-containedEasyPDM-Linux-x64_v<version>.tar.gzpackage installed as asystemdservice.
GitHub Actions workflows under .github/workflows/: build + integration tests on every
push/PR, Windows/Linux installer builds that actually install and smoke-test themselves
on a clean runner, Docker image publishing (:edge on every push to main, :latest
-
:vX.Y.Zon a version tag), andcreate-release-draft.yml, which on a version tag checks that the version numbers in the repo match the tag, builds both installers, attaches the Inventor/FreeCAD macro files (named with the release version), extracts release notes from the matchingCHANGELOG.mdsection, and opens a draft GitHub Release — publishing is always a deliberate, manual last step.
EasyPDM
Elsewhere