Commit Graph

84 Commits

Author SHA1 Message Date
Vasyka 47eb4f62c1 feat(injector-protocols): full module — resource + PDF export via Browsershot
Implements the injector diagnostic protocol module per spec:
- Migration: injector_protocols + injector_protocol_rows with company_id
  (multi-tenant), vehicle_id (not car_id — this CRM uses Vehicle),
  master_id FK to users, snapshot fields (car_model/plate/vin/mileage/year/
  injector_brand) captured at protocol time.
- Models with BelongsToTenant; auto-generate protocol_number as
  PS-{tenantId}-{year}-{seq6}; auto-seed 8 empty rows on create.
- Permissions: injector_protocols.view + injector_protocols.conclude.
  Default roles: owner/admin (both), manager (both), receptionist (view
  only), mechanic (both). Test permission count updated 52→54.
- InjectorProtocolResource under Service nav group with 4 sections:
  data auto+client (with client_id/vehicle_id lookups auto-filling
  snapshot fields), reason checkboxes, 8-row repeater for measurements
  (Repeater with position hidden; fixed 8, non-addable/deletable),
  conclusion + comment + master signature.
- Table with columns, badge filters, PDF action.
- Blade PDF template: pixel-close to reference (graphite/gold/blue
  brand tokens, striped rows, rotated 'ФОРСУНКИ' header).
- Route /app/injector-protocols/{id}/pdf with permission gate,
  streams PDF via new InjectorProtocolPdfService (Browsershot).
- Dockerfile: install nodejs 22 + chromium + noto fonts + puppeteer-core
  in /opt/browsershot; env vars for Browsershot binary paths.
- +71 RU/EN translations covering resource + PDF template.

All 306 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-26 11:27:53 +00:00
Vasyka 0e85035eff i18n: add 'Toate statusurile' (calendar-board status filter option)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-26 11:02:35 +00:00
Vasyka de2964c854 i18n(wo relations): translated snapshot names + explicit empty states
- WorksRelationManager Name column: getStateUsing(labor?->label()) so
  the row shows the labor's localized name (not the raw snapshot);
  fallback to stored snapshot when labor is missing.
- 4 explicit empty states with helper description + icon on Works,
  Parts, SubcontractJobs, Payments — replaces Filament's auto-generated
  'Не найдено X / Создать X для старта.'
- 4 CreateAction titles / modal headings for all four relation managers.
- Notification 'Piesa returnată în stoc' / 'Nimic de restituit' wrapped.
- +11 translation keys.

All 306 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-26 10:59:47 +00:00
Vasyka 9609295a9e feat(labors): trilingual name — add name_en column + Labor::label() helper
- Migration: add nullable `labors.name_en` alongside existing name_ro/
  name_ru.
- Labor model: label(?locale) accessor returns name_{locale} with
  name_ro fallback.
- LaborResource form: expose 3rd 'Nume (EN)' field.
- Table + Select displays now go through label() so options show the
  locale-appropriate name:
    /app/labors table column,
    WorkOrderResource works Select ('[category] name (Nh)'),
    ServiceTemplate items Select,
    ServiceComposer WorkOrderWork snapshot on create.
- Snapshot name saved on wo_works.name at creation reflects the
  current locale; existing rows keep their stored snapshot untouched.

All 306 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-26 10:54:00 +00:00
Vasyka 64a170b7f9 i18n(work-order works): translate labor Select category + h suffix + modal titles
- Labor Select options now build '[__(category)] name_ro (hours __(h))'
  so category chip and hour suffix translate on RU/EN. Labor name stays
  as name_ro (user data — separate long-term concern).
