diff --git a/.paul/codebase/concerns.md b/.paul/codebase/concerns.md index 5e60c2f..e5f16ae 100644 --- a/.paul/codebase/concerns.md +++ b/.paul/codebase/concerns.md @@ -31,7 +31,15 @@ | `Web:S6827` — Anchors without accessible text | 9+ | MINOR | Icon-only buttons need `aria-label` | | `Web:S6819` — Accessibility | 7+ | MAJOR | Use `` instead of `` | -**Note:** SonarQube scan not run for phases 105–107 — baseline may be stale. +**Note:** SonarQube scan not run for phases 105–108 — baseline may be stale. + +## Breaking Changes + +| Change | Phase | Impact | Migration | +|--------|-------|--------|-----------| +| Delivery status group keys przeniesione do DB | Phase 108 (2026-04-27) | Stare reguły automation z kluczami `registered`, `courier_pickup`, `dropped_at_point`, `unclaimed`, `picked_up` przestają działać | Operatorzy muszą ręcznie odtworzyć reguły w UI | +| `SHIPMENT_STATUS_OPTION_MAP` usunięty | Phase 108 (2026-04-27) | `AutomationService` porównuje klucze statusów bezpośrednio z DB | Brak wpływu po odtworzeniu reguł | +| `_csrf_token` → `_token` | Phase 105 (2026-04-19) | Stare nazwy pól formularzy | Sprawdzić czy nie ma starych referencji `_csrf_token` w widokach | ## Known Bugs & Issues diff --git a/.paul/codebase/db_schema.md b/.paul/codebase/db_schema.md new file mode 100644 index 0000000..3554783 --- /dev/null +++ b/.paul/codebase/db_schema.md @@ -0,0 +1,852 @@ +# Database Schema + +**Updated:** 2026-04-28 | **Total tables:** 55 | **Engine:** InnoDB | **Charset:** utf8mb4_unicode_ci + +--- + +## Auth / Users + +**users** — System user accounts with authentication +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK, AUTO_INCREMENT | +| `name` | VARCHAR(120) | NO | | +| `email` | VARCHAR(190) | NO | UNIQUE | +| `password_hash` | VARCHAR(255) | NO | | +| `remember_token` | VARCHAR(255) | YES | SHA256 of cookie token | +| `created_at` | DATETIME | NO | DEFAULT CURRENT_TIMESTAMP | + +--- + +## Products + +**products** — Main product catalog +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `uuid` | CHAR(36) | NO | UNIQUE | +| `type` | ENUM('simple','variant_parent') | NO | DEFAULT 'simple' | +| `sku` | VARCHAR(128) | YES | UNIQUE | +| `ean` | VARCHAR(32) | YES | | +| `status` | TINYINT(1) | NO | DEFAULT 1 | +| `promoted` | TINYINT(1) | NO | DEFAULT 0 | +| `new_to_date` | DATE | YES | | +| `additional_message` | TINYINT(1) | NO | DEFAULT 0 | +| `additional_message_required` | TINYINT(1) | NO | DEFAULT 0 | +| `additional_message_text` | TEXT | YES | | +| `vat` | DECIMAL(5,2) | YES | | +| `weight` | DECIMAL(10,3) | YES | | +| `price_brutto` | DECIMAL(12,2) | NO | DEFAULT 0.00 | +| `price_brutto_promo` | DECIMAL(12,2) | YES | | +| `price_netto` | DECIMAL(12,2) | YES | | +| `price_netto_promo` | DECIMAL(12,2) | YES | | +| `quantity` | DECIMAL(12,3) | NO | DEFAULT 0.000 | +| `producer_id` | INT UNSIGNED | YES | | +| `producer_name` | VARCHAR(255) | YES | | +| `product_unit_id` | INT UNSIGNED | YES | | +| `custom_fields_json` | TEXT | YES | | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | ON UPDATE CURRENT_TIMESTAMP | +| `deleted_at` | DATETIME | YES | Soft delete | + +Indexes: `products_status_idx`, `products_type_idx`, `products_updated_at_idx`, `products_ean_idx` + +**product_translations** — Localized product names/descriptions +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `product_id` | INT UNSIGNED | NO | FK → products(id) CASCADE | +| `lang` | VARCHAR(8) | NO | | +| `name` | VARCHAR(255) | NO | | +| `short_description` | TEXT | YES | | +| `description` | LONGTEXT | YES | | +| `meta_title` | VARCHAR(255) | YES | | +| `meta_description` | VARCHAR(255) | YES | | +| `meta_keywords` | VARCHAR(255) | YES | | +| `seo_link` | VARCHAR(255) | YES | | +| `security_information` | MEDIUMTEXT | YES | GPSR data | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +UNIQUE: `(product_id, lang)` + +**product_images** — Product image storage references +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `product_id` | INT UNSIGNED | NO | FK → products(id) CASCADE | +| `storage_path` | VARCHAR(255) | NO | | +| `alt` | VARCHAR(255) | YES | | +| `sort_order` | INT | NO | DEFAULT 0 | +| `is_main` | TINYINT(1) | NO | DEFAULT 0 | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +**product_categories** — Product–category associations (m2m) +| Column | Type | Notes | +|--------|------|-------| +| `product_id` | INT UNSIGNED | FK → products(id) CASCADE | +| `category_id` | INT UNSIGNED | | +| `created_at` | DATETIME | | + +PK: `(product_id, category_id)` + +**product_variants** — Variants for `variant_parent` products +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `product_id` | INT UNSIGNED | NO | FK → products(id) CASCADE | +| `permutation_hash` | VARCHAR(191) | NO | | +| `sku` | VARCHAR(128) | YES | UNIQUE | +| `ean` | VARCHAR(32) | YES | | +| `status` | TINYINT(1) | NO | DEFAULT 1 | +| `stock_0_buy` | TINYINT(1) | NO | DEFAULT 0 | +| `price_brutto` | DECIMAL(12,2) | YES | | +| `price_netto` | DECIMAL(12,2) | YES | | +| `weight` | DECIMAL(10,3) | YES | | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +UNIQUE: `(product_id, permutation_hash)` + +**product_variant_attributes** — Variant–attribute value mapping +| Column | Type | Notes | +|--------|------|-------| +| `variant_id` | INT UNSIGNED | FK → product_variants(id) CASCADE | +| `attribute_id` | INT UNSIGNED | FK → attributes(id) RESTRICT | +| `value_id` | INT UNSIGNED | FK → attribute_values(id) RESTRICT | +| `created_at` | DATETIME | | + +PK: `(variant_id, attribute_id)` + +**attributes** — Attribute definitions (e.g., size, color) +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `type` | TINYINT UNSIGNED | NO | DEFAULT 1 | +| `status` | TINYINT(1) | NO | DEFAULT 1 | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +**attribute_translations** — Localized attribute names +| Column | Type | Notes | +|--------|------|-------| +| `attribute_id` | INT UNSIGNED | FK → attributes(id) CASCADE | +| `lang` | VARCHAR(8) | | +| `name` | VARCHAR(255) | | +| `created_at` | DATETIME | | +| `updated_at` | DATETIME | | + +PK: `(attribute_id, lang)` + +**attribute_values** — Possible values per attribute +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `attribute_id` | INT UNSIGNED | NO | FK → attributes(id) CASCADE | +| `status` | TINYINT(1) | NO | DEFAULT 1 | +| `is_default` | TINYINT(1) | NO | DEFAULT 0 | +| `impact_on_price` | DECIMAL(12,2) | YES | | +| `sort_order` | INT | NO | DEFAULT 0 | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +**attribute_value_translations** — Localized value names +| Column | Type | Notes | +|--------|------|-------| +| `value_id` | INT UNSIGNED | FK → attribute_values(id) CASCADE | +| `lang` | VARCHAR(8) | | +| `name` | VARCHAR(255) | | +| `created_at` | DATETIME | | +| `updated_at` | DATETIME | | + +PK: `(value_id, lang)` + +**product_change_log** — Audit trail for product modifications +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `product_id` | INT UNSIGNED | NO | FK → products(id) CASCADE | +| `user_id` | INT UNSIGNED | YES | FK → users(id) SET NULL | +| `change_type` | VARCHAR(64) | NO | | +| `before_json` | JSON | YES | | +| `after_json` | JSON | YES | | +| `created_at` | DATETIME | NO | | + +**sales_channels** — Selling channel definitions +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `code` | VARCHAR(64) | NO | UNIQUE | +| `name` | VARCHAR(128) | NO | | +| `type` | VARCHAR(64) | NO | | +| `status` | TINYINT(1) | NO | DEFAULT 1 | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +**product_channel_map** — Link products to external channel offers +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `product_id` | INT UNSIGNED | NO | FK → products(id) CASCADE | +| `channel_id` | INT UNSIGNED | NO | FK → sales_channels(id) CASCADE | +| `integration_id` | INT UNSIGNED | YES | FK → integrations(id) SET NULL | +| `external_product_id` | VARCHAR(128) | YES | | +| `external_variant_id` | VARCHAR(128) | YES | | +| `sync_state` | VARCHAR(32) | NO | DEFAULT 'not_linked' | +| `link_type` | VARCHAR(32) | NO | DEFAULT 'manual' | +| `link_status` | VARCHAR(32) | NO | DEFAULT 'active' | +| `confidence` | TINYINT UNSIGNED | YES | | +| `linked_at` | DATETIME | YES | | +| `unlinked_at` | DATETIME | YES | | +| `sync_meta_json` | JSON | YES | | +| `last_sync_at` | DATETIME | YES | | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +UNIQUE: `(product_id, channel_id, external_product_id, external_variant_id)` + +**channel_offers** — External channel offer snapshots +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `integration_id` | INT UNSIGNED | NO | FK → integrations(id) CASCADE | +| `channel_id` | INT UNSIGNED | NO | FK → sales_channels(id) CASCADE | +| `external_product_id` | VARCHAR(128) | NO | | +| `external_variant_id` | VARCHAR(128) | YES | | +| `external_offer_id` | VARCHAR(128) | YES | | +| `name` | VARCHAR(255) | NO | | +| `sku` | VARCHAR(128) | YES | | +| `ean` | VARCHAR(32) | YES | | +| `price_brutto` | DECIMAL(12,2) | YES | | +| `quantity` | DECIMAL(12,3) | YES | | +| `currency` | VARCHAR(8) | YES | | +| `offer_status` | VARCHAR(32) | NO | DEFAULT 'active' | +| `source_updated_at` | DATETIME | YES | | +| `last_seen_at` | DATETIME | NO | | +| `payload_json` | JSON | YES | | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +UNIQUE: `(integration_id, external_product_id, external_variant_id)` + +**product_link_events** — Audit log for product-channel linking changes + +**product_link_alerts** — Alerts for product-channel link issues (ENUM status: `active`, `resolved`) + +**product_integration_translations** — Integration-specific product description overrides + +--- + +## Orders + +**orders** — Imported orders from sales channels +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `internal_order_number` | VARCHAR(11) | YES | UNIQUE, auto-assigned | +| `integration_id` | INT UNSIGNED | NO | FK → integrations(id) CASCADE | +| `external_order_id` | VARCHAR(64) | NO | | +| `external_order_number` | VARCHAR(128) | YES | | +| `status` | VARCHAR(64) | YES | Internal status code | +| `currency` | CHAR(3) | YES | | +| `total_gross` | DECIMAL(12,2) | YES | | +| `total_net` | DECIMAL(12,2) | YES | | +| `total_with_tax` | DECIMAL(12,2) | YES | | +| `total_paid` | DECIMAL(12,2) | YES | | +| `buyer_email` | VARCHAR(190) | YES | | +| `buyer_name` | VARCHAR(190) | YES | | +| `buyer_phone` | VARCHAR(64) | YES | | +| `payment_method` | VARCHAR(128) | YES | | +| `payment_status` | VARCHAR(64) | YES | | +| `external_payment_type_id` | VARCHAR(128) | YES | | +| `delivery_method` | VARCHAR(128) | YES | | +| `delivery_price` | DECIMAL(12,2) | YES | | +| `delivery_tracking_number` | VARCHAR(128) | YES | | +| `notes` | TEXT | YES | | +| `external_created_at` | DATETIME | YES | | +| `external_updated_at` | DATETIME | YES | | +| `last_status_checked_at` | DATETIME | YES | | +| `payload_json` | JSON | YES | Full raw API payload | +| `fetched_at` | DATETIME | NO | | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +UNIQUE: `(integration_id, external_order_id)` + +**order_items** — Line items within orders +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `order_id` | INT UNSIGNED | NO | FK → orders(id) CASCADE | +| `external_item_id` | VARCHAR(64) | YES | | +| `name` | VARCHAR(255) | NO | | +| `sku` | VARCHAR(128) | YES | | +| `ean` | VARCHAR(64) | YES | | +| `quantity` | DECIMAL(12,3) | NO | DEFAULT 0 | +| `price_gross` | DECIMAL(12,2) | YES | | +| `price_net` | DECIMAL(12,2) | YES | | +| `vat` | DECIMAL(6,2) | YES | | +| `personalization` | TEXT | YES | Customer personalization data for design generation | +| `project_generated` | TINYINT(1) | NO | DEFAULT 0 | +| `project_generated_at` | DATETIME | YES | | +| `payload_json` | JSON | YES | | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +**order_activity_log** — Event log for order state changes +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | BIGINT UNSIGNED | NO | PK | +| `order_id` | BIGINT UNSIGNED | NO | FK → orders(id) CASCADE | +| `event_type` | VARCHAR(32) | NO | | +| `summary` | VARCHAR(255) | NO | | +| `details_json` | JSON | YES | | +| `actor_type` | VARCHAR(16) | NO | DEFAULT 'system' | +| `actor_name` | VARCHAR(128) | YES | | +| `created_at` | DATETIME | NO | | + +**order_payments** — Payments linked to orders +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `order_id` | INT UNSIGNED | NO | FK → orders(id) CASCADE | +| `source_payment_id` | VARCHAR(64) | YES | | +| `external_payment_id` | VARCHAR(64) | YES | | +| `payment_type_id` | VARCHAR(64) | NO | | +| `payment_date` | DATETIME | YES | | +| `amount` | DECIMAL(12,2) | YES | | +| `currency` | CHAR(3) | YES | | +| `comment` | VARCHAR(255) | YES | | +| `payload_json` | JSON | YES | | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +UNIQUE: `(order_id, source_payment_id)` + +--- + +## Order Statuses + +**order_status_groups** — Status group categories (e.g., "Nowe", "W realizacji") +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `name` | VARCHAR(120) | NO | | +| `code` | VARCHAR(64) | NO | UNIQUE | +| `color_hex` | CHAR(7) | NO | DEFAULT '#64748b' | +| `sort_order` | INT | NO | DEFAULT 0 | +| `is_active` | TINYINT(1) | NO | DEFAULT 1 | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +**order_statuses** — Individual statuses within groups +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `group_id` | INT UNSIGNED | NO | FK → order_status_groups(id) CASCADE | +| `name` | VARCHAR(120) | NO | | +| `code` | VARCHAR(64) | NO | UNIQUE | +| `sort_order` | INT | NO | DEFAULT 0 | +| `is_active` | TINYINT(1) | NO | DEFAULT 1 | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +**order_status_mappings** — Map external (e.g., shopPRO) statuses to internal ones +| Column | Type | Notes | +|--------|------|-------| +| `id` | INT UNSIGNED | PK | +| `integration_id` | INT UNSIGNED | FK → integrations(id) CASCADE | +| `shoppro_status_code` | VARCHAR(64) | | +| `shoppro_status_name` | VARCHAR(128) | | +| `orderpro_status_code` | VARCHAR(64) | | +| `created_at` | DATETIME | | +| `updated_at` | DATETIME | | + +UNIQUE: `(integration_id, shoppro_status_code)` + +**integration_order_sync_state** — Track order fetch progress per integration + +**integration_order_status_sync_state** — Track status sync progress per integration and direction + +--- + +## Shipments & Delivery + +**shipment_packages** — Prepared shipments with tracking +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | BIGINT UNSIGNED | NO | PK | +| `order_id` | BIGINT UNSIGNED | NO | FK → orders(id) CASCADE | +| `provider` | VARCHAR(32) | NO | DEFAULT 'allegro_wza' | +| `delivery_method_id` | VARCHAR(128) | YES | | +| `credentials_id` | VARCHAR(128) | YES | | +| `command_id` | VARCHAR(64) | YES | | +| `shipment_id` | VARCHAR(64) | YES | | +| `tracking_number` | VARCHAR(128) | YES | | +| `status` | VARCHAR(32) | NO | DEFAULT 'draft' | +| `delivery_status` | VARCHAR(32) | NO | DEFAULT 'unknown' | +| `delivery_status_raw` | VARCHAR(128) | YES | Provider's original status string | +| `delivery_status_updated_at` | DATETIME | YES | | +| `carrier_id` | VARCHAR(64) | YES | | +| `package_type` | VARCHAR(16) | NO | DEFAULT 'PACKAGE' | +| `weight_kg` | DECIMAL(8,3) | YES | | +| `length_cm` | DECIMAL(8,1) | YES | | +| `width_cm` | DECIMAL(8,1) | YES | | +| `height_cm` | DECIMAL(8,1) | YES | | +| `insurance_amount` | DECIMAL(12,2) | YES | | +| `cod_amount` | DECIMAL(12,2) | YES | | +| `label_format` | VARCHAR(8) | NO | DEFAULT 'PDF' | +| `label_path` | VARCHAR(512) | YES | | +| `receiver_point_id` | VARCHAR(64) | YES | Parcel locker ID | +| `sender_point_id` | VARCHAR(64) | YES | | +| `reference_number` | VARCHAR(128) | YES | | +| `error_message` | TEXT | YES | | +| `payload_json` | JSON | YES | | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +Indexes: `shipment_packages_order_idx`, `shipment_packages_status_idx`, `shipment_packages_tracking_idx`, `idx_delivery_status` + +**shipment_presets** — Predefined shipment configurations (saved templates) +| Column | Type | Notes | +|--------|------|-------| +| `id` | BIGINT UNSIGNED | PK | +| `name` | VARCHAR(100) | | +| `color` | VARCHAR(7) | DEFAULT '#3b82f6' | +| `carrier` | VARCHAR(32) | | +| `provider_code` | VARCHAR(32) | | +| `delivery_method_id` | VARCHAR(128) | | +| `credentials_id` | VARCHAR(128) | DEFAULT '' | +| `carrier_id` | VARCHAR(64) | DEFAULT '' | +| `package_type` | VARCHAR(16) | DEFAULT 'PACKAGE' | +| `length_cm` | DECIMAL(8,1) | DEFAULT 25.0 | +| `width_cm` | DECIMAL(8,1) | DEFAULT 20.0 | +| `height_cm` | DECIMAL(8,1) | DEFAULT 8.0 | +| `weight_kg` | DECIMAL(8,3) | DEFAULT 1.000 | +| `sender_point_id` | VARCHAR(64) | DEFAULT '' | +| `label_format` | VARCHAR(8) | DEFAULT 'PDF' | +| `sort_order` | INT UNSIGNED | DEFAULT 0 | +| `created_at` | TIMESTAMP | | +| `updated_at` | TIMESTAMP | | + +**delivery_statuses** — Normalized delivery status definitions (Phase 108) +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `key` | VARCHAR(50) | NO | UNIQUE | +| `label_pl` | VARCHAR(100) | NO | Polish label | +| `color` | VARCHAR(7) | NO | DEFAULT '#6c757d' | +| `sort_order` | TINYINT UNSIGNED | NO | DEFAULT 0 | +| `is_terminal` | TINYINT(1) | NO | DEFAULT 0 — marks final states | +| `is_system` | TINYINT(1) | NO | DEFAULT 0 — system-managed | +| `created_at` | DATETIME | NO | | + +**delivery_status_mappings** — Map provider-specific raw statuses to normalized keys (Phase 108) +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `provider` | VARCHAR(32) | NO | | +| `raw_status` | VARCHAR(64) | NO | | +| `normalized_status` | VARCHAR(32) | NO | FK ref → delivery_statuses.key | +| `description` | VARCHAR(255) | NO | DEFAULT '' | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +UNIQUE: `(provider, raw_status)` + +--- + +## Integrations + +**integrations** — Integration configurations for external services +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `type` | VARCHAR(32) | NO | e.g., 'allegro', 'shoppro', 'apaczka', 'inpost' | +| `name` | VARCHAR(128) | NO | | +| `base_url` | VARCHAR(255) | NO | | +| `api_key_encrypted` | TEXT | YES | AES-encrypted | +| `timeout_seconds` | SMALLINT UNSIGNED | NO | DEFAULT 10 | +| `is_active` | TINYINT(1) | NO | DEFAULT 1 | +| `orders_fetch_enabled` | TINYINT(1) | NO | DEFAULT 0 | +| `orders_fetch_start_date` | DATE | YES | | +| `order_status_sync_direction` | VARCHAR(32) | NO | DEFAULT 'shoppro_to_orderpro' | +| `last_test_status` | VARCHAR(16) | YES | | +| `last_test_http_code` | SMALLINT UNSIGNED | YES | | +| `last_test_message` | VARCHAR(255) | YES | | +| `last_test_at` | DATETIME | YES | | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +UNIQUE: `(type, name)` + +**integration_test_logs** — API test results log + +**allegro_integration_settings** — Allegro OAuth tokens and API config +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `integration_id` | INT UNSIGNED | YES | UNIQUE, FK → integrations(id) CASCADE | +| `environment` | VARCHAR(16) | NO | DEFAULT 'sandbox' | +| `client_id` | VARCHAR(128) | YES | | +| `client_secret_encrypted` | TEXT | YES | | +| `redirect_uri` | VARCHAR(255) | YES | | +| `orders_fetch_enabled` | TINYINT(1) | NO | DEFAULT 0 | +| `orders_fetch_start_date` | DATE | YES | | +| `access_token_encrypted` | MEDIUMTEXT | YES | AES-encrypted | +| `refresh_token_encrypted` | MEDIUMTEXT | YES | AES-encrypted | +| `token_type` | VARCHAR(32) | YES | | +| `token_scope` | VARCHAR(255) | YES | | +| `token_expires_at` | DATETIME | YES | | +| `connected_at` | DATETIME | YES | | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +**allegro_order_status_mappings** — Allegro status → internal status +| Column | Type | Notes | +|--------|------|-------| +| `id` | INT UNSIGNED | PK | +| `allegro_status_code` | VARCHAR(64) | UNIQUE | +| `allegro_status_name` | VARCHAR(120) | | +| `orderpro_status_code` | VARCHAR(64) | | +| `created_at` | DATETIME | | +| `updated_at` | DATETIME | | + +**allegro_delivery_method_mappings** — Map order delivery method strings to Allegro services +| Column | Type | Notes | +|--------|------|-------| +| `id` | INT UNSIGNED | PK | +| `order_delivery_method` | VARCHAR(200) | UNIQUE | +| `allegro_delivery_method_id` | VARCHAR(128) | | +| `allegro_credentials_id` | VARCHAR(128) | | +| `allegro_carrier_id` | VARCHAR(128) | | +| `allegro_service_name` | VARCHAR(255) | | +| `created_at` | DATETIME | | +| `updated_at` | DATETIME | | + +**apaczka_integration_settings** — Apaczka API credentials +| Column | Type | Notes | +|--------|------|-------| +| `id` | TINYINT UNSIGNED | PK (fixed 1 row) | +| `integration_id` | INT UNSIGNED | UNIQUE, FK → integrations(id) | +| `api_key_encrypted` | TEXT | | +| `created_at` | DATETIME | | +| `updated_at` | DATETIME | | + +**inpost_integration_settings** — InPost ShipX settings +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | TINYINT UNSIGNED | NO | PK (fixed 1 row) | +| `integration_id` | INT UNSIGNED | YES | UNIQUE, FK → integrations(id) | +| `api_token_encrypted` | TEXT | YES | | +| `organization_id` | VARCHAR(50) | YES | | +| `environment` | ENUM('sandbox','production') | NO | DEFAULT 'sandbox' | +| `default_dispatch_method` | ENUM('pop','parcel_locker','courier') | NO | DEFAULT 'pop' | +| `default_dispatch_point` | VARCHAR(50) | YES | | +| `default_insurance` | DECIMAL(10,2) | YES | | +| `default_locker_size` | ENUM('small','medium','large') | NO | DEFAULT 'small' | +| `default_courier_length` | SMALLINT UNSIGNED | YES | DEFAULT 20 | +| `default_courier_width` | SMALLINT UNSIGNED | YES | DEFAULT 15 | +| `default_courier_height` | SMALLINT UNSIGNED | YES | DEFAULT 8 | +| `label_format` | ENUM('Pdf','Zpl','Epl') | NO | DEFAULT 'Pdf' | +| `weekend_delivery` | TINYINT(1) | NO | DEFAULT 0 | +| `auto_insurance_value` | TINYINT(1) | NO | DEFAULT 0 | +| `multi_parcel` | TINYINT(1) | NO | DEFAULT 0 | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +--- + +## Accounting / Receipts + +**receipt_configs** — Receipt generation configurations +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `name` | VARCHAR(128) | NO | | +| `is_active` | TINYINT(1) | NO | DEFAULT 1 | +| `number_format` | VARCHAR(64) | NO | DEFAULT 'PAR/%N/%M/%Y' | +| `numbering_type` | ENUM('monthly','yearly') | NO | DEFAULT 'monthly' | +| `is_named` | TINYINT(1) | NO | DEFAULT 0 | +| `sale_date_source` | ENUM('order_date','payment_date','issue_date') | NO | DEFAULT 'issue_date' | +| `order_reference` | ENUM('none','orderpro','integration') | NO | DEFAULT 'none' | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +**receipts** — Generated receipts / invoices +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `order_id` | BIGINT UNSIGNED | NO | FK → orders(id) CASCADE | +| `config_id` | INT UNSIGNED | NO | FK → receipt_configs(id) RESTRICT | +| `receipt_number` | VARCHAR(64) | NO | UNIQUE | +| `issue_date` | DATETIME | NO | | +| `sale_date` | DATETIME | NO | | +| `seller_data_json` | JSON | NO | Snapshot of company data at issue time | +| `buyer_data_json` | JSON | YES | | +| `items_json` | JSON | NO | | +| `total_net` | DECIMAL(12,2) | NO | DEFAULT 0.00 | +| `total_gross` | DECIMAL(12,2) | NO | DEFAULT 0.00 | +| `order_reference_value` | VARCHAR(128) | YES | | +| `created_by` | INT UNSIGNED | YES | | +| `created_at` | DATETIME | NO | | + +**receipt_number_counters** — Sequential numbering per config/period +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `config_id` | INT UNSIGNED | NO | FK → receipt_configs(id) CASCADE | +| `year` | SMALLINT UNSIGNED | NO | | +| `month` | TINYINT UNSIGNED | YES | NULL for yearly numbering | +| `last_number` | INT UNSIGNED | NO | DEFAULT 0 | + +UNIQUE: `(config_id, year, month)` + +--- + +## Email + +**email_mailboxes** — SMTP mailbox configurations +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `name` | VARCHAR(100) | NO | | +| `smtp_host` | VARCHAR(255) | NO | | +| `smtp_port` | SMALLINT UNSIGNED | NO | DEFAULT 587 | +| `smtp_encryption` | ENUM('tls','ssl','none') | NO | DEFAULT 'tls' | +| `smtp_username` | VARCHAR(255) | NO | | +| `smtp_password_encrypted` | TEXT | NO | AES-encrypted | +| `sender_email` | VARCHAR(255) | NO | | +| `sender_name` | VARCHAR(200) | YES | | +| `html_layout` | LONGTEXT | YES | Wrapper HTML for all emails from this mailbox | +| `is_default` | TINYINT(1) | NO | DEFAULT 0 | +| `is_active` | TINYINT(1) | NO | DEFAULT 1 | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +**email_templates** — Email message templates with variable placeholders +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `name` | VARCHAR(200) | NO | | +| `subject` | VARCHAR(500) | NO | | +| `body_html` | TEXT | NO | Supports `{{variable}}` placeholders | +| `mailbox_id` | INT UNSIGNED | YES | FK → email_mailboxes(id) SET NULL | +| `attachment1` | LONGTEXT | YES | | +| `is_active` | TINYINT(1) | NO | DEFAULT 1 | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +**email_logs** — Sent email history +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | BIGINT UNSIGNED | NO | PK | +| `template_id` | INT UNSIGNED | YES | FK → email_templates(id) SET NULL | +| `mailbox_id` | INT UNSIGNED | YES | FK → email_mailboxes(id) SET NULL | +| `order_id` | INT UNSIGNED | YES | | +| `recipient_email` | VARCHAR(255) | NO | | +| `recipient_name` | VARCHAR(200) | YES | | +| `subject` | VARCHAR(500) | NO | | +| `body_html` | TEXT | NO | | +| `attachments_json` | JSON | YES | | +| `status` | ENUM('sent','failed','pending') | NO | DEFAULT 'pending' | +| `error_message` | TEXT | YES | | +| `sent_at` | DATETIME | YES | | +| `created_at` | DATETIME | NO | | + +--- + +## Automation + +**automation_rules** — Business rules for order event automation +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `name` | VARCHAR(128) | NO | | +| `event_type` | VARCHAR(64) | NO | e.g., 'order_status_changed', 'order_status_aged' | +| `is_active` | TINYINT(1) | NO | DEFAULT 1 | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +Index: `(event_type, is_active)` + +**automation_conditions** — Conditions for automation rules +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `rule_id` | INT UNSIGNED | NO | FK → automation_rules(id) CASCADE | +| `condition_type` | VARCHAR(64) | NO | | +| `condition_value` | JSON | NO | | +| `sort_order` | SMALLINT UNSIGNED | NO | DEFAULT 0 | + +**automation_actions** — Actions executed when rules trigger +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `rule_id` | INT UNSIGNED | NO | FK → automation_rules(id) CASCADE | +| `action_type` | VARCHAR(64) | NO | e.g., 'send_email', 'update_status', 'create_receipt' | +| `action_config` | JSON | NO | | +| `sort_order` | SMALLINT UNSIGNED | NO | DEFAULT 0 | + +**automation_execution_logs** — Audit log for rule executions +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | BIGINT UNSIGNED | NO | PK | +| `event_type` | VARCHAR(64) | NO | | +| `rule_id` | INT UNSIGNED | YES | FK → automation_rules(id) SET NULL | +| `rule_name` | VARCHAR(128) | NO | Snapshot at execution time | +| `order_id` | INT UNSIGNED | NO | FK → orders(id) CASCADE | +| `execution_status` | VARCHAR(16) | NO | | +| `result_message` | VARCHAR(500) | YES | | +| `context_json` | JSON | YES | | +| `executed_at` | DATETIME | NO | | +| `created_at` | DATETIME | NO | | + +**automation_email_once_deliveries** — Idempotency guard: email sent-once per rule+action+order (Phase 107) +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | BIGINT UNSIGNED | NO | PK | +| `rule_id` | INT UNSIGNED | NO | FK → automation_rules(id) CASCADE | +| `action_id` | INT UNSIGNED | NO | FK → automation_actions(id) CASCADE | +| `order_id` | BIGINT UNSIGNED | NO | FK → orders(id) CASCADE | +| `created_at` | DATETIME | NO | | + +UNIQUE: `(rule_id, action_id, order_id)` + +--- + +## Print Queue + +**print_api_keys** — API keys for remote print client authentication +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT | NO | PK | +| `name` | VARCHAR(128) | NO | | +| `key_hash` | VARCHAR(128) | NO | UNIQUE, SHA256 | +| `key_prefix` | VARCHAR(8) | NO | Shown in UI for identification | +| `is_active` | TINYINT(1) | NO | DEFAULT 1 | +| `last_used_at` | DATETIME | YES | | +| `created_at` | DATETIME | NO | | + +**print_jobs** — Print queue for remote label printing +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `order_id` | BIGINT UNSIGNED | NO | | +| `package_id` | BIGINT UNSIGNED | NO | | +| `label_path` | VARCHAR(255) | NO | | +| `status` | ENUM('pending','printing','completed','failed') | NO | DEFAULT 'pending' | +| `created_by` | INT UNSIGNED | NO | | +| `created_at` | DATETIME | NO | | +| `completed_at` | DATETIME | YES | | + +--- + +## Cron & Scheduling + +**cron_jobs** — Individual cron job queue entries +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `job_type` | VARCHAR(80) | NO | | +| `status` | ENUM('pending','processing','completed','failed','cancelled') | NO | DEFAULT 'pending' | +| `priority` | TINYINT UNSIGNED | NO | DEFAULT 100 | +| `payload` | JSON | YES | | +| `result` | JSON | YES | | +| `attempts` | SMALLINT UNSIGNED | NO | DEFAULT 0 | +| `max_attempts` | SMALLINT UNSIGNED | NO | DEFAULT 3 | +| `last_error` | VARCHAR(500) | YES | | +| `scheduled_at` | DATETIME | NO | | +| `started_at` | DATETIME | YES | | +| `completed_at` | DATETIME | YES | | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +Index: `(status, priority, scheduled_at)` + +**cron_schedules** — Recurring job definitions +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `job_type` | VARCHAR(80) | NO | UNIQUE | +| `interval_seconds` | INT UNSIGNED | NO | | +| `priority` | TINYINT UNSIGNED | NO | DEFAULT 100 | +| `max_attempts` | SMALLINT UNSIGNED | NO | DEFAULT 3 | +| `payload` | JSON | YES | | +| `enabled` | TINYINT(1) | NO | DEFAULT 1 | +| `last_run_at` | DATETIME | YES | | +| `next_run_at` | DATETIME | YES | | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +--- + +## Settings & Configuration + +**app_settings** — Global key-value configuration store +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `setting_key` | VARCHAR(120) | NO | UNIQUE | +| `setting_value` | TEXT | YES | | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +Default keys: `cron_run_on_web`, `cron_web_limit`, `gs1_api_login`, `gs1_prefix`, `products_sku_format` + +**company_settings** — Single-record seller/company configuration (always id=1) +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | TINYINT UNSIGNED | NO | PK, always 1 | +| `company_name` | VARCHAR(200) | YES | | +| `person_name` | VARCHAR(200) | YES | | +| `street` | VARCHAR(200) | YES | | +| `city` | VARCHAR(128) | YES | | +| `postal_code` | VARCHAR(16) | YES | | +| `country_code` | CHAR(2) | NO | DEFAULT 'PL' | +| `phone` | VARCHAR(64) | YES | | +| `email` | VARCHAR(128) | YES | | +| `tax_number` | VARCHAR(64) | YES | NIP | +| `bank_account` | VARCHAR(64) | YES | | +| `bank_owner_name` | VARCHAR(200) | YES | | +| `contact_person_first_name` | VARCHAR(100) | YES | | +| `contact_person_last_name` | VARCHAR(100) | YES | | +| `contact_person_phone` | VARCHAR(64) | YES | | +| `contact_person_email` | VARCHAR(128) | YES | | +| `default_package_length_cm` | DECIMAL(8,1) | NO | DEFAULT 25.0 | +| `default_package_width_cm` | DECIMAL(8,1) | NO | DEFAULT 20.0 | +| `default_package_height_cm` | DECIMAL(8,1) | NO | DEFAULT 8.0 | +| `default_package_weight_kg` | DECIMAL(8,3) | NO | DEFAULT 1.000 | +| `default_label_format` | VARCHAR(8) | NO | DEFAULT 'PDF' | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +--- + +## Design Generation + +**project_mappings** — Map product name patterns to graphic generation scripts +| Column | Type | Nullable | Notes | +|--------|------|----------|-------| +| `id` | INT UNSIGNED | NO | PK | +| `product_name_pattern` | VARCHAR(255) | NO | Pattern matched against order_items.name | +| `script_name` | VARCHAR(255) | NO | Script filename in tools/generowanie/ | +| `output_dir` | VARCHAR(500) | YES | | +| `is_active` | TINYINT(1) | NO | DEFAULT 1 | +| `created_at` | DATETIME | NO | | +| `updated_at` | DATETIME | NO | | + +--- + +## Schema Characteristics + +| Property | Value | +|----------|-------| +| Engine | InnoDB (all tables) | +| Charset | utf8mb4_unicode_ci | +| Encrypted columns | `*_encrypted` suffix — AES via `IntegrationSecretCipher` | +| Soft deletes | `products.deleted_at` only | +| Audit via JSON | `payload_json` snapshots in orders, shipments, receipts | +| Migrations | `database/migrations/YYYYMMDD_NNNNNN_description.sql` | +| Deferred indexes | `idx_order_addresses_order_type`, `idx_shipment_packages_order_delivery` — apply at >50k orders | diff --git a/.paul/codebase/index.md b/.paul/codebase/index.md index f5a1149..51b5edf 100644 --- a/.paul/codebase/index.md +++ b/.paul/codebase/index.md @@ -1,6 +1,6 @@ # orderPRO — Codebase Map -**Generated:** 2026-04-26 | **Version:** 3.1.0-dev | **Milestone:** v3.1 Operational Enhancements +**Generated:** 2026-04-28 | **Version:** 3.2.0 | **Milestone:** v3.2 zamknięty (Phase 108 COMPLETE) ## What Is This Project @@ -10,12 +10,14 @@ orderPRO is a **multi-channel order management system** for Polish e-commerce. I | Document | Contents | |----------|----------| -| [STACK.md](STACK.md) | PHP 8.4, custom framework, PDO, SCSS, PHPUnit, Composer deps | -| [ARCHITECTURE.md](ARCHITECTURE.md) | MVC + Repository + Service layers, modules, routing, data flows | -| [CONVENTIONS.md](CONVENTIONS.md) | Naming, code patterns, security, UI rules (from CLAUDE.md) | -| [TESTING.md](TESTING.md) | PHPUnit 11.5, test patterns, coverage areas | -| [INTEGRATIONS.md](INTEGRATIONS.md) | Allegro, shopPRO, Apaczka, InPost, Email, Print queue | -| [CONCERNS.md](CONCERNS.md) | Tech debt, SonarQube issues, known bugs, performance | +| [stack.md](stack.md) | PHP 8.4, custom framework, PDO, SCSS, PHPUnit, Composer deps | +| [architecture.md](architecture.md) | MVC + Repository + Service layers, modules, routing, data flows | +| [conventions.md](conventions.md) | Naming, code patterns, security, UI rules (from CLAUDE.md) | +| [testing.md](testing.md) | PHPUnit 11.5, test patterns, coverage areas | +| [integrations.md](integrations.md) | Allegro, shopPRO, Apaczka, InPost, Email, Print queue | +| [concerns.md](concerns.md) | Tech debt, SonarQube issues, known bugs, performance | +| [db_schema.md](db_schema.md) | Pełny schemat bazy danych — 55 tabel, typy kolumn, klucze, indeksy | +| [tech_changelog.md](tech_changelog.md) | Chronologiczny log zmian technicznych — co i dlaczego, per-phase | ## Key Directories @@ -27,12 +29,14 @@ resources/views/ PHP templates organized by module resources/scss/ SCSS sources → public/assets/css/ database/migrations/ 84 SQL migration files (timestamped) tests/Unit/ PHPUnit tests for services -.paul/docs/ ARCHITECTURE.md, DB_SCHEMA.md, TECH_CHANGELOG.md +.paul/codebase/ Mapa kodu (architecture, db_schema, tech_changelog, ...) +.paul/changelog/ Dziennik zmian per dzień (klient-friendly) ``` ## Current State -- **Active phase:** 107 — Automation Email Send Once (planning) -- **Last completed:** Phase 106 — Customer Return Alert (2026-04-22) -- **Total migrations:** 84 (latest: `20260425_000102_create_automation_email_once_deliveries_table`) +- **Active phase:** — (Phase 108 COMPLETE, v3.2 zamknięty) +- **Last completed:** Phase 108 — Delivery Status Management (2026-04-27) +- **Total migrations:** 84+ (latest: delivery_status tables from Phase 108) - **God classes to watch:** `OrdersRepository` (1221 LOC), `OrdersController` (1187 LOC), `AutomationService` (834 LOC) +- **BREAKING CHANGE (Phase 108):** Automation rules z kluczami group delivery status (`registered`, `courier_pickup`, `dropped_at_point`, `unclaimed`, `picked_up`) wymagają ręcznego odtworzenia po migracji do DB diff --git a/.paul/docs/API.md b/.paul/docs/API.md deleted file mode 100644 index cce27e0..0000000 --- a/.paul/docs/API.md +++ /dev/null @@ -1,3 +0,0 @@ -# API - -> Endpointy, kontrakty request/response, autentykacja. diff --git a/.paul/docs/ARCHITECTURE.md b/.paul/docs/ARCHITECTURE.md deleted file mode 100644 index ff596ba..0000000 --- a/.paul/docs/ARCHITECTURE.md +++ /dev/null @@ -1,28 +0,0 @@ -# ARCHITECTURE - -> Struktura klas, modulow, przeplywow i zaleznosci w projekcie. - -## Phase 108 — Delivery Status Management - -### DeliveryStatusRepository (`src/Modules/Shipments/DeliveryStatusRepository.php`) -- CRUD dla tabeli `delivery_statuses` -- Per-request static cache (`private static ?array $cache`) -- Blokuje edycję/usunięcie statusów systemowych (`is_system=1`) -- Blokuje usunięcie statusów używanych w `delivery_status_mappings` lub `shipment_packages` - -### DeliveryStatusesController (`src/Modules/Settings/DeliveryStatusesController.php`) -- Panel `/settings/delivery-statuses` -- Dwie zakładki via `?tab=` param: `statuses` (CRUD) i `mapping` (embed mapowania) -- Wstrzykuje `DeliveryStatusRepository` i `DeliveryStatusMappingRepository` - -### DeliveryStatus::setRepository() (dynamic loading) -- Wywoływane raz w `routes/web.php` po bootstrap -- `label()`, `getAllOptions()`, `getAllStatuses()`, `getColor()` ladują z DB gdy repo ustawione -- Fallback na hardcoded stałe gdy repo niedostępne - -### AutomationController + AutomationService (Phase 108 Plan 02) -- `AutomationController::buildShipmentStatusOptions()` — buduje listę opcji `[key => ['label' => ...]]` z `DeliveryStatus::getAllOptions()` (DB-driven) -- Walidacja `shipment_status` warunku i `update_shipment_status` akcji w `parseConditionValue()`/`parseActionConfig()` używa `DeliveryStatus::getAllStatuses()` -- `AutomationService::evaluateShipmentStatusCondition()` — bezpośrednie porównanie kluczy DB (usunięto mapping grupowy `SHIPMENT_STATUS_OPTION_MAP`) -- `AutomationService::resolveStatusFromActionKey()` — bezpośredni klucz statusu z DB jako target -- BREAKING: stare reguły z grupowymi kluczami (`registered`, `courier_pickup`, `dropped_at_point`, `unclaimed`, `picked_up_return`) nie matchują się — operator musi je odtworzyć przy użyciu nowych kluczy DB diff --git a/.paul/docs/DB_SCHEMA.md b/.paul/docs/DB_SCHEMA.md deleted file mode 100644 index 2b51a4f..0000000 --- a/.paul/docs/DB_SCHEMA.md +++ /dev/null @@ -1,21 +0,0 @@ -# DB_SCHEMA - -> Schemat bazy danych — tabele, kolumny, FK, indeksy. - -## delivery_statuses - -Tabela znormalizowanych statusów przesyłek. Zastępuje hardcoded stałe z `DeliveryStatus.php` (od Phase 108). - -| Kolumna | Typ | Opis | -|---------|-----|------| -| id | INT UNSIGNED PK | Auto-increment | -| key | VARCHAR(50) UNIQUE | Klucz statusu (np. `in_transit`) | -| label_pl | VARCHAR(100) | Etykieta po polsku | -| color | VARCHAR(7) | Kolor tła w formacie hex (`#rrggbb`) | -| sort_order | TINYINT UNSIGNED | Kolejność sortowania | -| is_terminal | TINYINT(1) | 1 = status końcowy (nie można cofnąć) | -| is_system | TINYINT(1) | 1 = status systemowy (nieedytowalny z UI) | -| created_at | DATETIME | Data utworzenia | - -**Statusy systemowe** (is_system=1, is_terminal=1): `delivered`, `returned`, `cancelled`. -**Migracja**: `20260427_000103_create_delivery_statuses_table.sql` diff --git a/.paul/docs/DECISIONS.md b/.paul/docs/DECISIONS.md deleted file mode 100644 index 59239f4..0000000 --- a/.paul/docs/DECISIONS.md +++ /dev/null @@ -1,3 +0,0 @@ -# DECISIONS - -> Kluczowe decyzje techniczne i ich uzasadnienia. diff --git a/.paul/docs/STACK.md b/.paul/docs/STACK.md deleted file mode 100644 index bad9fe6..0000000 --- a/.paul/docs/STACK.md +++ /dev/null @@ -1,3 +0,0 @@ -# STACK - -> Stack technologiczny, wersje, zaleznosci, srodowisko. diff --git a/.paul/docs/TECH_CHANGELOG.md b/.paul/docs/TECH_CHANGELOG.md deleted file mode 100644 index 975277f..0000000 --- a/.paul/docs/TECH_CHANGELOG.md +++ /dev/null @@ -1,31 +0,0 @@ -# TECH_CHANGELOG - -> Chronologiczny log zmian technicznych — co i dlaczego. - -## 2026-04-27 — Phase 108 Plan 02: Automation Dropdowns z DB - -**Co zrobiono:** -- `AutomationController` — usunięto stałą `SHIPMENT_STATUS_OPTIONS` (8 grupowych kluczy) -- Dropdown statusów w warunku `shipment_status` i akcji `update_shipment_status` ładuje statusy z DB przez `DeliveryStatus::getAllOptions()` -- Walidacja w `parseConditionValue()` i `parseActionConfig()` używa `DeliveryStatus::getAllStatuses()` -- `AutomationService` — usunięto stałą `SHIPMENT_STATUS_OPTION_MAP`; ewaluacja `evaluateShipmentStatusCondition()` porównuje klucze bezpośrednio -- `resolveStatusFromActionKey()` — bezpośredni klucz statusu z DB jako target (zamiast pierwszego z grupy) - -**Dlaczego:** -- Zamknięcie integracji z Plan 01 — operator dodaje status w `/settings/delivery-statuses` i jest on od razu dostępny w dropdownach automatyzacji bez deploymentu -- Eliminacja kolizji semantycznej: stary klucz grupowy `picked_up` mapował na `delivered` (paczka odebrana przez klienta), nowy klucz DB `picked_up` to "Odebrana przez kuriera" (od nadawcy) -- BREAKING: stare reguły z grupowymi kluczami (`registered`, `courier_pickup`, `dropped_at_point`, `unclaimed`, `picked_up_return`, oraz `picked_up`/`ready_for_pickup`/`cancelled` w starym znaczeniu) nie matchują — wymagają ręcznego odtworzenia z nowymi kluczami DB - -## 2026-04-27 — Phase 108 Plan 01: Delivery Status Management - -**Co zrobiono:** -- Tabela `delivery_statuses` z seedem 11 statusów (migracja `20260427_000103`) -- `DeliveryStatusRepository` — CRUD + per-request cache -- `DeliveryStatus.php` — dynamiczne ładowanie statusów z DB (`setRepository()`) -- Panel `/settings/delivery-statuses` z CRUD (zakładka "Statusy") i mapowaniem (zakładka "Mapowanie dostawy") -- Sidebar: "Statusy" → "Statusy zamówień", nowe "Statusy przesyłek" z badge niezmapowanych -- Badge przesyłek: inline CSS custom property `--status-color` dla niestandardowych statusów - -**Dlaczego:** -- Dodanie nowego statusu wymagało zmiany kodu + deploymentu; teraz z UI -- Operator może definiować własne statusy znormalizowane bez ingerencji w kod diff --git a/.paul/docs/TODO.md b/.paul/docs/TODO.md deleted file mode 100644 index e5893db..0000000 --- a/.paul/docs/TODO.md +++ /dev/null @@ -1,3 +0,0 @@ -# TODO - -> Luzny parking pomyslow, rzeczy do sprawdzenia. diff --git a/.paul/governance/governance_2026-04-28.jsonl b/.paul/governance/governance_2026-04-28.jsonl index 5abdcbb..e8c334d 100644 --- a/.paul/governance/governance_2026-04-28.jsonl +++ b/.paul/governance/governance_2026-04-28.jsonl @@ -33,3 +33,84 @@ {"ts":"2026-04-28T10:28:33Z","tool":"Bash","cmd":"tasklist //FI \"IMAGENAME eq Photoshop.exe\" 2>/dev/null | grep -i photoshop && echo \"PS_RUNNING\" || echo \"PS_NOT_RUNNING\"\",\"description\":\"Check Photoshop status\"},\"tool_response\":{\"stdout","cwd":"/c/visual studio code/projekty/orderPRO"} {"ts":"2026-04-28T10:28:46Z","tool":"Bash","cmd":"python \"C:/visual studio code/projekty/orderPRO/tools/generowanie/prosba_chrzestny_zlota_plexi_uv.py\" \\\\\\n --klient \"Katarzyna Glogowiec\" \\\\\\n --imie-dziecka \"Sara\" \\\\\\n --ojciec-wol","cwd":"/c/visual studio code/projekty/orderPRO"} {"ts":"2026-04-28T10:28:55Z","tool":"Bash","cmd":"\"C:/xampp/mysql/bin/mysql.exe\" --default-character-set=utf8mb4 -h host700513.hostido.net.pl -P 3306 -u host700513_orderpro -phrDNtUBg9grwZ7syN77S host700513_orderpro -e \"UPDATE order_items SET proj","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:38:40Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find . -maxdepth 2 -type f -name \"*.json\" -o -name \"*.xml\" -o -name \".env*\" | head -20\"},\"tool_response\":{\"stdout\":\"./.claude/settings","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:38:40Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find . -type f -name \"*.php\" | head -20\"},\"tool_response\":{\"stdout\":\"./.vscode/ftp-kr.diff.OrdersController.php\\n./.vscode/ftp-kr.diff.tm","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:38:47Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find . -type f -name \"*.md\" | grep -E \"(CLAUDE|concerns|todo|TECH_CHANGELOG)\" | head -20\"},\"tool_response\":{\"stdout\":\"./.claude/memory/f","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:38:49Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -la\"},\"tool_response\":{\"stdout\":\"total 106\\ndrwxr-xr-x 1 jacek 197121 0 Apr 28 21:29 .\\ndrwxr-xr-x 1 jacek 197121 0 Apr 28 21:2","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:38:51Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find src -type d | head -30\"},\"tool_response\":{\"stdout\":\"src\\nsrc/Core\\nsrc/Core/Constants\\nsrc/Core/Database\\nsrc/Core/Exceptions\\nsrc","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:38:54Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find src -type d | head -30\"},\"tool_response\":{\"stdout\":\"src\\nsrc/Core\\nsrc/Core/Constants\\nsrc/Core/Database\\nsrc/Core/Exceptions\\nsrc","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:38:56Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find src -type f -name \"*.php\" | grep -i \"integr\\\\|allegro\\\\|apaczka\\\\|inpost\\\\|shoppro\" | head -20\"},\"tool_response\":{\"stdout\":\","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:38:59Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && wc -l src/**/*.php | tail -20\"},\"tool_response\":{\"stdout\":\"334 src/Core/Application.php\",\"stderr\":\"\",\"interrupted\":false,\"isImage\":","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:01Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find src -type f -name \"*.php\" | grep -i \"integr\\\\|allegro\\\\|apaczka\\\\|inpost\\\\|shoppro\" | tail -30\"},\"tool_response\":{\"stdout\":\","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:02Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find src -type f -name \"*.php\" | wc -l\"},\"tool_response\":{\"stdout\":\"135\",\"stderr\":\"\",\"interrupted\":false,\"isImage\":false,\"noOutp","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:04Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find src -name \"*.php\" -type f | wc -l\"},\"tool_response\":{\"stdout\":\"135\",\"stderr\":\"\",\"interrupted\":false,\"isImage\":false,\"noOutp","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:05Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find src/Core -type f -name \"*.php\" | head -40\"},\"tool_response\":{\"stdout\":\"src/Core/Application.php\\nsrc/Core/Constants/IntegrationSourc","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:06Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && wc -l src/Modules/**/*.php | sort -rn | head -40\"},\"tool_response\":{\"stdout\":\" 28402 total\\n 1221 src/Modules/Orders/OrdersRepository.ph","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:08Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find src -name \"*.php\" -type f -exec wc -l {} + | sort -rn | head -20\"},\"tool_response\":{\"stdout\":\" 29830 total\\n 1221 src/Modules/Ord","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:14Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -la routes/\"},\"tool_response\":{\"stdout\":\"total 44\\ndrwxr-xr-x 1 jacek 197121 0 Apr 28 21:29 .\\ndrwxr-xr-x 1 jacek 197121 0 Apr ","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:21Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find tests -type f -name \"*.php\" 2>/dev/null | wc -l\"},\"tool_response\":{\"stdout\":\"8\",\"stderr\":\"\",\"interrupted\":false,\"isImage\":fa","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:22Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -la src/Core/Support/ && ls -la public/assets/ 2>/dev/null | head -20\"},\"tool_response\":{\"stdout\":\"total 21\\ndrwxr-xr-x 1 jacek 197121 ","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:24Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && wc -l routes/web.php && grep -c \"router->\" routes/web.php\"},\"tool_response\":{\"stdout\":\"599 routes/web.php\\n132\",\"stderr\":\"\",\"interr","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:25Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find tests -type f -name \"*.php\" 2>/dev/null\"},\"tool_response\":{\"stdout\":\"tests/bootstrap.php\\ntests/Unit/AllegroOrderImportServiceTest.p","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:26Z","tool":"Bash","cmd":"cd \"c:/visual studio code/projekty/orderPRO\" && find src -name \"*.php\" -type f | head -5\"},\"tool_response\":{\"stdout\":\"src/Core/Application.php\\nsrc/Core/Constants/IntegrationSources.php\\ns","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:27Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -la public/assets/js/ public/assets/css/ 2>/dev/null\"},\"tool_response\":{\"stdout\":\"public/assets/css/:\\ntotal 80\\ndrwxr-xr-x 1 jacek 197","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:30Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find src/Modules -type f \\\\( -name \"*DeliveryStatus*\" -o -name \"*delivery_status*\" \\\\) 2>/dev/null\"},\"tool_response\":{\"stdout\":\"src/","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:31Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -la public/assets/js/modules/ public/assets/css/modules/\"},\"tool_response\":{\"stdout\":\"public/assets/css/modules/:\\ntotal 8\\ndrwxr-xr-x ","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:31Z","tool":"Bash","cmd":"cd \"c:/visual studio code/projekty/orderPRO\" && find src -type f -name \"*Repository.php\" | wc -l\"},\"tool_response\":{\"stdout\":\"35\",\"stderr\":\"\",\"interrupted\":false,\"isImage\":false,\"n","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:32Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -la database/\"},\"tool_response\":{\"stdout\":\"total 56\\ndrwxr-xr-x 1 jacek 197121 0 Apr 28 21:29 .\\ndrwxr-xr-x 1 jacek 197121 0 Apr 28 21:","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:35Z","tool":"Bash","cmd":"cd \"c:/visual studio code/projekty/orderPRO\" && find tests -type f -name \"*.php\" | sort\"},\"tool_response\":{\"stdout\":\"tests/Unit/AllegroOrderImportServiceTest.php\\ntests/Unit/AllegroShipment","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:36Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -la resources/views/settings/ | grep -i delivery\"},\"tool_response\":{\"stdout\":\"-rw-r--r-- 1 jacek 197121 9257 Apr 28 21:29 _delivery-stat","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:36Z","tool":"Bash","cmd":"cd \"c:/visual studio code/projekty/orderPRO\" && grep -r \"public function test\" tests --include=\"*.php\" | wc -l\"},\"tool_response\":{\"stdout\":\"38\",\"stderr\":\"\",\"interrupted\":false,\"isI","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:37Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && head -100 resources/scss/app.scss && echo \"---\" && ls -la resources/scss/\"},\"tool_response\":{\"stdout\":\"@use \"shared/ui-components\";\\r\\","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:38Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls database/migrations/ | wc -l && ls database/migrations/ | head -20\"},\"tool_response\":{\"stdout\":\"85\\n20260221_000001_create_users_table.s","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:42Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find resources/scss/shared resources/scss/modules -name \"*.scss\" | head -20\"},\"tool_response\":{\"stdout\":\"resources/scss/shared/_ui-compone","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:43Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && grep -r \"echo.*\\\\\\\\\\\\$\" resources/views --include=\"*.php\" | head -20\"},\"tool_response\":{\"stdout\":\"\",\"stderr\":\"\",\"interrupted","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:43Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find src/Modules -type d -maxdepth 2 | sort\"},\"tool_response\":{\"stdout\":\"src/Modules\\nsrc/Modules/Accounting\\nsrc/Modules/Auth\\nsrc/Modul","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:45Z","tool":"Bash","cmd":"cd \"c:/visual studio code/projekty/orderPRO\" && grep -r \"^declare(strict_types=1)\" src | wc -l\"},\"tool_response\":{\"stdout\":\"135\",\"stderr\":\"\",\"interrupted\":false,\"isImage\":false,\"no","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:45Z","tool":"Bash","cmd":"cd \"c:/visual studio code/projekty/orderPRO\" && grep -r \"^declare(strict_types=1)\" tests | wc -l\"},\"tool_response\":{\"stdout\":\"8\",\"stderr\":\"\",\"interrupted\":false,\"isImage\":false,\"no","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:47Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find database/migrations -type f | head -10\"},\"tool_response\":{\"stdout\":\"database/migrations/20260221_000001_create_users_table.sql\\ndataba","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:47Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && grep -r \"RuntimeException\\\\|InvalidArgumentException\\\\|DomainException\" src --include=\"*.php\" | wc -l\"},\"tool_response\":{\"stdout\":\"4","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:48Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && for dir in src/Modules/Orders src/Modules/Shipments src/Modules/Email; do echo \"=== $dir ===\"; ls -la \"$dir\" | grep -E \"\\\\.php$\"; done\"},","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:39:52Z","tool":"Bash","cmd":"cd \"c:/visual studio code/projekty/orderPRO\" && find src -type f -name \"*Exception.php\"\"},\"tool_response\":{\"stdout\":\"src/Core/Exceptions/AllegroApiException.php\\nsrc/Core/Exceptions/Allegro","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:40:47Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find . -maxdepth 3 -type f -name \"*.php\" | head -30\"},\"tool_response\":{\"stdout\":\"./.vscode/ftp-kr.diff.OrdersController.php\\n./.vscode/ft","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:40:52Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -la | head -20\"},\"tool_response\":{\"stdout\":\"total 106\\ndrwxr-xr-x 1 jacek 197121 0 kwi 28 21:29 .\\ndrwxr-xr-x 1 jacek 197121 0 ","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:40:56Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find . -maxdepth 2 -type d | grep -v \"^\\\\./\\\\.\" | sort\"},\"tool_response\":{\"stdout\":\".\\n./bin\\n./bootstrap\\n./clients\\n./clients/wi","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:41:08Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find ./src -type f -name \"*.php\" | head -40\"},\"tool_response\":{\"stdout\":\"./src/Core/Application.php\\n./src/Core/Constants/IntegrationSour","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:41:12Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find ./src -type d | sort\"},\"tool_response\":{\"stdout\":\"./src\\n./src/Core\\n./src/Core/Constants\\n./src/Core/Database\\n./src/Core/Exceptio","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:41:20Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -la ./resources/views/ | head -30\"},\"tool_response\":{\"stdout\":\"total 8\\ndrwxr-xr-x 1 jacek 197121 0 kwi 28 21:29 .\\ndrwxr-xr-x 1 jacek ","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:41:24Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find ./resources/views/components -type f | head -20\"},\"tool_response\":{\"stdout\":\"./resources/views/components/order-status-panel.php\\n./re","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:41:33Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find ./src/Modules/Orders -type f -name \"*.php\" | sort\"},\"tool_response\":{\"stdout\":\"./src/Modules/Orders/OrderImportRepository.php\\n./src","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:41:37Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find ./src/Modules -type f -name \"*.php\" | grep -E \"(Controller|Repository|Service)\" | head -50\"},\"tool_response\":{\"stdout\":\"./src/Modul","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:41:49Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find ./resources/modules -type f | head -20\"},\"tool_response\":{\"stdout\":\"./resources/modules/jquery-alerts/jquery-alerts.css\\n./resources/m","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:41:53Z","tool":"Bash","cmd":"for file in $(find src -name \"*Repository.php\" -o -name \"*Controller.php\" -o -name \"*Service.php\"); do echo \"$(wc -l < \"$file\") $file\"; done | sort -rn | head -15\"},\"tool_response\":{\"std","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:41:53Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -la ./public/assets/ 2>/dev/null | head -20\"},\"tool_response\":{\"stdout\":\"total 4\\ndrwxr-xr-x 1 jacek 197121 0 kwi 28 21:29 .\\ndrwxr-xr-","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:42:01Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find ./database/migrations -type f | head -15\"},\"tool_response\":{\"stdout\":\"./database/migrations/20260221_000001_create_users_table.sql\\n./","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:42:08Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -1 ./src/Modules/Settings/ | grep -E \"(Repository|Service)\" | head -30\"},\"tool_response\":{\"stdout\":\"AllegroDeliveryMethodMappingReposit","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:42:14Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -la ./resources/views/layouts/\"},\"tool_response\":{\"stdout\":\"total 28\\ndrwxr-xr-x 1 jacek 197121 0 kwi 28 21:29 .\\ndrwxr-xr-x 1 jace","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:42:22Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -1 ./src/Modules/Shipments/\"},\"tool_response\":{\"stdout\":\"AllegroShipmentService.php\\nAllegroTrackingService.php\\nApaczkaShipmentService","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:42:31Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -1 ./src/Modules/Email/\"},\"tool_response\":{\"stdout\":\"AttachmentGenerator.php\\nEmailSendingService.php\\nVariableResolver.php\",\"stderr\","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:42:33Z","tool":"Bash","cmd":"wc -l \"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tests\\\\Unit\\\\AllegroTokenManagerTest.php\"\"},\"tool_response\":{\"stdout\":\"267 C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\te","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:42:46Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && ls -1 ./src/Core/\"},\"tool_response\":{\"stdout\":\"Application.php\\nConstants\\nDatabase\\nExceptions\\nHttp\\nI18n\\nRouting\\nSecurity\\nSupp","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:42:53Z","tool":"Bash","cmd":"cd /c/visual\\\\ studio\\\\ code/projekty/orderPRO && find ./resources/views/orders -type f | head -10\"},\"tool_response\":{\"stdout\":\"./resources/views/orders/list.php\\n./resources/views/orders/p","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:44:29Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\codebase\\\\index.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:44:35Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\codebase\\\\index.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:44:46Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\codebase\\\\concerns.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:44:49Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\codebase\\\\concerns.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:49:20Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\codebase\\\\db_schema.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:49:29Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\codebase\\\\index.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:58:39Z","tool":"Edit","file":"C:\\\\Users\\\\jacek\\\\.claude\\\\paul-framework\\\\workflows\\\\map-codebase.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:58:47Z","tool":"Edit","file":"C:\\\\Users\\\\jacek\\\\.claude\\\\paul-framework\\\\workflows\\\\map-codebase.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:58:57Z","tool":"Edit","file":"C:\\\\Users\\\\jacek\\\\.claude\\\\paul-framework\\\\workflows\\\\map-codebase.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:59:02Z","tool":"Edit","file":"C:\\\\Users\\\\jacek\\\\.claude\\\\paul-framework\\\\workflows\\\\map-codebase.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:59:12Z","tool":"Edit","file":"C:\\\\Users\\\\jacek\\\\.claude\\\\paul-framework\\\\workflows\\\\map-codebase.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:59:21Z","tool":"Edit","file":"C:\\\\Users\\\\jacek\\\\.claude\\\\paul-framework\\\\workflows\\\\map-codebase.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:59:43Z","tool":"Write","file":"C:\\\\Users\\\\jacek\\\\.claude\\\\paul-framework\\\\templates\\\\codebase\\\\db_schema.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T19:59:59Z","tool":"Write","file":"C:\\\\Users\\\\jacek\\\\.claude\\\\paul-framework\\\\templates\\\\codebase\\\\tech_changelog.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T20:00:14Z","tool":"Edit","file":"C:\\\\Users\\\\jacek\\\\.claude\\\\paul-framework\\\\workflows\\\\apply-phase.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T20:00:36Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\codebase\\\\architecture.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T20:00:55Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\codebase\\\\tech_changelog.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T20:01:04Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\codebase\\\\index.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T20:01:23Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\CLAUDE.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T20:01:29Z","tool":"Bash","cmd":"rm -rf \".paul/docs\" && echo \"DELETED\" && ls .paul/ 2>/dev/null\",\"description\":\"Delete .paul/docs directory\"},\"tool_response\":{\"stdout\":\"DELETED\\nchangelog\\ncodebase\\ngovernance\\nhand","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T20:02:00Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\codebase\\\\index.md","cwd":"/c/visual studio code/projekty/orderPRO"} +{"ts":"2026-04-28T20:02:06Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\codebase\\\\index.md","cwd":"/c/visual studio code/projekty/orderPRO"} diff --git a/CLAUDE.md b/CLAUDE.md index 45c4cdb..ddd2ddb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -21,20 +21,20 @@ - Kod ma mieć komentarze tylko tam, gdzie wyjaśniają „dlaczego”, nie „co” ## Utrwalanie stalych wymagan -- Trwale wymagania techniczne zapisuj w tym pliku (`AGENTS.md`) w root projektu. +- Trwale wymagania techniczne zapisuj w tym pliku (`CLAUDE.md`) w root projektu. - Dla zmiennych srodowiskowych utrzymuj tez wpisy w `.env.example`. -- Dokumentacje techniczna utrzymuj w folderze `DOCS`: - - `DOCS/DB_SCHEMA.md` - aktualny schemat bazy danych (aktualizacja przy kazdej zmianie migracji/schematu), - - `DOCS/ARCHITECTURE.md` - struktura klas, metod, modulow i przeplywow, - - `DOCS/TECH_CHANGELOG.md` - chronologiczny log zmian technicznych (co i dlaczego). +- Dokumentacje techniczna utrzymuj w folderze `.paul/codebase/`: + - `.paul/codebase/db_schema.md` - aktualny schemat bazy danych (aktualizacja przy kazdej zmianie migracji/schematu), + - `.paul/codebase/architecture.md` - struktura klas, metod, modulow i przeplywow, + - `.paul/codebase/tech_changelog.md` - chronologiczny log zmian technicznych (co i dlaczego). - Przy kazdej nowej funkcji lub zmianie: - - zaktualizuj odpowiednie sekcje w `DOCS/DB_SCHEMA.md`, `DOCS/ARCHITECTURE.md`, `DOCS/TECH_CHANGELOG.md`, + - zaktualizuj odpowiednie sekcje w `.paul/codebase/db_schema.md`, `.paul/codebase/architecture.md`, `.paul/codebase/tech_changelog.md`, - opisz nowe tabele/kolumny/indeksy/FK, nowe klasy/metody oraz zmiany kontraktow API. ## Wdrażanie poprawek - Przed wdrożeniem zmian w kodzie, przeglądnij, poniższe dokumenty aby nowe kody dopasować do istniejacych już rozwiązań: - - `DOCS/DB_SCHEMA.md` - aktualny schemat bazy danych - - `DOCS/ARCHITECTURE.md` - struktura klas, metod, modulow i przeplywow + - `.paul/codebase/db_schema.md` - aktualny schemat bazy danych + - `.paul/codebase/architecture.md` - struktura klas, metod, modulow i przeplywow - Zrób plan i mi go przedstaw - Po akceptacji przejdź do wdrożenia - Po wdrożeniu przeprowadź testy