Commit Graph
74 Commits
Author SHA1 Message Date
Malek TellissiandClaude Sonnet 4.6 a4f3254ebd Add address, phone, email, website fields to suppliers
Deploy / deploy (push) Successful in 16s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 21:38:53 +02:00
Malek TellissiandClaude Sonnet 4.6 c5b0a43928 Show recipe version and date in product list instead of recipe name
Deploy / deploy (push) Successful in 16s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 21:30:15 +02:00
Malek TellissiandClaude Sonnet 4.6 e9ea8770e5 Make Produkte a flat nav item, remove Produkte navigation group
Deploy / deploy (push) Successful in 15s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 21:28:16 +02:00
Malek TellissiandClaude Sonnet 4.6 42748bbe20 Fix deploy: clear PHP source dirs before SCP so deleted files don't persist
Deploy / deploy (push) Successful in 16s
SCP only adds/overwrites files, never deletes. Clearing app/, routes/,
config/, database/, resources/, bootstrap/ before copy ensures the server
always reflects the current git state exactly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 21:25:41 +02:00
Malek TellissiandClaude Sonnet 4.6 ae579892bc Add optimize:clear before cache rebuild in entrypoint to prevent stale cache
Deploy / deploy (push) Successful in 14s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 21:22:12 +02:00
Malek TellissiandClaude Sonnet 4.6 7dfd01c11a Remove standalone RecipeResource — recipes managed via product page
Deploy / deploy (push) Successful in 9s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 21:17:38 +02:00
Malek TellissiandClaude Sonnet 4.6 a104924add Remove accidentally committed article_number migration (was rejected)
Deploy / deploy (push) Successful in 9s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 21:17:05 +02:00
Malek TellissiandClaude Sonnet 4.6 352f2a0aac Remove standalone BatchResource — chargen managed via product relation manager
Deploy / deploy (push) Successful in 14s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 21:16:52 +02:00
Malek TellissiandClaude Sonnet 4.6 1290ab934e Update README: document lot_number format, add suppliers table to schema
Deploy / deploy (push) Successful in 10s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 20:59:09 +02:00
Malek TellissiandClaude Sonnet 4.6 b90c00cf34 Fix lot_suffix input: switch to live(onBlur) to prevent typing interference
Deploy / deploy (push) Successful in 14s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 20:40:00 +02:00
Malek TellissiandClaude Sonnet 4.6 5c034ec895 Add lot_prefix to products; compose LOT number from prefix + date suffix
Deploy / deploy (push) Successful in 14s
Products now have a configurable lot_prefix (e.g. "112"). In the batch form
the prefix is shown read-only next to the suffix input (JJMMTT), and the full
lot_number (e.g. "112-260912") is composed automatically and stored.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 20:35:37 +02:00
Malek TellissiandClaude Sonnet 4.6 e9734c2590 Preserve existing origin entries when switching recipe version
Deploy / deploy (push) Successful in 14s
When the recipe is changed in a batch form, keep origin data for spices
that exist in both the old and new recipe. Only add empty rows for
spices that are new to the selected recipe version.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 20:20:07 +02:00
Malek TellissiandClaude Sonnet 4.6 769d91465f Update README: LOT API origins array, updated DB schema
Deploy / deploy (push) Successful in 9s
Reflects nested batch_origin_entries structure, farmers table,
decimal(6,2) precision fix for recipes_spices.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 20:09:20 +02:00
Malek TellissiandClaude Sonnet 4.6 7c0fde4fd5 Update LOT API to use nested batch_origin_entries structure
Deploy / deploy (push) Successful in 14s
Each spice now returns an `origins` array (was single `origin` object) with
supplier and farmer resolved from the new entries relation, not flat columns.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 20:07:53 +02:00
Malek TellissiandClaude Sonnet 4.6 4a98beeb45 Restructure batch origins: nested entries per ingredient with Supplier/Farmer selects
Deploy / deploy (push) Successful in 14s
Each BatchOrigin (spice) now has multiple BatchOriginEntry rows, replacing the flat
single-supplier/farmer fields. Lieferant and Landwirt are Select fields backed by
dedicated tables with inline create support. Migration preserves existing data.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 20:03:05 +02:00
Malek TellissiandClaude Sonnet 4.6 400237aa5b Allow multiple supplier/farmer entries per ingredient in batch origins
Deploy / deploy (push) Successful in 14s
Each batch origin row now shows a searchable Rohstoff Select so the same
ingredient can appear in multiple rows with different suppliers or farmers.
Pre-fill from recipe still works (one row per ingredient); user clicks
'Eintrag hinzufügen' to add a second entry for the same ingredient.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 19:46:17 +02:00
Malek TellissiandClaude Sonnet 4.6 2dffe6f695 Pre-fill batch origins from recipe in standalone BatchResource
Deploy / deploy (push) Successful in 14s
Selecting a Produkt auto-sets the current Rezeptur and pre-fills one
Herkunft row per Rohstoff. Changing the Rezeptur resets the rows.
Rohstoff is shown read-only (Hidden + Placeholder); user fills in
supplier, origin country, farmer and notes only.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 19:00:45 +02:00
Malek TellissiandClaude Sonnet 4.6 62be3761a9 Pre-fill batch origin rows from recipe spices automatically
Deploy / deploy (push) Successful in 14s
When creating a new batch, the Herkunft-Repeater is automatically populated
with one row per Rohstoff from the product's current recipe. The Rohstoff
field is shown as a read-only label (Hidden spice_id + Placeholder name)
so the user only fills in supplier, origin country, farmer and notes.

