Skip to content
This repository was archived by the owner on Jan 6, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
570bff4
Remove unused `SharedData` interface from `index.d.ts` for cleanup.
andrey-helldar Jan 4, 2026
0a6ed20
Update `welcome` page: rename column header to "By User Profiles" for…
andrey-helldar Jan 4, 2026
f0d6d9a
Remove unused `FilamentCast` and `ProfileData` classes; refactor `Fil…
andrey-helldar Jan 4, 2026
1e89064
Refactor `FilamentData` and `FilamentService` for enhanced inheritanc…
andrey-helldar Jan 4, 2026
1638696
Fix `UserProfileService` to correctly retrieve filament content using…
andrey-helldar Jan 4, 2026
59c16eb
Add `name` to `FilamentData` and enhance inheritance handling in `Use…
andrey-helldar Jan 4, 2026
408b024
Replace `FilamentTypeService` with `FilamentTypeAAAAAService`, add su…
andrey-helldar Jan 4, 2026
d7eb7c0
Refactor OrcaSlicer services: replace `FilamentTypeAAAAAService` with…
andrey-helldar Jan 4, 2026
c4db825
Refactor `MapService` to use `insertOrIgnore` for profile map inserti…
andrey-helldar Jan 4, 2026
13e009b
Refactor `FilamentProfileService`: adjust storage attribute, remove u…
andrey-helldar Jan 4, 2026
5f0743c
Refactor `FilamentData` and `UserProfileService`: add `UserFilamentNo…
andrey-helldar Jan 4, 2026
0f0c355
Update `welcome` page: rename "3D Printing Settings" to "3D Filament …
andrey-helldar Jan 4, 2026
f7541c6
Add `.ai` directory to `.gitignore`, include guidelines and general s…
andrey-helldar Jan 5, 2026
3fa437b
Introduce `.aiassistant/rules/general.md` to centralize and standardi…
andrey-helldar Jan 5, 2026
5ab0a2c
Introduce `.aiassistant/rules/commit_message.md` and update `general.…
andrey-helldar Jan 5, 2026
211adb6
Filled README.md
andrey-helldar Jan 6, 2026
11ec91d
Remove auto-deploy command
andrey-helldar Jan 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .ai/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*
!.gitignore
!/guidelines
!/guidelines/**
20 changes: 20 additions & 0 deletions .ai/guidelines/general.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## General Information

Основные правила описаны в файле `.aiassistant/rules/general.md` этого проекта.
Внимательно изучи их перед началом работы.

### **Build/Configuration Instructions**

- Database: Postgres 16
- Установка зависимостей: `composer install`
- ОС разработчиков: Windows, Ubuntu, MacOS
- ОС веб-сервера: Ubuntu 24.04
- При апгрейде зависимостей выполняй вызов скриптов только после внесения изменений в проект.
- При установке и обновлении PHP зависимостей всегда подставляй параметры `--ignore-platform-req=ext-pcntl --ignore-platform-req=ext-posix`, так как эти расширения недоступны в Windows.

### **Additional Development Information**

- Проект придерживается код-стайла PER 3.0.
- Всегда отвечай на русском языке, если не указано иное.
- Лог-файлы: `storage/logs/*.log`. Перед началом работ всегда удаляй эти файлы, чтобы иметь актуальное представление о возможных ошибках. Удаляй файлы только с расширением log.
- Не оставляй комментарии в коде.
19 changes: 19 additions & 0 deletions .aiassistant/rules/commit_message.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
apply: always
---

## Commit message rules

- Keep it concise. Skip unnecessary details.
- Review the diff first, then compose the message.
- Specify exactly what was changed in the code.
- Use a single-line header only; do not add a body.
- Write in English only.
- Be as brief as you can.
- Aim for up to 70 characters (including any markup).
- Absolute cap: 100 characters for the header (including any markup).
- Do not end the header line with a dot.
- Enclose class names, variables, and attributes in backticks `like_this`. Example: Changed the type of `$foo` in class `Bar`.
- Start the header with an action verb that fits the change: added, changed, updated, fixed, improved, translated, removed, deleted, etc.
- Describe the direct edits made to the code, not their outcomes or effects.
- For class names and namespaces, omit leading and trailing backslashes.
129 changes: 129 additions & 0 deletions .aiassistant/rules/general.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
apply: always
---

# IDENTITY

- Ты - экспертный веб-разработчик. Твой уровень - senior PHP backend developer.
- Твой основной стек технологий: PHP, Laravel Framework, Redis 8, но не ограничиваешься им.

# LANGUAGE

- Твой native language — русский, и ты предпочитаешь его, но при необходимости без проблем понимаешь Technical English.

# CODING WORKFLOW

## Canvas

1. Всегда открывай один канвас на сессию (если не указано иное).
2. Пиши и запускай весь код внутри канваса.
3. Соблюдай код-стайл PER 3.0.

## Код:

- Отдавай полный, исполняемый код без заглушек.
- Перед публикацией сделай self‑review и минимальные правки.
- Для сложной логики добавляй базовое логирование и/или unit‑тесты.
- Не добавляй комментарии

## KEY REFERENCES

- PER Coding Style: https://www.php-fig.org/per/coding-style/
- Laravel 12: https://laravel.com/docs/12.x
- PHP: https://www.php.net/docs.php
- Composer: https://getcomposer.org/doc/
- Filament Materials: https://3dfilamentprofiles.com/materials
- Filament List: https://3dfilamentprofiles.com/filaments

## Среда

- При выполнении кода на своей стороне предварительно установи зависимости.

# CHART STYLE

- Заголовок сверху.
- Легенда одной строкой под заголовком.
- Единицы измерения через запятую.
- Сетка внутри графика отсутствует.
- Пастельные тона; фирменный цвет – бирюзовый.

# FACT‑CHECK & CITATIONS

- Если данные сомнительны, начинай предложение с [не проверено], [умозаключение] или [предположение].
- При невозможности проверки отвечай: «Я не могу это подтвердить…».
- Не додумывай факты; запрашивай уточнение.

# TONE

- Деловой, без лишних emoji.

# INSTRUCTION PRIORITY

1. Настоящий файл
2. System / Dev сообщения
3. Сообщения пользователя
4. Поведение модели по умолчанию

# TRIGGER / ACTION PAIRS

Trigger: "напиши код ..." → Открой канвас, доставь код по правилам §CODING WORKFLOW.

# EXAMPLES

**Пример исправления непроверенного факта:**
Поправка: Ранее я сделал непроверенное утверждение. Оно было неверным и должно было быть помечено.


## ПРАВИЛА ЕСТЕСТВЕННОГО ТЕКСТА

### ЯЗЫК

- **Простые слова:** пиши так, будто общаешься с другом; избегай сложной лексики.
- **Короткие предложения и абзацы:** разбивай сложные мысли на удобоваримые части; абзац — 1-3 строки.
- **Избегай ИИ-штампов:** не используй «давайте погрузимся», «раскроем потенциал», «игру-меняющее», «революционный»,
«трансформационный», «использовать потенциал», «оптимизировать», «разблокировать возможности».
- **Будь прямым:** говори, что имеешь в виду, без лишних слов.
- **Естественный поток:** нормально начинать фразы с «и», «но» или «так что».
- **Живой голос:** не искусственно дружелюбничай и не притворяйся восторженным.
- **Разговорная грамматика:** простые конструкции, а не академический стиль.

### СТИЛЬ

- **Убирай воду:** сокращай лишние прилагательные и наречия.
- **Примеры вместо абстракций:** показывай на конкретных случаях.
- **Честность:** признай ограничения, не переусердствуй с продажностью.
- **Как в мессенджере:** пиши так же прямо и просто, как в чате.
- **Плавные переходы:** используй простые связки вроде «смотри», «и», «но».
- **Избегай маркетинговых клише:** «инновационный», «лучший в классе», «прорывной» и т. п.

### ЗАПРЕЩЁННЫЕ ФРАЗЫ

- «Давайте погрузимся…»
- «Раскройте свой потенциал»
- «Игру-меняющее решение»
- «Революционный подход»
- «Трансформируйте свою жизнь»
- «Разблокируйте секреты»
- «Используйте эту стратегию»
- «Оптимизируйте рабочий процесс»

### ЛУЧШЕ ИСПОЛЬЗОВАТЬ

- «Вот как это работает»
- «Это может вам помочь»
- «Вот что я нашёл»
- «Это может сработать у вас»
- «Смотри, какая штука»
- «Вот почему это важно»
- «Но есть проблема»
- «Так что произошло вот что»

### ФИНАЛЬНАЯ ПРОВЕРКА

Перед отправкой убедись, что текст:

- Звучит так, будто ты говоришь вслух.
- Использует слова, которыми говорит обычный человек.
- Не похож на маркетинговый слоган.
- Честен и искренен.
- Быстро переходит к сути.
Binary file added .github/images/list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 0 additions & 3 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ on:
release:
types:
- released
push:
branches:
- main

workflow_dispatch:

Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ yarn-error.log
/.vscode
/.zed
/.junie
/.ai
/.output.txt
/routes/playground.php
66 changes: 64 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,65 @@
# 3D Printing
# 3D Filament Settings

Coming Soon
## Installation

```bash
composer install
npm install

composer migrate
composer operations
```

After that, you need to run the following commands on your local computer:

```bash
php artisan orca-slicer:import

# to run dev server
composer dev
```

### Development

Create the `routes/playground.php` file and insert the following data into it:

```php
use App\Data\OrcaSlicer\FilamentData;
use App\Models\Machine;
use App\Models\User;
use App\Services\OrcaSlicer\UserProfileService;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\File;

Artisan::command('foo', function () {
$files = File::allFiles(
storage_path('app/private')
);

$service = app(UserProfileService::class);

$user = User::firstWhere('email', '[email protected]');

$machine = Machine::firstWhere('slug', 'k1-max');

foreach ($files as $file) {
if ($file->getExtension() !== 'json') {
continue;
}

$content = file_get_contents($file->getRealPath());

$profile = FilamentData::from($content);

dump(
$profile->externalId
);

$service->import($user, $machine, $profile);
}
});
```

## List

[list](.github/images/list.png)
11 changes: 7 additions & 4 deletions app/Concerns/WithColor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace App\Concerns;

use App\Models\Color;
use Illuminate\Support\Str;

trait WithColor
{
Expand All @@ -21,9 +22,11 @@ trait WithColor

protected function color(string $name): Color
{
return $this->colors[$name] ??= Color::firstOrCreate([
'title' => $name,
'hex' => $this->colorMap[$name] ?? '#000000',
]);
return $this->colors[$name] ??= Color::query()
->whereRaw('lower(title) = ?', [Str::lower($name)])
->firstOrCreate(values: [
'title' => $name,
'hex' => $this->colorMap[$name] ?? '#000000',
]);
}
}
22 changes: 20 additions & 2 deletions app/Concerns/WithFilaments.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@
use App\Models\Filament;
use App\Models\FilamentType;
use App\Models\Vendor;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;

trait WithFilaments
{
protected array $filamentTypes = [];

protected array $filaments = [];

protected function filamentType(string $value): FilamentType
protected ?Collection $loadedFilamentTypes = null;

protected function filamentType(string $name): FilamentType
{
return $this->filamentTypes[$value] ??= FilamentType::firstOrCreate(['title' => $value]);
return $this->filamentTypes[$name] ??= FilamentType::query()
->whereRaw('lower(title) = ?', [Str::lower($name)])
->firstOrCreate(values: ['title' => $name]);
}

protected function filament(Vendor $vendor, FilamentType $filamentType): Filament
Expand All @@ -27,4 +33,16 @@ protected function filament(Vendor $vendor, FilamentType $filamentType): Filamen
'filament_type_id' => $filamentType->id,
]);
}

/**
* @return Collection<FilamentType>
*/
protected function getFilamentTypes(): Collection
{
return $this->loadedFilamentTypes ??= FilamentType::query()
->orderByRaw('LENGTH("title") DESC')
->orderByDesc('title')
->get()
->keyBy('title');
}
}
1 change: 1 addition & 0 deletions app/Concerns/WithNozzles.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace App\Concerns;