- CreateAction gets explicit label + modalHeading (was 'Create Work
  Order Work' auto-generated).
- Notification 'Piese implicite adăugate (N)' rewritten with __(':n')
  placeholder.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-26 10:47:00 +00:00
Vasyka 8228689580 i18n(leads): +12 translations (sections, SOURCES, STATUSES, empty state)
Sections Mesaj client / Sursă & Atribuire / Marketing (UTM), the full
empty-state description, plus previously-missing Lead::SOURCES enum
values (Manual, Apel, Site, Google Maps, SEO, Recomandare) and
STATUSES (Contactat, Convertit, Pierdut).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 11:43:03 +00:00
Vasyka 8c2f10b5a5 i18n(bodyshop-jobs): +48 translations covering resource + enums + damage map
Full coverage for bodyshop resource: sections (Asigurare, Daune,
Status dosar), all TYPES enum (Tinichigerie, PDR, Vopsitorie,
Detailing, Ceramică, PPF, Polish), STATUSES + INSURANCE_STATUSES,
damage-point SEVERITIES, all 20 damage ZONES (Bară față, Capotă,
Aripă FS/FD/SS/SD, Ușă F/S ×2, Bara spate, Portbagaj, Plafon,
Parbriz, Lunetă, Prag S/D, Oglindă S/D, Jantă), and 6 damage KINDS
(Zgârietură, Lovitură, Fisură, Rugină, Vopsea sărită, Spart).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 11:40:53 +00:00
Vasyka 93f17e8945 i18n(backup): +10 translations covering full backup + export page
Page title, download button, format description, use-cases list,
sensitive-data warning, spinner text.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 11:38:41 +00:00
Vasyka 7d81e69ca4 i18n(api-tokens): +17 translations for full page + token-generated banner
Covers page title, generate/revoke actions, freshly-created token
banner (copy/hide buttons + warning), permissions column, empty state,
endpoint documentation section (helpers + subdomain note).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 11:37:05 +00:00
Vasyka d97b9b3d6d i18n(settings): wrap delivery methods CheckboxList with I18n::opts + 3 keys
OnlineOrder::DELIVERY values (Ridicare din service / Curier / Poștă)
weren't translated; now go through I18n::opts and have RU/EN entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 11:36:10 +00:00
Vasyka a6f21762fc i18n(settings): fix currency I18n::opts + push notification + closing-quote strings
- Currency Select ->options() had 4 raw entries (MDL/EUR/USD/UAH)
  and 2 wrapped (RON/RUB); consolidated all 6 under I18n::opts()
- Push notification title 'Trimis pe N dispozitiv(e)' rebuilt with
  __(':n')-placeholder; empty state + helper now go through __()
- Added 4 long helper description keys with the closing „…"
  Romanian quotation marks (the previous keys were missing the
  trailing quote and dot; now match Settings.php byte-for-byte)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 11:33:52 +00:00
Vasyka a658e359b9 i18n(settings): +38 translations covering full company settings page
Full coverage across Logo & favicon / AI providers / Telegram bot /
Notifications (client reminders) / Shop / Currencies / Internal
margin. Includes long helper paragraphs and 'Setări salvate' /
'Tenant not resolved' notification titles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 11:27:37 +00:00
Vasyka 9296d9db11 i18n(permission-overrides): explicit empty state (was auto-generated class name)
Filament default rendered 'Не найдено user permission overrides /
Создать user permission override для старта.' from the model class
name. Overridden with translated heading + explanatory description
+ shield-exclamation icon.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 11:24:41 +00:00
Vasyka 49b491a7bd feat(rbac): human labels + descriptions for all 50 permissions
- Add Permissions::permissionLabels() mapping every slug to a
  human-readable RO label (e.g. 'clients.view_all' → 'Vezi toți
  clienții').
- RoleResource permission checkboxes now show translated labels
  as titles + technical slug as description (so admins see both
  the meaning and the key).
- PermissionOverridesRelationManager Select 'permission_id' now
  shows 'Human label (technical.slug)' format, plus helper text
  explaining GRANT/DENY. Same format on the display column.
- +57 translations (50 permission labels in RU/EN + role page
  supporting keys + module labels).

All 306 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 11:16:21 +00:00
Vasyka af0327d27d i18n(permission-overrides): wrap DENY option + explicit CreateAction labels
- 'DENY — interzice dreptul' select option was missing __() wrap
- CreateAction/EditAction now have explicit label/modalHeading so
  the modal shows 'Добавить исключение прав' instead of
  'Создать User Permission Override' (auto-generated from class name)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 11:11:37 +00:00
Vasyka 3d60e1d368 i18n(users): translate 'status' badge column + relabel Locale → Язык / Language
Status column showed raw DB enum values (active/inactive/blocked) with
no formatStateUsing → readers saw 'active' instead of the translated
'Активный / Активно' visible in the Select. Added formatStateUsing with
a match() that returns the appropriate __() key.

Locale header re-translated to 'Язык' (RU) / 'Language' (EN) since
'Локаль' is unusual for end users.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 11:08:46 +00:00
Vasyka 58f168dd97 i18n(users): wrap role Select options with I18n::opts + 2FA status + Locale
- Both role selects (primary + additional roles multi) passed the raw
  roleLabels() array without translation; wrap with I18n::opts() so
  Proprietar/Administrator/… now render translated in RU/EN.
- 2FA status text ('✓ Activat (TOTP)' / '✗ Dezactivat') split so
  the checkmark stays and label runs through __().
- +3 translations (Activat (TOTP), Dezactivat, Locale) — Locale is
  Filament's auto-generated headline from the `locale` field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 11:04:30 +00:00
Vasyka 00afca8a17 i18n(users): +16 translations for sections, roles, 2FA, salary helpers
Covers Identitate/Acces/2FA sections, all helper texts on user
edit page (2FA reset, role sync, additional roles, margin helper,
salary formula), placeholder examples, RBAC role labels (Proprietar,
Vizitator, Recepție), 'Română' language option, and Permission
Overrides RelationManager helpers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:58:33 +00:00
Vasyka f96bb96fa1 i18n(posts): +4 translations (plural label + placeholder + helper + empty)
Fixes 'Posturi De Lucru' title (was RO fallback) and translates the
create form placeholder + default-mechanic helper text + no-default
option label.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:55:06 +00:00
Vasyka e43d79fea7 i18n(subcontract-jobs + filament core): +6 keys + fix missing 'no options' RU/EN
- +6 subcontract-jobs translations (Lucrare, Termene, Returnat, ETA,
  helper 'Setat manual dacă markup = 0.', empty-state description)
- Add lang/vendor/filament-forms/{ru,en}/components.php with select
  no_options_message + max_items_message. Filament ships RO copy with
  no RU override, so 'Nu sunt disponibile opțiuni.' bled through into
  RU/EN locales.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:51:42 +00:00
Vasyka 8deb58b1ab i18n: add 'Specialty' (Filament auto-generated headline from specialty field)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:48:50 +00:00
Vasyka 493c4f0de9 i18n(subcontractors): +9 translations (SPECIALTIES enum, section, empty state)
Fills in the untranslated Subcontractor::SPECIALTIES options (Turbo,
Variator, Casetă direcție, PDR, Electronică, Injectoare) plus
Specialitate label, empty-state heading and full description.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:46:26 +00:00
Vasyka 7df4d1306f i18n(workload): +10 translations + wrap capacity/hours/legend suffixes
Wrapped 'capacitate ref: Nh/zi' header, cell counters 'Nh / N progr.',
and 3 previously-raw legend labels (liber / mediu / plin (peste
capacitate)). +10 keys total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:41:48 +00:00
Vasyka 990a2898a3 i18n(recommendations): +12 translations + wrap raw 'niciodată' fallback
Covers page title, 4 section headings + subtitles, 4 empty-state
messages, 'ultima fișă' column suffix, and last-contact 'niciodată'
fallback (which was a raw string).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:38:19 +00:00
Vasyka 3b6dc982c1 i18n(ai-assistant): wrap wire:confirm delete conversation prompt
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:37:10 +00:00
Vasyka b8a5fd528e i18n(ai-assistant): +8 translations covering setup notice, placeholder, tokens footer
Wraps the free-text token/requests counter suffix and adds the last 6
identity-fallback keys used on the page.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:33:46 +00:00
Vasyka 78e48c6dda i18n(reports): wrap Anul curent + auto-translate specialization tokens
- Reports.php periods() had 'this_year' hardcoded; now wrapped in __()
- masters tab specialization cell: split by '/' and __()-translate each
  token so 'Motor / Cutie viteze' auto-renders as «Двигатель / КПП»
  on RU (and 'Engine / Gearbox' on EN). Users can enter any free-text
  specialisation; the common keywords now have RU/EN translations.
- +12 specialisation vocabulary entries (Motor, Frâne, Suspensie,
  Anvelope, Cutie viteze, Electrică, Diagnosticare, Vopsitorie,
  Tinichigerie, Aer condiționat, Roți, Ambreiaj).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:32:06 +00:00
Vasyka 8e4b1f713e i18n(reports): +3 wrap missed tabs (masters/works/parts) + translations
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:28:55 +00:00
Vasyka 04cdb706e7 i18n(reports): +13 translations for tabs, sections, empty states
Covers 3 report tabs (Clienți/Finanțe/Încărcare), 6 subsection titles
(Cheltuieli pe categorie, Încasări pe metodă, Top piese vândute,
Tranz., Pe status, Ore total) and 4 empty-state messages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:24:38 +00:00
Vasyka 7abbfe8509 i18n(excel-import-wizard): translate stepper (1-4) + Step 3 title + row status badges
- 4 stepper labels (Upload / Mapare coloane / Previzualizare / Confirmare)
  now split so the number stays and only the text runs through __()
- Step 3 heading rewritten with __(':n poziții') placeholder
- 'Selectat: filename.xlsx' hint wrapped
- Row status badges (Găsit/Nou/Nu găsit) split so emoji stays and label
  translates
- 'Articole noi (se vor crea)' summary line wrapped

+8 translations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:18:39 +00:00
Vasyka 466d182192 i18n(excel-import-wizard): +19 translations (full wizard + fix Step 4 count)
Full page translation across all 4 steps (upload / map columns / preview /
done), including form labels, buttons, helper text, empty state, and
final result summary. Notification 'N poziții importate' now built via
__(':n')-placeholder so it translates on RU/EN.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:16:20 +00:00
Vasyka bf325c8149 i18n(tire-sets): +23 translations (sections, TPMS, CONDITIONS, empty states, history)
Complete coverage for /app/tire-sets + create + storage history tab.
Includes Specificații/TPMS/Uzură sections, all field labels
(Sezon/Stare/Cu jante/Tip jante/Senzori TPMS/Dimensiune/Diametru R),
Check-in depozit action + result notifications, empty state (heading
+ description), placeholder examples, storage history relation
manager, and remaining CONDITIONS enum values (Bun/Critic/All-season).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:09:24 +00:00
Vasyka 702494b922 i18n(integrations): +7 translations for channel cards + info banner
Descriptions for Telegram/SMS/Message-templates/Webhook integration
cards + the placeholder-note info banner + Status: label.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:02:22 +00:00
Vasyka e4130eed03 i18n(calls): +8 translations for DIRECTIONS/STATUSES enums + filter
Adds RU/EN for Call::DIRECTIONS (Primit/Efectuat/Pierdut),
Call::STATUSES (Răspuns/Ocupat/Fără răspuns), the 'Pierdute'
missed-calls quick filter, and Filament's auto-generated
'Direction' label from the direction field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 10:00:58 +00:00
Vasyka d5349aaa25 i18n(marketing-channels): +5 translations for columns + labels + empty state
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 09:58:38 +00:00
Vasyka 819f35aa49 i18n(shop-customers): +2 empty state translations
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 09:57:16 +00:00
Vasyka 26e48368d0 i18n(online-orders): +10 keys (model labels, STATUSES fem, Livrare col, action)
Adds RU/EN for feminine STATUSES enum values used by online-orders
(Nouă/Confirmată/Pregătită/Expediată/Livrată/Anulată), lowercase
model labels for plural/create titles, Livrare (delivery method
column), and the confirm-order helper.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 09:55:11 +00:00
Vasyka 54284daf22 i18n(payroll-adjustments): +7 translations for model labels, columns, TYPES
Model labels (ajustare, bonusuri/avansuri) drive the plural title
'Bonusuri/avansuri' and 'Create Ajustare' text; TYPES enum
(Bonus/Penalizare/Avans) drives the type select; column 'Aplicat'
and auto-generated 'Period' for the period field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 09:53:01 +00:00
Vasyka 954e299940 i18n(payroll-runs): +5 auto-generated column labels (Base/Bonus/Fines/Advance/Paid)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 09:51:45 +00:00
Vasyka c72a5b2542 i18n: add 'Hire date' (Filament auto-generated from hire_date field)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-18 09:44:14 +00:00
Vasyka 98f71d782c i18n(payroll-runs): +8 translations + fix hardcoded notification title
Notification 'Calculat salariul YYYY-MM pentru N utilizatori' was
built via string interpolation → couldn't translate. Now uses __()
with :period / :count placeholders. Adds 7 more translations for
section titles and column labels.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-17 07:01:42 +00:00
Vasyka c9d754fade i18n(employee-profiles): +9 translations for full list + create form
Section titles (Profil, Salariu & comisioane), commission column
headers (% Manopere / % marja piese), plural model label, hire date
label, and both commission helper texts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-17 06:56:19 +00:00
Vasyka 74fe9fc8d9 i18n: +2 Payment::METHODS translations (Card, Virament)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-17 06:43:00 +00:00
Vasyka 67aa138092 i18n(expenses): add missing lowercase 'cheltuială'/'cheltuieli' model labels
Model labels used lowercase (Expense::getModelLabel returns __('cheltuială'))
but dict only had capitalised keys. Filament rendered 'Создать
Cheltuială' as fallback. Now RU shows 'Создать расход' / EN 'Create
expense'.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-17 06:40:40 +00:00
Vasyka f66227088c i18n(payments): +4 translations (model labels + helper + Mobile pay method)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-17 06:31:33 +00:00
Vasyka 2b56bbc35b i18n(finance): full page — tabs/periods/pnl/balance + Expense.CATEGORIES
- All 4 tabs (Overview/Cashflow/P&L/Balanță) built with __() around
  the text portion, emoji stays in code
- 4 period presets wrapped with __()
- P&L table Marjă/Marjă piese footer wrapped
- Expense::CATEGORIES values look up through __() in the expensesByCat
  loop so categories show translated (Salariu → Зарплата etc.)
- +25 translations covering all UI copy on /app/finance

306 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-17 06:28:53 +00:00
Vasyka 5a2b97833a i18n(warehouses): +3 translations (Loturi, empty state)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-17 05:48:57 +00:00
Vasyka f45df71410 i18n(pricing-coefficients): wrap BODY_TYPES/TRANSMISSION_TYPES CheckboxList options
The two CheckboxList options passed raw Vehicle::BODY_TYPES and
Vehicle::TRANSMISSION_TYPES arrays — now they run through I18n::opts()
so the RO values translate at display. +6 translations for the enum
values that weren't yet in dict (Crossover, Pickup, Minivan, DSG,
DCT, AMT).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-16 20:59:33 +00:00
Vasyka 1de1812fed i18n(pricing-coefficients): +15 translations covering list + create form
Includes VEHICLE_CLASSES enum values (Sedan/Hatchback, SUV/Crossover,
Comercial, Hibrid, Electric EV, Premium/Lux), section titles
(Coeficient), badges (Prio/Cumul.), all helper texts, empty-state
heading + description, placeholder example.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-16 20:57:31 +00:00
Vasyka 2985c38d93 i18n(markup-rules): +11 translations + wrap key label & categories
Wrapped the dynamic Select 'key' label (Brand/Categorie) with __(),
switched the category options to I18n::opts(). Notification 'Recalculat
preț pentru N piese' now uses __(:n) placeholder.

+11 keys: regulă, reguli markup, Cheie, Mai mic = aplicat primul.,
'Va recalcula sell_price…' confirm text, notification, 'Interval preț'
enum, and missing Part.CATEGORIES (Ulei, Filtre, Lichide, Distribuție).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-16 20:55:13 +00:00