Changing the recipe field updates the origin rows accordingly.
On edit, existing origin data is preserved unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 18:54:00 +02:00
Malek TellissiandClaude Sonnet 4.6 6f78b22285 Rewrite RecipeHistory without InteractsWithTable to fix 404
Deploy / deploy (push) Successful in 17s
The Filament table boot lifecycle (bootedInteractsWithTable) fires before
mount(), causing issues with typed $record properties on custom resource
pages. Replaced with a plain Page + Blade view rendering recipes directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 18:38:37 +02:00
Malek TellissiandClaude Sonnet 4.6 dd710cb1c0 Fix 404 on recipe history page
Deploy / deploy (push) Successful in 14s
bootedInteractsWithTable() calls table() before mount() sets $this->record.
Accessing $this->record eagerly causes a TypeError on the uninitialized typed
property, which Filament/Livewire converts to a 404.

Deferred all $this->record accesses into closures so they only execute at
render time (after mount() has run).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 18:30:07 +02:00
Malek TellissiandClaude Sonnet 4.6 656b105cb9 Show Shopify product ID as read-only field next to product name
Deploy / deploy (push) Successful in 14s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 18:24:44 +02:00
Malek TellissiandClaude Sonnet 4.6 3301a1e9b2 Fix 500 on recipe save and surface errors as notifications
Deploy / deploy (push) Successful in 14s
- Fix root cause: recipes_spices.amount_in_percent was decimal(4,2) which
  overflows on 100% — widened to decimal(6,2) via migration
- Wrap afterSave() in try-catch so DB/logic errors show as a persistent
  danger notification instead of a blank 500 page
- Same for CreateProduct: errors show as notification; also reads
  recipe_spices from raw Livewire $this->data (not $data param which
  excludes dehydrated(false) fields) so recipes actually save on create

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 18:19:31 +02:00
Malek TellissiandClaude Sonnet 4.6 811f5a015e Add Shopify pull-from feature and fix product creation payload
Deploy / deploy (push) Successful in 14s
- Add "Aus Shopify laden" button on product edit page that pulls description
  and variant prices/SKUs/GTINs from Shopify back into SMS
- Add ShopifyService::getProduct() for fetching a single product
- Add 'options' to createProduct() payload so Shopify properly creates variants
  (without it Shopify ignores variant option values)
- Add request/response logging to createProduct() for diagnosing transfer issues
- Remove dead code from ProductResource (mutateFormData*, getRecord, getActions)
- Clean up imports in ProductResource

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 18:07:24 +02:00
Malek TellissiandClaude Sonnet 4.6 9ef24fc45f Fix 500 on product create: remove $arguments from render-time closures
Deploy / deploy (push) Successful in 15s
In Filament v3, $arguments is only injected when an action is executed
(clicked), not when it's rendered. Using $arguments in label(), icon(),
color() and visible() closures causes ErrorException: Undefined variable
$arguments on every Livewire update, including on the create page.

