Commit Graph

34 Commits

Author SHA1 Message Date
chaim c2269f8d58 Add CI/CD workflow for pre-built Docker image deployment 2026-04-13 20:41:59 +00:00
chaim d0b87b16dc fix: use semver comparison for extension version upgrades
Previously the system used simple string inequality to detect available
updates, causing downgrades to appear as upgrades (e.g. 2.5.1 → 2.5.0).
Now both backend (SQL) and frontend (JS) compare version tuples properly.
Also fixes latest_version in DB on registry sync startup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 15:05:15 +00:00
chaim 3cee3abfeb fix: add curl for healthcheck, PYTHONUNBUFFERED for logging
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 14:28:01 +00:00
chaim 7595763711 fix: restore server.py content destroyed by bad Gitea API commit fed6ca3
Commit fed6ca3 replaced the entire server.py (1017 lines) with a single
${FILE:/tmp/ext-platform-server.py} placeholder via Gitea API, breaking
the application. This restores the correct code and adds /api/health.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 14:24:44 +00:00
chaim c70c4e71e6 fix: rename server.py to app_server.py to bypass stale Coolify file mount
A Coolify persistent storage entry was overriding /app/server.py with an
unresolved ${FILE:} placeholder, causing SyntaxError on startup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 14:21:32 +00:00
chaim fed6ca30f6 feat: add /api/health endpoint with CORS headers 2026-04-06 13:39:27 +00:00
chaim 9aaee609cb fix: hide deploy button for extensions without a published version
Extensions like LegalAssistance that are in the registry but haven't
been published yet (latest_version is null) now show "אין גרסה"
instead of a deploy button. Batch deploy also skips them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 07:17:59 +00:00
chaim 1e5f220c97 fix: filter inactive extensions from dashboard API responses
/api/extensions and customer extension list now only return
is_active extensions, preventing deleted extensions from showing
in the dashboard and causing deploy errors with null versions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 07:11:32 +00:00
chaim d2a2d28b01 feat: auto-sync extension registry from Gitea on startup
Every time the server starts (including after deploy), it syncs
the extension registry from Gitea before serving requests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 06:58:03 +00:00
chaim 69fd5ae0c4 feat: auto-discover extensions from Gitea, sync registry with DB
MODULES was a static dict that got out of sync with Gitea repos —
LegalAssistance was missing, 5 deleted extensions were still listed.

Now MODULES loads from DB on startup with static fallback.
New POST /sync-registry endpoint scans espocrm-extensions org on Gitea,
adds new extensions, deactivates removed ones, and reloads MODULES.
INSTALL_ORDER is now computed dynamically via topological sort.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 06:49:57 +00:00
chaim 9bbac18b1a fix: send both Espo-Authorization and X-Api-Key for opcache clear
The platform stores API keys as base64-encoded Espo-Authorization,
not raw API keys. Send both headers so opcache-clear.php can validate.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 12:18:26 +00:00
chaim 08995b9027 feat: clear PHP opcache after extension deploy
Add multi-tier opcache clearing after extension install:
- Tier 1: HTTP call to opcache-clear.php endpoint
- Tier 2: SSH + docker exec apachectl graceful
- Tier 3: Log warning

Add ssh_host, ssh_user, ssh_key, docker_container fields
to customers table for SSH fallback.

Fixes production issue where new PHP files weren't loaded
after extension upgrade due to stale opcache.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 11:51:49 +00:00
chaim f8026afed4 fix: improved error display - show step, HTTP code, Hebrew messages; sync errors shown to user; deployment log shows error details 2026-03-30 21:00:43 +00:00
chaim 9380364376 fix: stale deploy check only looks at latest deploy per extension+customer
Was showing all historical deploys causing noise. Now uses DISTINCT ON
to get only the most recent deploy for each extension+customer pair.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 11:44:26 +00:00
chaim 0c77056422 feat: add health check endpoint + twice-daily monitoring workflow
New /health-check endpoint verifies:
- Gitea release integrity (manifest version matches tag)
- Duplicate ZIP assets in releases
- EspoCRM API reachability per customer
- Extension load status on each instance
- Stale deployments (logged ok but version not updated)