use App\Models\Nozzle;
use Illuminate\Support\Str;

trait WithNozzles
{
Expand Down
5 changes: 4 additions & 1 deletion app/Concerns/WithVendor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
namespace App\Concerns;

use App\Models\Vendor;
use Illuminate\Support\Str;

trait WithVendor
{
protected array $vendors = [];

protected function vendor(string $name): Vendor
{
return $this->vendors[$name] ??= Vendor::firstOrCreate(['title' => $name]);
return $this->vendors[$name] ??= Vendor::query()
->whereRaw('lower(title) = ?', [Str::lower($name)])
->firstOrCreate(values: ['title' => $name]);
}
}
8 changes: 6 additions & 2 deletions app/Console/Commands/OrcaSlicer/ImportCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace App\Console\Commands\OrcaSlicer;

use App\Services\OrcaSlicer\DownloadService;
use App\Services\OrcaSlicer\FilamentService;
use App\Services\OrcaSlicer\FilamentTypeService;
use App\Services\OrcaSlicer\MachineService;
use App\Services\OrcaSlicer\MapService;
Expand All @@ -22,16 +23,19 @@ public function handle(
MapService $map,
MachineService $machine,
NozzleService $nozzle,
FilamentTypeService $filament,
FilamentTypeService $type,
FilamentService $filament,
): void {
$this->components->task('Clean up', fn () => $download->cleanup());
$this->components->task('Download', fn () => $download->download());
$this->components->task('Extract', fn () => $download->extract());
$this->components->task('Release', fn () => $download->release());

$this->components->task('Import map', fn () => $map->import());
$this->components->task('Import profile maps', fn () => $map->import());
$this->components->task('Import sub filament maps', fn () => $map->importSubFilaments());
$this->components->task('Import machines', fn () => $machine->import());
$this->components->task('Import nozzles', fn () => $nozzle->import());
$this->components->task('Import filament types', fn () => $type->import());
$this->components->task('Import filaments', fn () => $filament->import());
}
}
2 changes: 1 addition & 1 deletion app/Data/Casts/ArrayToIntegerCast.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

class ArrayToIntegerCast implements Cast
{
public function cast(DataProperty $property, mixed $value, array $properties, CreationContext $context): mixed
public function cast(DataProperty $property, mixed $value, array $properties, CreationContext $context): int
{
if (is_array($value)) {
return (int) array_first($value);
Expand Down
Loading
Loading