Simplified extraItemAction to static label/icon/color; all dynamic
logic (publish vs sync, guard for unsaved items) stays in action().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 17:39:58 +02:00
Malek TellissiandClaude Sonnet 4.6 74b47193d9 Hide 'publish to Shopify' button if any variant already has a shopify_variant_id
Deploy / deploy (push) Successful in 15s
Products imported before shopify_product_id column was added have null
there, but their variants already carry shopify_variant_id — that's
enough to know the product exists in Shopify. Running shopify:import
once will backfill shopify_product_id for all existing products.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 17:25:53 +02:00
Malek TellissiandClaude Sonnet 4.6 3450b06e32 Reload page after publishing variant to Shopify so badge updates
Deploy / deploy (push) Successful in 14s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 17:23:18 +02:00
Malek TellissiandClaude Sonnet 4.6 6fe34883c6 Add 'Publish to Shopify' for locally-created products
Deploy / deploy (push) Successful in 14s
New header action on the product edit page creates the entire product
(title, description, all variants) in Shopify via API. The returned
shopify_product_id and per-variant shopify_variant_ids are stored
locally. After success the page reloads so status badges update.
Button is hidden once the product is already linked to Shopify.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 17:22:37 +02:00
Malek TellissiandClaude Sonnet 4.6 3ebd9845b0 Add Shopify publish/sync per product variant
Deploy / deploy (push) Successful in 14s
Each size row in the product form now shows a Shopify status badge
(green ✓ Shopify / gray Lokal). For saved variants, an action button
appears: 'Zu Shopify' for local-only variants (creates via Shopify
API and stores the returned variant ID), 'Shopify sync' for linked
variants (pushes price/SKU/GTIN to Shopify).

Also fixes:
- gtin missing from ProductSize::$fillable (was silently not saved)
- shopify_product_id added to products table and stored on import
- sizes afterStateHydrated now loads ProductSize directly instead of
  via the belongsToMany pivot (gets product_size_id, shopify_variant_id)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 17:20:26 +02:00
Malek TellissiandClaude Sonnet 4.6 e187465553 Fix syncSizes: replace belongsToMany sync with ProductSize updateOrCreate
Deploy / deploy (push) Successful in 14s
belongsToMany sync() is wrong for products_sizes which is a full model
with its own id and a unique shopify_variant_id. The new approach:
- updateOrCreate per row (safe for repeated saves)
- strips non-digits from gtin, stores null when empty (fixes 500 on
  unsignedBigInteger column with empty string in strict SQL mode)