New n8n workflow runs at 07:00 & 19:00, combines health check
with drift sync, and posts combined report to Mattermost.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 11:38:36 +00:00
chaim f546b7d660 fix: handle duplicate ZIP assets in Gitea releases
- When re-publishing, delete old ZIP assets before uploading new one
- Take last ZIP asset when duplicates exist in deploy flow
- Handle empty response body from DELETE API calls

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 11:34:38 +00:00
chaim fc28ef2d7c fix: sync auto-assigns all active extensions to customer
Ensures every sync call first fills in any missing extension
assignments, so new extensions are automatically available to
all customers without manual intervention.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 10:25:38 +00:00
chaim 2cbb9aaa65 feat: auto-assign extensions + form validation
- Backend: new customers auto-get all active extensions assigned
- Frontend: required field validation (name, URL, credentials)
- Frontend: removed manual "add extension" dropdown (auto-assigned)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 10:02:05 +00:00
chaim 09ef629b8d fix: customer form auth fields layout + sticky header opacity
- Auth fields: use grid-cols-2 with dir=ltr for proper username/password
  layout, better spacing and visual hierarchy with key icon
- Header: increase opacity to 0.95 with subtle shadow to prevent
  content showing through when scrolling

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:34:27 +00:00
chaim 7aca2abf78 feat: add delete customer + fix auth form UX
- Backend: DELETE /api/customers/:id removes customer + extensions + logs
- Frontend: delete button on customer detail with confirmation
- Auth form: only sends espocrm_api_key when credentials are entered

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:27:19 +00:00
chaim ad386f5cef feat: add username/password fields to customer form for Espo auth
Instead of manually entering base64, users can now type username and
password which auto-generates the Espo-Authorization header value.
Empty credentials on edit won't overwrite existing API key.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:20:40 +00:00
chaim a11ddb82a6 fix: sync now resets installed_version when extension removed from server
- Backend: sync_customer_extensions now sets installed_version=NULL when
  extension is missing_on_server (previously only detected drift without
  updating DB)
- Frontend: refresh button now calls /sync endpoint before reloading,
  ensuring the dashboard reflects actual server state

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:02:11 +00:00
chaim 36812af6e7 feat: add POST /sync endpoint + daily n8n drift check workflow
Adds extension sync that queries each customer's EspoCRM to compare
actually-installed extensions with what the platform DB tracks.
Updates platform DB on version mismatches and reports drifts to Mattermost.

n8n workflow ID: NXxBHm3qhWL3yHza (daily at 07:00)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:26:01 +00:00
chaim f028299693 feat: add DataMigration to MODULES, DEPENDENCIES, and INSTALL_ORDER 2026-03-28 19:59:16 +00:00
chaim 98db6899db feat: UI improvements - default to customers tab, refresh button, installed extensions first 2026-03-28 19:30:40 +00:00
chaim 814e5a182c fix: return 404 for missing assets instead of index.html fallback
Prevents MIME type mismatch when asset filenames change after rebuild.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:46:35 +00:00
chaim 22b05617d4 feat: install order, dependency blocking, batch install
- Sort extensions by install order (HebrewLanguage first, then deps)
- Grey out extensions with missing dependencies (show lock icon + "נדרש: X")
- Checkbox selection for batch install with progress indicator
- "בחר הכל" button to select all installable extensions
- Server returns dependencies + install_order in customer API

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:56 +00:00
chaim eea011d68a fix: cancel button on form, edit customer, show installed/total count 2026-03-26 08:20:51 +00:00
chaim 72c3087dd0 redesign: apply Stitch design system — Heebo font, glass header, Material icons, editorial tables 2026-03-26 07:56:11 +00:00
chaim ccb467ebaa fix: show update button only when newer version available 2026-03-26 06:57:48 +00:00
chaim 4638763ee1 feat: structured extensions table in customer detail view
4 columns: name, installed version, available update, actions
Actions: install (if not installed), update + remove (if installed)
2026-03-26 06:50:35 +00:00
chaim 188c5fb878 fix: use multipart upload for Composer Registry (fixes 500 error) 2026-03-26 06:22:27 +00:00
chaim 8c6cd8a3ef fix: handle 409 Conflict in gitea_upload as 'exists' not error 2026-03-26 06:19:13 +00:00
chaim 5e0e5f1066 Extension Platform: API server + React dashboard
- Python API server with Gitea-based build (no local files needed)
- PostgreSQL on Coolify internal network
- React + Vite + Tailwind dashboard
- Endpoints: /publish, /deploy, /deploy-all, /api/*
- Dockerfile: multi-stage (Node build + Python runtime)
2026-03-26 04:53:01 +00:00