Документация
Инженерные конвенции
Шаблоны, используемые для вычислений предметной области, проверки схемы, служб эффектов, доступа к базе данных и проверки.
Автоматически переведено с английского. Смотреть оригинал на английском
Исходная структура
Используйте английские идентификаторы, комментарии, документацию и сообщения о фиксации. В проектах TypeScript используется строгая проверка; общедоступные интерфейсы должны сохранять явные типы и декодировать внешние значения вместо распространения непроверенных данных. Манифесты пакетов предоставляют точки входа в исходный код, а модули приложений используют относительный импорт, соответствующий их инструменту сборки.
На рабочем столе есть групповые экраны, компоненты, магазины и помощники в разделе apps/desktop/src/features. Адаптеры маршрутов остаются в src/pages, а оболочка приложения и настройка клиента находятся в src/app. Основная геометрия остается независимой от состояния пользовательского интерфейса и доступа к базе данных.
Геометрия и выходные единицы
Геометрия базового вектора и аналитического объекта использует миллиметры и радианы. Размещение сцены, элементы управления функциями и поля поворотной оси CAM имеют определенные в контракте соглашения об углах, включая градусы. Следуйте каждой схеме при адаптации между ними. Преобразование отображения пользовательского интерфейса происходит на границе отображения. В операциях обработки дополнительно используются параметры подачи, шпинделя, глубины и зазора, значения которых определяются их схемами; голое число никогда не должно приобретать неявную единицу только из метки.
G-код обеспечивает собственное преобразование вывода и форматирование чисел, специфичное для контроллера. Общий эмиттер подвергает formatNumber, округляет до запрошенного десятичного значения, нормализует отрицательный ноль и отслеживает исходящую позицию. При форматировании фида может быть опущена дробная часть целых значений. Используйте эмиттер, а не форматируйте слова движения отдельно для каждого вызывающего абонента.
Сохраняйте четкость модели и приблизительной геометрии отображения. Мозаичная поверхность полезна для рендеринга и анализа, но сама по себе не доказывает успешность точной операции B-rep.
Услуги эффектов
Услуги расширяются Context.Service и предоставить типизированные методы, возвращающие эффект. Уровень создает реализацию и предоставляет ее зависимости. apps/sidecar/src/layers.ts — это точка интеграции репозиториев, служб, обработчиков, авторизации и конфигурации среды выполнения.
Ресурсы со сроком службы, такие как дескрипторы SQLite, приобретаются и освобождаются внутри области владения владеющего слоя. Использовать Effect.try или Effect.tryPromise переводить иностранные исключения в значимые ошибки. Стабильные имена операций в ошибках и трассировке позволяют диагностировать сбои без привязки вызывающих программ к драйверу хранилища.
Состав слоев имеет значение: объединенные вместе родственные уровни не предоставляют друг другу услуги автоматически. Регистрация шагов рабочего процесса Sidecar располагается после необходимого бегуна; шаг AI регистрируется там, где доступна услуга AI.
Проверка и ошибки
Входы и выходы HTTP объявлены в packages/api/src/groups. Подтвердите неизвестные входные данные на этих границах. Контракт включает в себя простые сообщения об ошибках, конверты успеха/ошибки и некоторые тела ошибок с ключами; сохранить объявленный статус конечной точки и представление ответа.
Ошибки, связанные с HTTP, используют схемы эффектов и аннотации состояния. Например, BadRequest, Unauthorized, NotFound, и Conflict объявлены в packages/api/src/errors.ts. Внутренние сбои базы данных вызывают операцию и приводят к DatabaseError. Сопоставьте внутренние сбои на границе HTTP, а не раскрывайте сведения о драйвере клиентам.
Восстановление клиентов после изменения контракта с bun run generate. Проверьте зафиксированный вывод с помощью bun run generate:check. Созданные папки являются выходными данными; генерация явно исключает конечные точки, которые цель не может представить.
Постоянство и конфигурация
Репозитории приложений используют Database обслуживание от @cadcamfun/db и его query(operation, run) помощник. Изменять packages/db/src/schema.ts перед созданием миграций. Просматривайте сгенерированный SQL и метаданные вместе; не проводите эксперимент по деструктивной схеме с базой данных пользователя.
Сайдкар считывает конфигурацию в apps/sidecar/src/config.ts и пропускает его через AppConfigService. В учетных данных используются отредактированные значения, если они требуются службе. Не допускайте попадания секретных значений токена и поставщика в журналы, документацию и результаты устранения неполадок. Собственная оболочка предоставляет собственный токен запуска и пути хранения.
Студия документации представляет собой отдельный локальный инструмент с собственным выбором пути в packages/web/script/studio-server.ts. Не предполагайте, что его путь к базе данных или сеанс входа в систему совпадают с работающим рабочим столом.
Проверка
bun test packages/core
bun run --filter @cadcamfun/core typecheck
bun run generate:check
# Documentation content and build
bun test packages/web/test
bun run --filter @cadcamfun/web typecheck
bun run --filter @cadcamfun/web build Выберите проверки, которые используют затронутую границу. Чистые изменения ядра требуют случаев числовой и геометрической регрессии. Изменения HTTP требуют покрытия обработчика и схемы. Для внесения изменений в документацию необходимы действительные маршруты, привязки, примеры и успешная сборка сайта. Полный тестовый запуск рабочей области bun run test, который включает пакеты, приложения и сценарии.
Необязательные поля, значения NULL и транспортные значения
Необязательное поле может быть опущено. Поле, допускающее значение NULL, может явно содержать null. Это отдельные объекты недвижимости: контракт по проекту требует description в возвращаемых строках, допуская при этом значение null, а запрос на создание допускает пропуск этого поля. Сохраняйте эти различия при создании клиентов или исправлении сохраненных документов.
Транспортная проверка также отличается от бизнес-проверки. Полезная нагрузка создания проекта допускает опущенное имя на уровне схемы, но обработчик возвращает 400 с Project name is required если он отсутствует или пуст. Сгенерированный тип сам по себе не может установить, что операция будет разрешена для существующего ресурса или текущей учетной записи.
Параметры HTTP-запроса представляют собой закодированный текст. Используйте объявленные клиентом поля запроса или кодировку URL-адреса, а не объединяйте произвольный ввод пользователя в URL-адрес. Кодируйте ключ или идентификатор проекта как один сегмент пути и отправляйте токены носителя в заголовках, а не в скопированных ссылках.
The справочник по API проектов показывает эти поля и коды состояния; тот захваченное прохождение демонстрирует результат проверки обработчика.
Ведение исполняемой документации
Напишите пример для конкретной публичной поверхности, которую он называет. Promise SDK и полный клиент Effect на основе контракта имеют разные формы методов/входных данных и покрытие. Запрос генератора, управляемого настройками, отличается от собственного запроса ядра, а сгенерированная программа отличается от сохраненной записи траектории инструмента.
Эталонный снимок API создается на основе контракта приложения. После изменения конечной точки заново создайте ее в рабочей веб-пространстве с помощью bun run generate:api-reference. Бегать bun run check:api-reference чтобы сравнить его с текущим источником. Группировка ресурсов, текст статьи, навигация и поиск помощника по-прежнему должны точно описывать этот контракт.
При документировании ответа, полученного в результате изолированного запуска, определите любые нормализованные идентификаторы, временные метки или пропущенные поля. Помечайте шаблоны запросов как шаблоны. Не представляйте придуманный идентификатор или пример невыполненной схемы в качестве наблюдаемого производственного ответа.
Шаблоны эффектов, используемые повсюду
import { Context, Data, Effect, Layer } from "effect"
import { AppConfigService } from "../config.ts"
export class StorageError extends Data.TaggedError("StorageError")<{
readonly operation: string
readonly cause: unknown
}> {}
export class Storage extends Context.Service<Storage, {
readonly read: (key: string) => Effect.Effect<Uint8Array, StorageError>
}>()("cadcamfun/Storage") {
static readonly layer = Layer.effect(Storage, Effect.gen(function* () {
const config = yield* AppConfigService // dependencies come from the context
return Storage.of({
read: (key) => Effect.tryPromise({
try: () => Bun.file(`${config.dataDir}/storage/${key}`).bytes(),
catch: (cause) => new StorageError({ operation: "read", cause }),
}),
})
}))
} - Служебные ключи расположены в пространстве имен:
"cadcamfun/Database","cadcamfun/AppConfig","cadcamfun/ApiClient". - Ошибки
Data.TaggedErrorвнутренние службы иSchema.TaggedErrorсhttpApiStatusна границе HTTP. Обработчики сопоставляют первое со вторым. - Ресурсы с пожизненным использованием
Effect.acquireReleaseпоэтому они закрываются, когда закрывается область действия слоя. - Именованные функции используют
Effect.fn("area.name")поэтому трассировки содержат читаемое имя диапазона, напримерcam.runKernelRequest. - Конфигурация считывается один раз, в
AppConfigService; никакой другой модуль не читаетprocess.envв сайдкаре.
Правила именования и компоновки
| Вещь | Соглашение | Пример |
|---|---|---|
| Файлы | кебаб-кейс, по одному концепту в файле, рядом тест | cam-program.ts, cam-program.test.ts |
| Идентификаторы операций | <group>.<method> | projects.create, health.check |
| Ярлыки запросов | пунктир, сначала ресурс | projects.list, toolpaths.update |
| Единицы | миллиметры, градусы, секунды; мм/мин для подачи, м/мин для Vc | feed: 5696 |
| Координаты | Z вверх, правша; программа перемещается по рабочим координатам | происхождение в верхней части складского центра |
| Идентификаторы | Строки UUID | crypto.randomUUID() |