- only deletes local-only sizes (whereNull shopify_variant_id) that
  were removed — Shopify-imported sizes are never deleted here

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 17:00:58 +02:00
Malek TellissiandClaude Sonnet 4.6 538053d36e Restrict API subdomain to /api/* paths in Caddy config
Deploy / deploy (push) Successful in 9s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 16:48:03 +02:00
Malek TellissiandClaude Sonnet 4.6 6f0c94cc21 Update API subdomain docs to use Caddy reverse proxy
Deploy / deploy (push) Successful in 9s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 16:44:08 +02:00
Malek TellissiandClaude Sonnet 4.6 e14baca7e0 Add LOT API v1 endpoint with full batch details
Deploy / deploy (push) Successful in 15s
Route changed to /api/v1/{lot_number}. LotResource now includes
packing details, units_produced, quantity_g and recipe version.
CORS config added for public API access. README documents the
endpoint, example response and subdomain setup instructions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 16:43:48 +02:00
Malek TellissiandClaude Sonnet 4.6 269570c7d6 Remove recipe name field; use product title internally
Deploy / deploy (push) Successful in 15s
The recipe name input is dropped from the product form — the version
number alone identifies a recipe. The product title is stored as the
internal name to satisfy the NOT NULL constraint. The history table
no longer shows the name column.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 06:00:18 +02:00
Malek TellissiandClaude Sonnet 4.6 a7e7375edd Add recipe versioning: auto-bump on change, history sub-page
Deploy / deploy (push) Successful in 16s
Each time the recipe name or spices are changed on the product edit
page, a new version is created instead of overwriting the current one.
Unchanged saves are skipped. A 'Rezept-Versionen' button opens a
sub-page (/produkt/{id}/rezept-versionen) listing all versions with
their spices and timestamps; the active version is highlighted in green.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 05:52:59 +02:00
Malek TellissiandClaude Sonnet 4.6 4775cffaae Embed recipe editing directly on product page
Deploy / deploy (push) Successful in 14s
Replaces the recipe dropdown with an inline Section containing a name
field and a spice-repeater with percentage inputs. On save, the recipe
is created (version 1) or updated in place; spice pivot rows are synced
via sync(). SumEquals100 rule enforces that percentages add up to 100.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 05:43:37 +02:00
Malek TellissiandClaude Sonnet 4.6 af55857883 Update README: batch deduction, recipe versioning, current DB schema
Deploy / deploy (push) Successful in 10s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 05:34:57 +02:00
Malek TellissiandClaude Sonnet 4.6 a34bb29620 Auto-deduct spice inventory when batch is created/updated/deleted
Deploy / deploy (push) Successful in 14s
- Add size_id, units_produced, quantity_g to batches table
- quantity_g auto-calculated from units × packing size on save
- Batch model deducts spice quantities on create, reverses on delete,
  recalculates on update when relevant fields change
- Batch form shows live total weight preview
- Chargen table shows units + grams produced

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 05:34:09 +02:00
Malek TellissiandClaude Sonnet 4.6 1e93aaa7d8 Make description read-only and auto-sized using Placeholder
Deploy / deploy (push) Successful in 14s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 05:22:32 +02:00
Malek TellissiandClaude Sonnet 4.6 a12502418b Display product images in grid layout with 200px preview height
Deploy / deploy (push) Successful in 14s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 05:20:40 +02:00
Malek TellissiandClaude Sonnet 4.6 a7f5c4a83e Recipe versioning, inline recipe create, recipe summary, Shopify description
Deploy / deploy (push) Successful in 15s
- Add version + product_id to recipes table (migration)
- Recipe select shows version label (e.g. "Kurkuma v2")
- Creating recipe from product page pre-fills product name, auto-increments version
- Recipe ingredient summary shown read-only below the select
- Remove package_content field (redundant with recipe ingredients)
- Pull product description from Shopify body_html on import
- Update existing products with empty description on re-import

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 05:18:11 +02:00
Malek TellissiandClaude Sonnet 4.6 6e28984278 Add recipe inline create/edit and batches relation on product page
Deploy / deploy (push) Successful in 14s
- Recipe select now has a create/edit modal (name + description)
- Batches RelationManager shows all LOT charges for the product below
  the form, sorted newest first, with create/edit/delete actions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 05:10:04 +02:00
Malek TellissiandClaude Sonnet 4.6 e959faff8d Fix barcode 500 error, GTIN mask formatting, and add price sync
Deploy / deploy (push) Successful in 15s
- Wrap barcode generation in try-catch to prevent 500 on invalid GTIN
- Move barcode preview above GTIN input field
- Add input mask (X XXXXXX XXXXXX) and strip non-digits before save/render
- Only render barcode when >= 8 digits present
- shopify:sync now updates price alongside inventory

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 04:59:46 +02:00
Malek TellissiandClaude Sonnet 4.6 25b32c717b Add SKU/GTIN fields, live barcode preview, and Shopify price import
Deploy / deploy (push) Successful in 26s
- Add SKU and GTIN fields to product variant repeater
- Render EAN/UPC barcode live from GTIN input (picqer/php-barcode-generator)
- Pull variant price from Shopify API instead of defaulting to 0
- Sync sku/gtin through EditProduct and CreateProduct save logic

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 04:46:00 +02:00
Malek TellissiandClaude Sonnet 4.6 35cacb2e99 Replace storage:link with explicit ln -sf to fix broken symlink
Deploy / deploy (push) Successful in 14s
php artisan storage:link was creating a regular file instead of a
symlink, causing 404s for all uploaded images.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 04:36:42 +02:00
Malek TellissiandClaude Sonnet 4.6 cb7765bbcc Ensure storage directories exist before storage:link in entrypoint
Deploy / deploy (push) Successful in 14s
The Docker volume replaces storage/app/ with an empty volume on first
run, so storage/app/public/ must be created explicitly before the
storage:link symlink is registered.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 04:33:44 +02:00
Malek TellissiandClaude Sonnet 4.6 e34020e5bd Update README: Docker setup, artisan-in-container, Shopify commands
Deploy / deploy (push) Successful in 10s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 04:30:04 +02:00
Malek TellissiandClaude Sonnet 4.6 2024f060f1 Run artisan inside container instead of on host (PHP version mismatch)
Deploy / deploy (push) Successful in 14s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 04:27:14 +02:00
Malek TellissiandClaude Sonnet 4.6 9752e7db4c Fix composer install dir: use \$HOME instead of ~ in deploy script
Deploy / deploy (push) Failing after 8s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 04:25:12 +02:00
Malek TellissiandClaude Sonnet 4.6 4e53c9a310 Install composer on host during deploy so artisan commands work directly
Deploy / deploy (push) Failing after 7s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 04:22:59 +02:00
Malek TellissiandClaude Sonnet 4.6 822790bfc0 Improve image import logging and move HTTP downloads out of DB transaction
Deploy / deploy (push) Successful in 16s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 04:16:12 +02:00