ドキュメント
エンジニアリング上の規約
ドメインの計算、スキーマ検証、エフェクト サービス、データベース アクセス、および検証に使用されるパターン。
英語から自動翻訳されています。 英語の原文を見る
ソース構造
英語の識別子、コメント、ドキュメント、コミット メッセージを使用します。 TypeScript プロジェクトでは厳密なチェックが使用されます。パブリック インターフェイスは、チェックされていないデータを伝播するのではなく、明示的な型を保持し、外部値をデコードする必要があります。パッケージ マニフェストはソース エントリ ポイントを公開し、アプリケーション モジュールはビルド ツールに適した相対インポートを使用します。
デスクトップ機能は、画面、コンポーネント、ストア、およびヘルパーをグループ化します。 apps/desktop/src/features。ルートアダプターはそのまま残ります src/pages、アプリケーションシェルとクライアントセットアップは src/app。コア ジオメトリは、UI 状態やデータベース アクセスから独立したままになります。
ジオメトリと出力ユニット
コア ベクトルと解析エンティティ ジオメトリでは、ミリメートルとラジアンが使用されます。シーンの配置、機能コントロール、および CAM 回転軸フィールドには、度を含む契約固有の角度規則があります。スキーマ間で適応させる場合は、それぞれのスキーマに従ってください。 UI 表示変換は表示境界に属します。機械加工操作では、さらに、スキーマによって定義された意味を持つ送り、主軸、深さ、およびクリアランスのパラメータが使用されます。裸の数値がラベルだけから暗黙の単位を取得してはなりません。
G コードは、独自のコントローラー固有の出力変換と数値フォーマットをポストします。共有エミッタが公開するもの formatNumber、要求された 10 進数に丸め、負のゼロを正規化し、放出された位置を追跡します。フィードの書式設定では、整数値の小数部が省略される場合があります。各呼び出し元でモーション ワードを個別にフォーマットするのではなく、エミッターを使用します。
モデルの証拠とおおよその表示ジオメトリを区別してください。テッセレーションされたサーフェスはレンダリングと分析には役立ちますが、それ自体は正確な B-rep 操作が成功したことを証明するものではありません。
エフェクトサービス
サービスの延長 Context.Service そして、型付きの Effect を返すメソッドを公開します。レイヤーは実装を構築し、その依存関係を提供します。 apps/sidecar/src/layers.ts リポジトリ、サービス、ハンドラ、認可、およびランタイム設定の統合ポイントです。
SQLite ハンドルなどの有効期間を持つリソースは、所有層のスコープ内で取得および解放されます。使用 Effect.try または Effect.tryPromise 外部例外を意味のあるエラーに変換します。エラーとトレースにおける安定した操作名により、呼び出し元をストレージ ドライバーに結合することなく障害を診断できます。
レイヤーの構成は重要です。マージされた兄弟レイヤーは、自動的に相互にサービスを提供しません。サイドカー ワークフロー ステップの登録は、必要なランナーの後に階層化されます。 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。資格情報は、サービスで必要な場合に編集された値を使用します。トークンとプロバイダーのシークレット値をログ、ドキュメント、トラブルシューティングの出力に含めないでください。ネイティブ シェルは、独自の起動トークンとストレージ パスを提供します。
ドキュメント Studio は、独自のパス選択を持つ別個のローカル ツールです。 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 を許可し、作成リクエストではそのフィールドの省略を許可します。クライアントを構築するとき、または保存されたドキュメントにパッチを適用するときに、これらの区別を維持してください。
トランスポートの検証はビジネスの検証とも異なります。 project-create ペイロードではスキーマ レベルで名前の省略が許可されていますが、ハンドラーは次のような 400 を返します。 Project name is required 欠落しているか空の場合。生成された型だけでは、既存のリソースまたは現在のアカウントに対して操作が許可されるかどうかを確立できません。
HTTP クエリ パラメータはエンコードされたテキストです。任意のユーザー入力を URL に連結するのではなく、クライアントの宣言されたクエリ フィールドまたは URL エンコーディングを使用します。キーまたはプロジェクト識別子を単一のパス セグメントとしてエンコードし、コピーされたリンクではなくヘッダーでベアラー トークンを送信します。
の プロジェクト API リファレンス これらのフィールドとステータス コードを示します。の キャプチャされたウォークスルー ハンドラーの検証結果を示します。
実行可能なドキュメントを保守する
名前を付けた正確な公開面に対して例を書きます。 Promise SDK と完全なコントラクトベースの Effect クライアントには、メソッド/入力の形状とカバレッジが異なります。設定主導のジェネレーター リクエストはネイティブ カーネル リクエストとは異なり、生成されたプログラムは保存されたツールパス レコードとは異なります。
API リファレンス スナップショットはアプリケーション コントラクトから生成されます。エンドポイントを変更した後、Web ワークスペース内でエンドポイントを再生成します。 bun run generate:api-reference。走る bun run check:api-reference 現在のソースと比較します。リソースのグループ化、記事のテキスト、ナビゲーション、およびアシスタントの検索では、その契約を忠実に記述する必要があります。
分離された実行からキャプチャされた応答を文書化するときは、正規化された ID、タイムスタンプ、または省略されたフィールドを特定します。リクエスト テンプレートにテンプレートとしてラベルを付けます。発明された識別子または未実行のスキーマの例を、観察された運用応答として提示しないでください。
全体で使用されるエフェクトパターン
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とhttpApiStatushTTP境界で。ハンドラーは最初のものを 2 番目のものにマップします。 - 生涯にわたって使用できるリソース
Effect.acquireReleaseしたがって、レイヤーのスコープが閉じるとそれらも閉じます。 - 名前付き関数の使用
Effect.fn("area.name")したがって、トレースには読み取り可能なスパン名が含まれます。たとえば、cam.runKernelRequest. - 構成は一度読み取られます。
AppConfigService;他のモジュールは読み込まないprocess.envサイドカーの中。
命名とレイアウトのルール
| もの | 大会 | 例 |
|---|---|---|
| ファイル | kebab-case、ファイルごとに 1 つのコンセプト、その隣にテスト | cam-program.ts, cam-program.test.ts |
| オペレーションID | <group>.<method> | projects.create, health.check |
| クエリラベル | 点線、リソース優先 | projects.list, toolpaths.update |
| 単位 | ミリメートル、度、秒。送りの場合は mm/min、Vc の場合は m/min | feed: 5696 |
| 座標 | Z アップ、右利き。プログラムは作業座標内で移動します | ストックセンター上部の原点 |
| ID | UUID文字列 | crypto.randomUUID() |