Skip to content

Technical Overview

pawelcel edited this page Sep 30, 2026 · 2 revisions

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).

Architecture

  • Backend — ASP.NET Core (.NET) minimal API, Npgsql with no ORM, endpoints split by function under EasyPDM.Api/Endpoints/. Serves the built frontend straight from its own wwwroot/. 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.sql holds 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 manual psql step 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.

Data model, in brief

  • Items (items table) 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-precheck reports what is blocking; PATCH .../status enforces it and, with promoteChildren, moves the children and the assembly in one transaction).
  • Structure is a separate table, item_relations (parent/child/quantity/position) — not a tree column on items — 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_id is 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_attachments is the project-level counterpart, where a nullable role column marks the quote and order-confirmation slots and leaves NULL for ordinary files.
  • Client verification (item_client_verifications plus 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 NULL result is 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.

Login and access

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.

API surface

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.

Deployment paths

Three ways to run EasyPDM, all covered in detail in TECHNICAL.md:

  • Windows installer (packaging/windows/, Inno Setup) — produces EasyPDM_Windows_v<version>.exe.
  • Linux, Docker — install-easypdm-docker.sh / docker-compose.yml, pulling published images from ghcr.io/pawelcel/easypdm-api and ghcr.io/pawelcel/easypdm-postgres.
  • Linux, native — install-easypdm-linux.sh, a self-contained EasyPDM-Linux-x64_v<version>.tar.gz package installed as a systemd service.

CI/CD

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.Z on a version tag), and create-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 matching CHANGELOG.md section, and opens a draft GitHub Release — publishing is always a deliberate, manual last step.

Clone this wiki locally